How to assign a CV to a package with a list of operation codes?

I play with the new parse_block feature in bleadperl,

I can parse several statements in listop, which will generate the tree below:

LISTOP (0x1002a00c0) leave [1] OP (0x1002d6220) enter COP (0x1002a0b80) nextstate OP (0x10028c0f0) null LISTOP (0x1002a0170) print OP (0x1002b1a90) pushmark SVOP (0x100327ee0) const PV (0x100826ec0) "hello\n" COP (0x1002a0c50) nextstate LISTOP (0x100324ee0) print OP (0x100327880) pushmark SVOP (0x100324eb0) const PV (0x100897688) "world\n" 

I need to return a pointer to the optECT structure from my keyword plugin, which currently only contains a bare list of ops. I want to wrap these ops inside a subroutine and assign it to a dash symbol.

So, I want to do something like this:

 $ perl -MO=Terse -e "*foo = sub { print 'my listops here' }" LISTOP (0x10022b5e0) leave [1] OP (0x10022b620) enter COP (0x10022b590) nextstate BINOP (0x100202090) sassign UNOP (0x1002083d0) refgen UNOP (0x100208360) null [146] OP (0x1002083a0) pushmark SVOP (0x100208330) anoncode [1] CV (0x100826d40) UNOP (0x1002085a0) rv2gv SVOP (0x100208550) gv GV (0x100826d28) *foo 

Presumably I need to add entersub, leavesub at the beginning and at the end of my lists, but I'm not sure how I will build it in XS? I also don't know how to turn the resulting optree into a CV?

I can find examples of CV generation for xsubs, but not from optrees.

Thank you for your help.

+4
source share
1 answer

I would look at what eval does internally, since that is essentially what it does. In particular, op.c and Perl_newPROG (OP * o) can be a good place to run:

 void Perl_newPROG(pTHX_ OP *o) { ... PL_eval_root = newUNOP(OP_LEAVEEVAL, ((PL_in_eval & EVAL_KEEPERR) ? OPf_SPECIAL : 0), o); PL_eval_start = op_linklist(PL_eval_root); PL_eval_root->op_private |= OPpREFCOUNTED; OpREFCNT_set(PL_eval_root, 1); PL_eval_root->op_next = 0; CALL_PEEP(PL_eval_start); ... 
0
source

Source: https://habr.com/ru/post/1333647/


All Articles