X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/a2167ea9aa2930062a9c589acf175b51c19cf90e..0bd6eef439e2cdb97b9b64430c17d4f523f75914:/op.h diff --git a/op.h b/op.h index 9d177d0..4c086a5 100644 --- a/op.h +++ b/op.h @@ -24,7 +24,7 @@ * !op_slabbed. * op_savefree on savestack via SAVEFREEOP * op_folded Result/remainder of a constant fold operation. - * op_lastsib this op is is the last sibling + * op_moresib this op is is not the last sibling * op_spare One spare bit * op_flags Flags common to all operations. See OPf_* below. * op_private Flags peculiar to a particular operation (BUT, @@ -43,7 +43,7 @@ typedef PERL_BITFIELD16 Optype; #else #define BASEOP \ OP* op_next; \ - OP* op_sibling; \ + OP* op_sibparent; \ OP* (*op_ppaddr)(pTHX); \ PADOFFSET op_targ; \ PERL_BITFIELD16 op_type:9; \ @@ -52,13 +52,13 @@ typedef PERL_BITFIELD16 Optype; PERL_BITFIELD16 op_savefree:1; \ PERL_BITFIELD16 op_static:1; \ PERL_BITFIELD16 op_folded:1; \ - PERL_BITFIELD16 op_lastsib:1; \ + PERL_BITFIELD16 op_moresib:1; \ PERL_BITFIELD16 op_spare:1; \ U8 op_flags; \ U8 op_private; #endif -/* If op_type:9 is changed to :10, also change PUSHEVAL in cop.h. +/* If op_type:9 is changed to :10, also change cx_pusheval() Also, if the type of op_type is ever changed (e.g. to PERL_BITFIELD32) then all the other bit-fields before/after it should change their types too to let VC pack them into the same 4 byte integer.*/ @@ -85,7 +85,7 @@ Deprecated. Use C instead. =cut */ -#define GIMME_V OP_GIMME(PL_op, block_gimme()) +#define GIMME_V Perl_gimme_V(aTHX) /* Public flags */ @@ -99,20 +99,26 @@ Deprecated. Use C instead. #define OPf_REF 16 /* Certified reference. */ /* (Return container, not containee). */ #define OPf_MOD 32 /* Will modify (lvalue). */ + #define OPf_STACKED 64 /* Some arg is arriving on the stack. */ + /* Indicates mutator-variant of op for those + * ops which support them, e.g. $x += 1 + */ + #define OPf_SPECIAL 128 /* Do something weird for this op: */ /* On local LVAL, don't init local value. */ /* On OP_SORT, subroutine is inlined. */ /* On OP_NOT, inversion was implicit. */ - /* On OP_LEAVE, don't restore curpm. */ + /* On OP_LEAVE, don't restore curpm, e.g. + * /(...)/ while ...>; */ /* On truncate, we truncate filehandle */ /* On control verbs, we saw no label */ /* On flipflop, we saw ... instead of .. */ /* On UNOPs, saw bare parens, e.g. eof(). */ + /* On OP_CHDIR, handle (or bare parens) */ /* On OP_NULL, saw a "do". */ /* On OP_EXISTS, treat av as av, not avhv. */ /* On OP_(ENTER|LEAVE)EVAL, don't clear $@ */ - /* On pushre, rx is used as part of split, e.g. split " " */ /* On regcomp, "use re 'eval'" was in scope */ /* On RV2[ACGHS]V, don't create GV--in defined()*/ @@ -124,9 +130,10 @@ Deprecated. Use C instead. /* On OP_SMARTMATCH, an implicit smartmatch */ /* On OP_ANONHASH and OP_ANONLIST, create a reference to the new anon hash or array */ - /* On OP_HELEM and OP_HSLICE, localization will be followed - by assignment, so do not wipe the target if it is special - (e.g. a glob or a magic SV) */ + /* On OP_HELEM, OP_MULTIDEREF and OP_HSLICE, + localization will be followed by assignment, + so do not wipe the target if it is special + (e.g. a glob or a magic SV) */ /* On OP_MATCH, OP_SUBST & OP_TRANS, the operand of a logical or conditional that was optimised away, so it should @@ -138,33 +145,57 @@ Deprecated. Use C instead. */ /* On OP_PADRANGE, push @_ */ /* On OP_DUMP, has no label */ + /* On OP_UNSTACK, in a C-style for loop */ + /* On OP_READLINE, it's for <<>>, not <> */ +/* There is no room in op_flags for this one, so it has its own bit- + field member (op_folded) instead. The flag is only used to tell + op_convert_list to set op_folded. */ +#define OPf_FOLDED (1<<16) /* old names; don't use in new code, but don't break them, either */ #define OPf_LIST OPf_WANT_LIST #define OPf_KNOW OPf_WANT -#define GIMME \ +#if !defined(PERL_CORE) && !defined(PERL_EXT) +# define GIMME \ (PL_op->op_flags & OPf_WANT \ ? ((PL_op->op_flags & OPf_WANT) == OPf_WANT_LIST \ ? G_ARRAY \ : G_SCALAR) \ : dowantarray()) +#endif /* NOTE: OPp* flags are now auto-generated and defined in opcode.h, * from data in regen/op_private */ -#define OPpTRANS_ALL (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF|OPpTRANS_IDENTICAL|OPpTRANS_SQUASH|OPpTRANS_COMPLEMENT|OPpTRANS_GROWS|OPpTRANS_DELETE) - +#define OPpTRANS_ALL (OPpTRANS_USE_SVOP|OPpTRANS_CAN_FORCE_UTF8|OPpTRANS_IDENTICAL|OPpTRANS_SQUASH|OPpTRANS_COMPLEMENT|OPpTRANS_GROWS|OPpTRANS_DELETE) +#define OPpTRANS_FROM_UTF OPpTRANS_USE_SVOP +#define OPpTRANS_TO_UTF OPpTRANS_CAN_FORCE_UTF8 /* Mask for OP_ENTERSUB flags, the absence of which must be propagated in dynamic context */ #define OPpENTERSUB_LVAL_MASK (OPpLVAL_INTRO|OPpENTERSUB_INARGS) -/* VMS-specific hints in COPs */ -#define OPpHINT_M_VMSISH_MASK (OPpHINT_M_VMSISH_STATUS|OPpHINT_M_VMSISH_TIME) + +/* things that can be elements of op_aux */ +typedef union { + PADOFFSET pad_offset; + SV *sv; + IV iv; + UV uv; + char *pv; + SSize_t ssize; +} UNOP_AUX_item; + +#ifdef USE_ITHREADS +# define UNOP_AUX_item_sv(item) PAD_SVl((item)->pad_offset); +#else +# define UNOP_AUX_item_sv(item) ((item)->sv); +#endif + @@ -177,6 +208,12 @@ struct unop { OP * op_first; }; +struct unop_aux { + BASEOP + OP *op_first; + UNOP_AUX_item *op_aux; +}; + struct binop { BASEOP OP * op_first; @@ -195,6 +232,22 @@ struct listop { OP * op_last; }; +struct methop { + BASEOP + union { + /* op_u.op_first *must* be aligned the same as the op_first + * field of the other op types, and op_u.op_meth_sv *must* + * be aligned with op_sv */ + OP* op_first; /* optree for method name */ + SV* op_meth_sv; /* static method name */ + } op_u; +#ifdef USE_ITHREADS + PADOFFSET op_rclass_targ; /* pad index for redirect class */ +#else + SV* op_rclass_sv; /* static redirect class $o->A::meth() */ +#endif +}; + struct pmop { BASEOP OP * op_first; @@ -207,11 +260,8 @@ struct pmop { U32 op_pmflags; union { OP * op_pmreplroot; /* For OP_SUBST */ -#ifdef USE_ITHREADS - PADOFFSET op_pmtargetoff; /* For OP_PUSHRE */ -#else - GV * op_pmtargetgv; -#endif + PADOFFSET op_pmtargetoff; /* For OP_SPLIT lex ary or thr GV */ + GV * op_pmtargetgv; /* For OP_SPLIT non-threaded GV */ } op_pmreplrootu; union { OP * op_pmreplstart; /* Only used in OP_SUBST */ @@ -275,48 +325,56 @@ struct pmop { * allocate off the low end until you get to PMf_BASE_SHIFT+0. If that isn't * enough, move PMf_BASE_SHIFT down (if possible) and add the new bit at the * other end instead; this preserves binary compatibility. */ -#define PMf_BASE_SHIFT (_RXf_PMf_SHIFT_NEXT+4) +#define PMf_BASE_SHIFT (_RXf_PMf_SHIFT_NEXT+2) + +/* Set by the parser if it discovers an error, so the regex shouldn't be + * compiled */ +#define PMf_HAS_ERROR (1U<<(PMf_BASE_SHIFT+3)) /* 'use re "taint"' in scope: taint $1 etc. if target tainted */ -#define PMf_RETAINT (1U<<(PMf_BASE_SHIFT+5)) +#define PMf_RETAINT (1U<<(PMf_BASE_SHIFT+4)) /* match successfully only once per reset, with related flag RXf_USED in * re->extflags holding state. This is used only for ?? matches, and only on * OP_MATCH and OP_QR */ -#define PMf_ONCE (1U<<(PMf_BASE_SHIFT+6)) +#define PMf_ONCE (1U<<(PMf_BASE_SHIFT+5)) /* PMf_ONCE, i.e. ?pat?, has matched successfully. Not used under threading. */ -#define PMf_USED (1U<<(PMf_BASE_SHIFT+7)) +#define PMf_USED (1U<<(PMf_BASE_SHIFT+6)) /* subst replacement is constant */ -#define PMf_CONST (1U<<(PMf_BASE_SHIFT+8)) +#define PMf_CONST (1U<<(PMf_BASE_SHIFT+7)) /* keep 1st runtime pattern forever */ -#define PMf_KEEP (1U<<(PMf_BASE_SHIFT+9)) +#define PMf_KEEP (1U<<(PMf_BASE_SHIFT+8)) -#define PMf_GLOBAL (1U<<(PMf_BASE_SHIFT+10)) /* pattern had a g modifier */ +#define PMf_GLOBAL (1U<<(PMf_BASE_SHIFT+9)) /* pattern had a g modifier */ /* don't reset pos() if //g fails */ -#define PMf_CONTINUE (1U<<(PMf_BASE_SHIFT+11)) +#define PMf_CONTINUE (1U<<(PMf_BASE_SHIFT+10)) /* evaluating replacement as expr */ -#define PMf_EVAL (1U<<(PMf_BASE_SHIFT+12)) +#define PMf_EVAL (1U<<(PMf_BASE_SHIFT+11)) /* Return substituted string instead of modifying it. */ -#define PMf_NONDESTRUCT (1U<<(PMf_BASE_SHIFT+13)) +#define PMf_NONDESTRUCT (1U<<(PMf_BASE_SHIFT+12)) /* the pattern has a CV attached (currently only under qr/...(?{}).../) */ -#define PMf_HAS_CV (1U<<(PMf_BASE_SHIFT+14)) +#define PMf_HAS_CV (1U<<(PMf_BASE_SHIFT+13)) /* op_code_list is private; don't free it etc. It may well point to * code within another sub, with different pad etc */ -#define PMf_CODELIST_PRIVATE (1U<<(PMf_BASE_SHIFT+15)) +#define PMf_CODELIST_PRIVATE (1U<<(PMf_BASE_SHIFT+14)) /* the PMOP is a QR (we should be able to detect that from the op type, * but the regex compilation API passes just the pm flags, not the op * itself */ -#define PMf_IS_QR (1U<<(PMf_BASE_SHIFT+16)) -#define PMf_USE_RE_EVAL (1U<<(PMf_BASE_SHIFT+17)) /* use re'eval' in scope */ +#define PMf_IS_QR (1U<<(PMf_BASE_SHIFT+15)) +#define PMf_USE_RE_EVAL (1U<<(PMf_BASE_SHIFT+16)) /* use re'eval' in scope */ + +/* Means that this is a subpattern being compiled while processing a \p{} + * wildcard. This isn't called from op.c, but it is passed as a pm flag. */ +#define PMf_WILDCARD (1U<<(PMf_BASE_SHIFT+17)) /* See comments at the beginning of these defines about adding bits. The * highest bit position should be used, so that if PMf_BASE_SHIFT gets @@ -375,18 +433,21 @@ struct loop { OP * op_lastop; }; -#define cUNOPx(o) ((UNOP*)o) -#define cBINOPx(o) ((BINOP*)o) -#define cLISTOPx(o) ((LISTOP*)o) -#define cLOGOPx(o) ((LOGOP*)o) -#define cPMOPx(o) ((PMOP*)o) -#define cSVOPx(o) ((SVOP*)o) -#define cPADOPx(o) ((PADOP*)o) -#define cPVOPx(o) ((PVOP*)o) -#define cCOPx(o) ((COP*)o) -#define cLOOPx(o) ((LOOP*)o) +#define cUNOPx(o) ((UNOP*)(o)) +#define cUNOP_AUXx(o) ((UNOP_AUX*)(o)) +#define cBINOPx(o) ((BINOP*)(o)) +#define cLISTOPx(o) ((LISTOP*)(o)) +#define cLOGOPx(o) ((LOGOP*)(o)) +#define cPMOPx(o) ((PMOP*)(o)) +#define cSVOPx(o) ((SVOP*)(o)) +#define cPADOPx(o) ((PADOP*)(o)) +#define cPVOPx(o) ((PVOP*)(o)) +#define cCOPx(o) ((COP*)(o)) +#define cLOOPx(o) ((LOOP*)(o)) +#define cMETHOPx(o) ((METHOP*)(o)) #define cUNOP cUNOPx(PL_op) +#define cUNOP_AUX cUNOP_AUXx(PL_op) #define cBINOP cBINOPx(PL_op) #define cLISTOP cLISTOPx(PL_op) #define cLOGOP cLOGOPx(PL_op) @@ -398,6 +459,7 @@ struct loop { #define cLOOP cLOOPx(PL_op) #define cUNOPo cUNOPx(o) +#define cUNOP_AUXo cUNOP_AUXx(o) #define cBINOPo cBINOPx(o) #define cLISTOPo cLISTOPx(o) #define cLOGOPo cLOGOPx(o) @@ -409,6 +471,7 @@ struct loop { #define cLOOPo cLOOPx(o) #define kUNOP cUNOPx(kid) +#define kUNOP_AUX cUNOP_AUXx(kid) #define kBINOP cBINOPx(kid) #define kLISTOP cLISTOPx(kid) #define kLOGOP cLOGOPx(kid) @@ -420,6 +483,24 @@ struct loop { #define kLOOP cLOOPx(kid) +typedef enum { + OPclass_NULL, /* 0 */ + OPclass_BASEOP, /* 1 */ + OPclass_UNOP, /* 2 */ + OPclass_BINOP, /* 3 */ + OPclass_LOGOP, /* 4 */ + OPclass_LISTOP, /* 5 */ + OPclass_PMOP, /* 6 */ + OPclass_SVOP, /* 7 */ + OPclass_PADOP, /* 8 */ + OPclass_PVOP, /* 9 */ + OPclass_LOOP, /* 10 */ + OPclass_COP, /* 11 */ + OPclass_METHOP, /* 12 */ + OPclass_UNOP_AUX /* 13 */ +} OPclass; + + #ifdef USE_ITHREADS # define cGVOPx_gv(o) ((GV*)PAD_SVl(cPADOPx(o)->op_padix)) # ifndef PERL_CORE @@ -431,6 +512,7 @@ struct loop { ? cSVOPx(v)->op_sv : PAD_SVl((v)->op_targ)) # define cSVOPx_svp(v) (cSVOPx(v)->op_sv \ ? &cSVOPx(v)->op_sv : &PAD_SVl((v)->op_targ)) +# define cMETHOPx_rclass(v) PAD_SVl(cMETHOPx(v)->op_rclass_targ) #else # define cGVOPx_gv(o) ((GV*)cSVOPx(o)->op_sv) # ifndef PERL_CORE @@ -439,8 +521,11 @@ struct loop { # endif # define cSVOPx_sv(v) (cSVOPx(v)->op_sv) # define cSVOPx_svp(v) (&cSVOPx(v)->op_sv) +# define cMETHOPx_rclass(v) (cMETHOPx(v)->op_rclass_sv) #endif +#define cMETHOPx_meth(v) cSVOPx_sv(v) + #define cGVOP_gv cGVOPx_gv(PL_op) #define cGVOPo_gv cGVOPx_gv(o) #define kGVOP_gv cGVOPx_gv(kid) @@ -481,6 +566,8 @@ struct loop { #define OA_BASEOP_OR_UNOP (11 << OCSHIFT) #define OA_FILESTATOP (12 << OCSHIFT) #define OA_LOOPEXOP (13 << OCSHIFT) +#define OA_METHOP (14 << OCSHIFT) +#define OA_UNOP_AUX (15 << OCSHIFT) /* Each remaining nybble of PL_opargs (i.e. bits 12..15, 16..19 etc) * encode the type for each arg */ @@ -542,6 +629,15 @@ struct loop { #define ref(o, type) doref(o, type, TRUE) #endif + +/* translation table attached to OP_TRANS/OP_TRANSR ops */ + +typedef struct { + Size_t size; /* number of entries in map[], not including final slot */ + short map[1]; /* Unwarranted chumminess */ +} OPtrans_map; + + /* =head1 Optree Manipulation Functions @@ -549,7 +645,7 @@ struct loop { Given the root of an optree, link the tree in execution order using the C pointers and return the first op executed. If this has already been done, it will not be redone, and C<< o->op_next >> will be -returned. If C<< o->op_next >> is not already set, I should be at +returned. If C<< o->op_next >> is not already set, C should be at least an C. =cut @@ -599,19 +695,23 @@ least an C. #ifdef PERL_CORE struct opslot { - /* keep opslot_next first */ - OPSLOT * opslot_next; /* next slot */ - OPSLAB * opslot_slab; /* owner */ + U16 opslot_size; /* size of this slot (in pointers) */ + U16 opslot_offset; /* offset from start of slab (in ptr units) */ OP opslot_op; /* the op itself */ }; struct opslab { - OPSLOT * opslab_first; /* first op in this slab */ OPSLAB * opslab_next; /* next slab */ - OP * opslab_freed; /* chain of freed ops */ - size_t opslab_refcnt; /* number of ops */ + OPSLAB * opslab_head; /* first slab in chain */ + OP ** opslab_freed; /* array of sized chains of freed ops (head only)*/ + size_t opslab_refcnt; /* number of ops (head slab only) */ + U16 opslab_freed_size; /* allocated size of opslab_freed */ + U16 opslab_size; /* size of slab in pointers, + including header */ + U16 opslab_free_space; /* space available in this slab + for allocating new ops (in ptr + units) */ # ifdef PERL_DEBUG_READONLY_OPS - U16 opslab_size; /* size of slab in pointers */ bool opslab_readonly; # endif OPSLOT opslab_slots; /* slots begin here */ @@ -621,7 +721,11 @@ struct opslab { # define OPSLOT_HEADER_P (OPSLOT_HEADER/sizeof(I32 *)) # define OpSLOT(o) (assert_(o->op_slabbed) \ (OPSLOT *)(((char *)o)-OPSLOT_HEADER)) -# define OpSLAB(o) OpSLOT(o)->opslot_slab + +/* the first (head) opslab of the chain in which this op is allocated */ +# define OpSLAB(o) \ + (((OPSLAB*)( (I32**)OpSLOT(o) - OpSLOT(o)->opslot_offset))->opslab_head) + # define OpslabREFCNT_dec(slab) \ (((slab)->opslab_refcnt == 1) \ ? opslab_free_nopad(slab) \ @@ -647,31 +751,31 @@ struct block_hooks { =for apidoc mx|U32|BhkFLAGS|BHK *hk Return the BHK's flags. -=for apidoc mx|void *|BhkENTRY|BHK *hk|which -Return an entry from the BHK structure. I is a preprocessor token +=for apidoc mxu|void *|BhkENTRY|BHK *hk|which +Return an entry from the BHK structure. C is a preprocessor token indicating which entry to return. If the appropriate flag is not set -this will return NULL. The type of the return value depends on which +this will return C. The type of the return value depends on which entry you ask for. -=for apidoc Amx|void|BhkENTRY_set|BHK *hk|which|void *ptr +=for apidoc Amxu|void|BhkENTRY_set|BHK *hk|which|void *ptr Set an entry in the BHK structure, and set the flags to indicate it is -valid. I is a preprocessing token indicating which entry to set. -The type of I depends on the entry. +valid. C is a preprocessing token indicating which entry to set. +The type of C depends on the entry. -=for apidoc Amx|void|BhkDISABLE|BHK *hk|which +=for apidoc Amxu|void|BhkDISABLE|BHK *hk|which Temporarily disable an entry in this BHK structure, by clearing the -appropriate flag. I is a preprocessor token indicating which +appropriate flag. C is a preprocessor token indicating which entry to disable. -=for apidoc Amx|void|BhkENABLE|BHK *hk|which +=for apidoc Amxu|void|BhkENABLE|BHK *hk|which Re-enable an entry in this BHK structure, by setting the appropriate -flag. I is a preprocessor token indicating which entry to enable. +flag. C is a preprocessor token indicating which entry to enable. This will assert (under -DDEBUGGING) if the entry doesn't contain a valid pointer. -=for apidoc mx|void|CALL_BLOCK_HOOKS|which|arg -Call all the registered block hooks for type I. I is a -preprocessing token; the type of I depends on I. +=for apidoc mxu|void|CALL_BLOCK_HOOKS|which|arg +Call all the registered block hooks for type C. C is a +preprocessing token; the type of C depends on C. =cut */ @@ -746,19 +850,19 @@ preprocessing token; the type of I depends on I. Return the XOP's flags. =for apidoc Am||XopENTRY|XOP *xop|which -Return a member of the XOP structure. I is a cpp token +Return a member of the XOP structure. C is a cpp token indicating which entry to return. If the member is not set this will return a default value. The return type depends -on I. This macro evaluates its arguments more than +on C. This macro evaluates its arguments more than once. If you are using C to retreive a C from a C, use the more efficient L instead. =for apidoc Am||XopENTRYCUSTOM|const OP *o|which Exactly like C but more -efficient. The I parameter is identical to L. +efficient. The C parameter is identical to L. =for apidoc Am|void|XopENTRY_set|XOP *xop|which|value -Set a member of the XOP structure. I is a cpp token +Set a member of the XOP structure. C is a cpp token indicating which entry to set. See L for details about the available members and how they are used. This macro evaluates its argument @@ -848,20 +952,23 @@ Return a short description of the provided OP. =for apidoc Am|U32|OP_CLASS|OP *o Return the class of the provided OP: that is, which of the *OP structures it uses. For core ops this currently gets the information out -of PL_opargs, which does not always accurately reflect the type used. +of C, which does not always accurately reflect the type used; +in v5.26 onwards, see also the function C> which can do a better +job of determining the used type. + For custom ops the type is returned from the registration, and it is up to the registree to ensure it is accurate. The value returned will be -one of the OA_* constants from op.h. +one of the C* constants from F. -=for apidoc Am|bool|OP_TYPE_IS|OP *o, Optype type -Returns true if the given OP is not a NULL pointer +=for apidoc Am|bool|OP_TYPE_IS|OP *o|Optype type +Returns true if the given OP is not a C pointer and if it is of the given type. The negation of this macro, C is also available as well as C and C which elide the NULL pointer check. -=for apidoc Am|bool|OP_TYPE_IS_OR_WAS|OP *o, Optype type +=for apidoc Am|bool|OP_TYPE_IS_OR_WAS|OP *o|Optype type Returns true if the given OP is not a NULL pointer and if it is of the given type or used to be before being replaced by an OP of type OP_NULL. @@ -869,16 +976,28 @@ replaced by an OP of type OP_NULL. The negation of this macro, C is also available as well as C and C which elide -the NULL pointer check. +the C pointer check. + +=for apidoc Am|bool|OpHAS_SIBLING|OP *o +Returns true if C has a sibling -=for apidoc Am|bool|OP_HAS_SIBLING|OP *o -Returns true if o has a sibling +=for apidoc Am|OP*|OpSIBLING|OP *o +Returns the sibling of C, or C if there is no sibling -=for apidoc Am|bool|OP_SIBLING|OP *o -Returns the sibling of o, or NULL if there is no sibling +=for apidoc Am|void|OpMORESIB_set|OP *o|OP *sib +Sets the sibling of C to the non-zero value C. See also C> +and C>. For a higher-level interface, see +C>. -=for apidoc Am|bool|OP_SIBLING_set|OP *o|OP *sib -Sets the sibling of o to sib +=for apidoc Am|void|OpLASTSIB_set|OP *o|OP *parent +Marks C as having no further siblings and marks +o as having the specified parent. See also C> and +C. For a higher-level interface, see +C>. + +=for apidoc Am|void|OpMAYBESIB_set|OP *o|OP *sib|OP *parent +Conditionally does C or C depending on whether +C is non-null. For a higher-level interface, see C>. =cut */ @@ -916,14 +1035,20 @@ Sets the sibling of o to sib #define OP_TYPE_ISNT_AND_WASNT(o, type) \ ( (o) && OP_TYPE_ISNT_AND_WASNT_NN(o, type) ) -#ifdef PERL_OP_PARENT -# define OP_HAS_SIBLING(o) (!cBOOL((o)->op_lastsib)) -# define OP_SIBLING(o) (0 + (o)->op_lastsib ? NULL : (o)->op_sibling) -# define OP_SIBLING_set(o, sib) ((o)->op_sibling = (sib)) -#else -# define OP_HAS_SIBLING(o) (cBOOL((o)->op_sibling)) -# define OP_SIBLING(o) (0 + (o)->op_sibling) -# define OP_SIBLING_set(o, sib) ((o)->op_sibling = (sib)) +/* should match anything that uses ck_ftst in regen/opcodes */ +#define OP_IS_STAT(op) (OP_IS_FILETEST(op) || (op) == OP_LSTAT || (op) == OP_STAT) + +#define OpHAS_SIBLING(o) (cBOOL((o)->op_moresib)) +#define OpSIBLING(o) (0 + (o)->op_moresib ? (o)->op_sibparent : NULL) +#define OpMORESIB_set(o, sib) ((o)->op_moresib = 1, (o)->op_sibparent = (sib)) +#define OpLASTSIB_set(o, parent) \ + ((o)->op_moresib = 0, (o)->op_sibparent = (parent)) +#define OpMAYBESIB_set(o, sib, parent) \ + ((o)->op_sibparent = ((o)->op_moresib = cBOOL(sib)) ? (sib) : (parent)) + +#if !defined(PERL_CORE) && !defined(PERL_EXT) +/* for backwards compatibility only */ +# define OP_SIBLING(o) OpSIBLING(o) #endif #define newATTRSUB(f, o, p, a, b) Perl_newATTRSUB_x(aTHX_ f, o, p, a, b, FALSE) @@ -945,12 +1070,73 @@ Sets the sibling of o to sib # define OP_CHECK_MUTEX_TERM NOOP #endif + +/* Stuff for OP_MULTDEREF/pp_multideref. */ + +/* actions */ + +/* Load another word of actions/flag bits. Must be 0 */ +#define MDEREF_reload 0 + +#define MDEREF_AV_pop_rv2av_aelem 1 +#define MDEREF_AV_gvsv_vivify_rv2av_aelem 2 +#define MDEREF_AV_padsv_vivify_rv2av_aelem 3 +#define MDEREF_AV_vivify_rv2av_aelem 4 +#define MDEREF_AV_padav_aelem 5 +#define MDEREF_AV_gvav_aelem 6 + +#define MDEREF_HV_pop_rv2hv_helem 8 +#define MDEREF_HV_gvsv_vivify_rv2hv_helem 9 +#define MDEREF_HV_padsv_vivify_rv2hv_helem 10 +#define MDEREF_HV_vivify_rv2hv_helem 11 +#define MDEREF_HV_padhv_helem 12 +#define MDEREF_HV_gvhv_helem 13 + +#define MDEREF_ACTION_MASK 0xf + +/* key / index type */ + +#define MDEREF_INDEX_none 0x00 /* run external ops to generate index */ +#define MDEREF_INDEX_const 0x10 /* index is const PV/UV */ +#define MDEREF_INDEX_padsv 0x20 /* index is lexical var */ +#define MDEREF_INDEX_gvsv 0x30 /* index is GV */ + +#define MDEREF_INDEX_MASK 0x30 + +/* bit flags */ + +#define MDEREF_FLAG_last 0x40 /* the last [ah]elem; PL_op flags apply */ + +#define MDEREF_MASK 0x7F +#define MDEREF_SHIFT 7 + +#if defined(PERL_IN_DOOP_C) || defined(PERL_IN_PP_C) +# define FATAL_ABOVE_FF_MSG \ + "Use of strings with code points over 0xFF as arguments to " \ + "%s operator is not allowed" +#endif +#if defined(PERL_IN_OP_C) || defined(PERL_IN_DOOP_C) || defined(PERL_IN_PERL_C) +# define TR_UNMAPPED (UV)-1 +# define TR_DELETE (UV)-2 +# define TR_R_EMPTY (UV)-3 /* rhs (replacement) is empty */ +# define TR_OOB (UV)-4 /* Something that isn't one of the others */ +# define TR_SPECIAL_HANDLING TR_DELETE /* Can occupy same value */ +# define TR_UNLISTED TR_UNMAPPED /* A synonym whose name is clearer + at times */ +#endif +#if defined(PERL_IN_OP_C) || defined(PERL_IN_TOKE_C) +#define RANGE_INDICATOR ILLEGAL_UTF8_BYTE +#endif + +/* stuff for OP_ARGCHECK */ + +struct op_argcheck_aux { + UV params; /* number of positional parameters */ + UV opt_params; /* number of optional positional parameters */ + char slurpy; /* presence of slurpy: may be '\0', '@' or '%' */ +}; + + /* - * Local variables: - * c-indentation-style: bsd - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - * * ex: set ts=8 sts=4 sw=4 et: */