* !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,
#else
#define BASEOP \
OP* op_next; \
- OP* op_sibling; \
+ OP* op_sibparent; \
OP* (*op_ppaddr)(pTHX); \
PADOFFSET op_targ; \
PERL_BITFIELD16 op_type:9; \
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.*/
#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 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()*/
/* 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
SV *sv;
IV iv;
UV uv;
+ char *pv;
+ SSize_t ssize;
} UNOP_AUX_item;
#ifdef USE_ITHREADS
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 */
* other end instead; this preserves binary compatibility. */
#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))
#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
# define cMETHOPx_rclass(v) (cMETHOPx(v)->op_rclass_sv)
#endif
-# define cMETHOPx_meth(v) cSVOPx_sv(v)
+#define cMETHOPx_meth(v) cSVOPx_sv(v)
#define cGVOP_gv cGVOPx_gv(PL_op)
#define cGVOPo_gv cGVOPx_gv(o)
#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
Given the root of an optree, link the tree in execution order using the
C<op_next> 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<o> should be at
+returned. If C<< o->op_next >> is not already set, C<o> should be at
least an C<UNOP>.
=cut
struct opslot {
/* keep opslot_next first */
OPSLOT * opslot_next; /* next slot */
- OPSLAB * opslot_slab; /* owner */
+ 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 */
+ OPSLAB * opslab_head; /* first slab in chain */
OP * opslab_freed; /* chain of freed ops */
- size_t opslab_refcnt; /* number of ops */
+ size_t opslab_refcnt; /* number of ops (head slab only) */
# ifdef PERL_DEBUG_READONLY_OPS
U16 opslab_size; /* size of slab in pointers */
bool opslab_readonly;
# 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) \
Return the BHK's flags.
=for apidoc mx|void *|BhkENTRY|BHK *hk|which
-Return an entry from the BHK structure. I<which> is a preprocessor token
+Return an entry from the BHK structure. C<which> 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<NULL>. 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<which> is a preprocessing token indicating which entry to set.
-The type of I<ptr> depends on the entry.
+valid. C<which> is a preprocessing token indicating which entry to set.
+The type of C<ptr> 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<which> is a preprocessor token indicating which
+appropriate flag. C<which> 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<which> is a preprocessor token indicating which entry to enable.
+flag. C<which> 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<which>. I<which> is a
-preprocessing token; the type of I<arg> depends on I<which>.
+Call all the registered block hooks for type C<which>. C<which> is a
+preprocessing token; the type of C<arg> depends on C<which>.
=cut
*/
Return the XOP's flags.
=for apidoc Am||XopENTRY|XOP *xop|which
-Return a member of the XOP structure. I<which> is a cpp token
+Return a member of the XOP structure. C<which> 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<which>. This macro evaluates its arguments more than
+on C<which>. This macro evaluates its arguments more than
once. If you are using C<Perl_custom_op_xop> to retreive a
C<XOP *> from a C<OP *>, use the more efficient L</XopENTRYCUSTOM> instead.
=for apidoc Am||XopENTRYCUSTOM|const OP *o|which
Exactly like C<XopENTRY(XopENTRY(Perl_custom_op_xop(aTHX_ o), which)> but more
-efficient. The I<which> parameter is identical to L</XopENTRY>.
+efficient. The C<which> parameter is identical to L</XopENTRY>.
=for apidoc Am|void|XopENTRY_set|XOP *xop|which|value
-Set a member of the XOP structure. I<which> is a cpp token
+Set a member of the XOP structure. C<which> is a cpp token
indicating which entry to set. See L<perlguts/"Custom Operators">
for details about the available members and how
they are used. This macro evaluates its argument
=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<PL_opargs>, which does not always accurately reflect the type used;
+in v5.26 onwards, see also the function C<L</op_class>> 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<OA_>* constants from F<op.h>.
=for apidoc Am|bool|OP_TYPE_IS|OP *o|Optype type
-Returns true if the given OP is not a NULL pointer
+Returns true if the given OP is not a C<NULL> pointer
and if it is of the given type.
The negation of this macro, C<OP_TYPE_ISNT> is also available
The negation of this macro, C<OP_TYPE_ISNT_AND_WASNT>
is also available as well as C<OP_TYPE_IS_OR_WAS_NN>
and C<OP_TYPE_ISNT_AND_WASNT_NN> which elide
-the NULL pointer check.
+the C<NULL> pointer check.
=for apidoc Am|bool|OpHAS_SIBLING|OP *o
-Returns true if o has a sibling
+Returns true if C<o> has a sibling
+
+=for apidoc Am|OP*|OpSIBLING|OP *o
+Returns the sibling of C<o>, or C<NULL> if there is no sibling
+
+=for apidoc Am|void|OpMORESIB_set|OP *o|OP *sib
+Sets the sibling of C<o> to the non-zero value C<sib>. See also C<L</OpLASTSIB_set>>
+and C<L</OpMAYBESIB_set>>. For a higher-level interface, see
+C<L</op_sibling_splice>>.
-=for apidoc Am|bool|OpSIBLING|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<o> as having no further siblings and marks
+o as having the specified parent. See also C<L</OpMORESIB_set>> and
+C<OpMAYBESIB_set>. For a higher-level interface, see
+C<L</op_sibling_splice>>.
-=for apidoc Am|bool|OpSIBLING_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<OpMORESIB_set> or C<OpLASTSIB_set> depending on whether
+C<sib> is non-null. For a higher-level interface, see C<L</op_sibling_splice>>.
=cut
*/
#define OP_TYPE_ISNT_AND_WASNT(o, type) \
( (o) && OP_TYPE_ISNT_AND_WASNT_NN(o, type) )
-#ifdef PERL_OP_PARENT
-# define OpHAS_SIBLING(o) (!cBOOL((o)->op_lastsib))
-# define OpSIBLING(o) (0 + (o)->op_lastsib ? NULL : (o)->op_sibling)
-# define OpSIBLING_set(o, sib) ((o)->op_sibling = (sib))
-#else
-# define OpHAS_SIBLING(o) (cBOOL((o)->op_sibling))
-# define OpSIBLING(o) (0 + (o)->op_sibling)
-# define OpSIBLING_set(o, sib) ((o)->op_sibling = (sib))
-#endif
+/* 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 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"
+# define DEPRECATED_ABOVE_FF_MSG \
+ "Use of strings with code points over 0xFF as arguments to " \
+ "%s operator is deprecated. This will be a fatal error in " \
+ "Perl 5.32"
+#endif
+
/*
* ex: set ts=8 sts=4 sw=4 et: