Front page | perl.perl5.porters |
Postings from August 2016
Re: Flailing randomly at ops
Thread Previous
|
Thread Next
From:
Father Chrysostomos
Date:
August 9, 2016 01:20
Subject:
Re: Flailing randomly at ops
Message ID:
20160809011959.2489.qmail@lists-nntp.develooper.com
Paul Evans wrote:
> can anyone explain to me
> how I can write a function that takes an OP tree representing the body
> of the eval block (the calls to A() and B() in the above), and return a
> new OP tree that invokes the given one inside an eval{} scope?
I will show you how to look up things like this in the perl source.
Under KEY_eval, toke.c has:
UNIBRACK(OP_ENTERTRY);
UNIBRACK is defined in terms of UNI3, which ultimately results in the equivalent of:
pl_yylval.ival = OP_ENTERTRY;
return UNIOP;
So yylex returns a UNIOP with OP_ENTERTRY as the value, and we need to
look in perly.y to see how it handles UNIOP.
I see this:
| UNIOP block /* eval { foo }* */
{ $$ = newUNOP($1, 0, $2); }
I already know that newUNOP will create a simply uniary op with
'block' as its argument. It also calls a check function, so we look
in regen/opcodes to find out which one:
entertry eval {block} ck_eval d|
OK, so it is ck_eval. No surprises there. If you look at ck_eval in
op.c, you can see that it does quite a bit of op tree munging, includ-
ing freeing the original op that newUNOP just created.
So it seems that you can just use:
newUNOP(OP_ENTERTRY, 0, your_ops);
> For bonus points, I'll be wanting to inspect the success-or-failure of
> the eval{} operation, and interact with the perl stack afterwards based
> on this. I can probably implement all of my behaviour inside a single
> (custom) OP, so if someone can suggest how to (perhaps) PUSHMARK before
> the eval body, so I can find the length of the successfully returned
> list, and otherwise interact with the stack in the next OPs after the
> eval block returns, that would be useful too.
You could probably take what newUNOP ultimately returns (affected by
ck_eval) and change the OP_LEAVETRY into an OP_CUSTOM.
That custom op can call PL_ppaddr[OP_LEAVETRY] and then inspect the
stack when it returns. As for distinguishing between an empty list
resulting from an error and an empty list return by a successful eval,
I do not know the details off the top of my head, but you could proba-
bly check ERRSV ($@). If you want more details about how eval works at
run time, the only advice I can give you is to study pp_ctl.c.
> As a final item: if there's anywhere that these subjects are
> documented, could someone point me at it?
As you see, I use the source code as documentation of sorts. I do not
know how much detail is in the various documents that perlhack links
to, since I rarely use them, having never found them nearly as helpful
as the source code itself.
Thread Previous
|
Thread Next