X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/6d4eed2136c73d9331ed2edb2e7650c90b974ea7..4c210ae9fdfacb3cd9e99e11f0a1b017805effa6:/op.h diff --git a/op.h b/op.h index befdc79..ef85148 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, @@ -38,12 +38,21 @@ typedef PERL_BITFIELD16 Optype; +/* this field now either points to the next sibling or to the parent, + * depending on op_moresib. So rename it from op_sibling to op_sibparent. + */ +#ifdef PERL_OP_PARENT +# define _OP_SIBPARENT_FIELDNAME op_sibparent +#else +# define _OP_SIBPARENT_FIELDNAME op_sibling +#endif + #ifdef BASEOP_DEFINITION #define BASEOP BASEOP_DEFINITION #else #define BASEOP \ OP* op_next; \ - OP* op_sibling; \ + OP* _OP_SIBPARENT_FIELDNAME;\ OP* (*op_ppaddr)(pTHX); \ PADOFFSET op_targ; \ PERL_BITFIELD16 op_type:9; \ @@ -52,13 +61,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.*/ @@ -104,15 +113,16 @@ Deprecated. Use C instead. /* 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 +134,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 @@ -142,18 +153,20 @@ Deprecated. Use C instead. /* 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 +#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, @@ -169,6 +182,22 @@ Deprecated. Use C instead. #define OPpENTERSUB_LVAL_MASK (OPpLVAL_INTRO|OPpENTERSUB_INARGS) +/* things that can be elements of op_aux */ +typedef union { + PADOFFSET pad_offset; + SV *sv; + IV iv; + UV uv; +} 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 + + + struct op { BASEOP @@ -179,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; @@ -225,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 */ @@ -293,7 +325,11 @@ 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+4)) /* 'use re "taint"' in scope: taint $1 etc. if target tainted */ #define PMf_RETAINT (1U<<(PMf_BASE_SHIFT+5)) @@ -393,19 +429,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 cMETHOPx(o) ((METHOP*)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) @@ -417,6 +455,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) @@ -428,6 +467,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) @@ -439,6 +479,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 @@ -505,6 +563,7 @@ struct loop { #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 */ @@ -573,7 +632,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 @@ -672,30 +731,30 @@ struct block_hooks { 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 +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 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 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 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. +Call all the registered block hooks for type C. C is a +preprocessing token; the type of C depends on C. =cut */ @@ -770,19 +829,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 @@ -872,20 +931,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. @@ -893,16 +955,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|OP*|OpSIBLING|OP *o +Returns the sibling of C, or C if there is no sibling -=for apidoc Am|bool|OP_HAS_SIBLING|OP *o -Returns true if o has a 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|OP *o -Returns the sibling of o, or NULL if there is no sibling +=for apidoc Am|void|OpLASTSIB_set|OP *o|OP *parent +Marks C as having no further siblings. On C builds, marks +o as having the specified parent. 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|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 */ @@ -940,14 +1014,28 @@ 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)) +# 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)) #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)) +# define OpHAS_SIBLING(o) (cBOOL((o)->op_sibling)) +# define OpSIBLING(o) (0 + (o)->op_sibling) +# define OpMORESIB_set(o, sib) ((o)->op_moresib = 1, (o)->op_sibling = (sib)) +# define OpLASTSIB_set(o, parent) \ + ((o)->op_moresib = 0, (o)->op_sibling = NULL) +# define OpMAYBESIB_set(o, sib, parent) \ + ((o)->op_moresib = cBOOL(sib), (o)->op_sibling = (sib)) +#endif + +#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) @@ -969,12 +1057,53 @@ 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) +static const char * const fatal_above_ff_msg + = "Use of strings with code points over 0xFF as arguments to " + "%s operator is not allowed"; +#endif + + /* - * Local variables: - * c-indentation-style: bsd - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - * * ex: set ts=8 sts=4 sw=4 et: */