This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge the sfio removal to blead.
[perl5.git] / op.h
diff --git a/op.h b/op.h
index 06437d4..a1869ae 100644 (file)
--- a/op.h
+++ b/op.h
  *     op_type         The type of the operation.
  *     op_opt          Whether or not the op has been optimised by the
  *                     peephole optimiser.
- *
- *                     See the comments in S_clear_yystack() for more
- *                     details on the following three flags:
- *
- *     op_latefree     tell op_free() to clear this op (and free any kids)
- *                     but not yet deallocate the struct. This means that
- *                     the op may be safely op_free()d multiple times
- *     op_latefreed    an op_latefree op has been op_free()d
- *     op_attached     this op (sub)tree has been attached to a CV
- *
- *     op_spare        three spare bits!
+ *     op_slabbed      allocated via opslab
+ *     op_static       tell op_free() to skip PerlMemShared_free(), when
+ *                      !op_slabbed.
+ *     op_savefree     on savestack via SAVEFREEOP
+ *     op_folded       Result/remainder of a constant fold operation.
+ *     op_spare        Two spare bits
  *     op_flags        Flags common to all operations.  See OPf_* below.
  *     op_private      Flags peculiar to a particular operation (BUT,
  *                     by default, set to the number of children until
@@ -59,10 +54,11 @@ typedef PERL_BITFIELD16 Optype;
     PADOFFSET  op_targ;                \
     PERL_BITFIELD16 op_type:9;         \
     PERL_BITFIELD16 op_opt:1;          \
-    PERL_BITFIELD16 op_latefree:1;     \
-    PERL_BITFIELD16 op_latefreed:1;    \
-    PERL_BITFIELD16 op_attached:1;     \
-    PERL_BITFIELD16 op_spare:3;                \
+    PERL_BITFIELD16 op_slabbed:1;      \
+    PERL_BITFIELD16 op_savefree:1;     \
+    PERL_BITFIELD16 op_static:1;       \
+    PERL_BITFIELD16 op_folded:1;       \
+    PERL_BITFIELD16 op_spare:2;                \
     U8         op_flags;               \
     U8         op_private;
 #endif
@@ -72,11 +68,9 @@ typedef PERL_BITFIELD16 Optype;
    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.*/
 
+/* for efficiency, requires OPf_WANT_VOID == G_VOID etc */
 #define OP_GIMME(op,dfl) \
-       (((op)->op_flags & OPf_WANT) == OPf_WANT_VOID   ? G_VOID   : \
-        ((op)->op_flags & OPf_WANT) == OPf_WANT_SCALAR ? G_SCALAR : \
-        ((op)->op_flags & OPf_WANT) == OPf_WANT_LIST   ? G_ARRAY   : \
-        dfl)
+       (((op)->op_flags & OPf_WANT) ? ((op)->op_flags & OPf_WANT) : dfl)
 
 #define OP_GIMME_REVERSE(flags)        ((flags) & G_WANT)
 
@@ -123,7 +117,7 @@ Deprecated.  Use C<GIMME_V> instead.
                                /*  On OP_ENTERSUB || 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 pushre, rx is used as part of split, e.g. split " " */
                                /*  On regcomp, "use re 'eval'" was in scope */
                                /*  On OP_READLINE, was <$filehandle> */
                                /*  On RV2[ACGHS]V, don't create GV--in
@@ -148,6 +142,8 @@ Deprecated.  Use C<GIMME_V> instead.
                                    - Before ck_glob, called as CORE::glob
                                    - After ck_glob, use Perl glob function
                                 */
+                                /*  On OP_PADRANGE, push @_ */
+                                /*  On OP_DUMP, has no label */
 
 /* old names; don't use in new code, but don't break them, either */
 #define OPf_LIST       OPf_WANT_LIST
@@ -176,6 +172,9 @@ Deprecated.  Use C<GIMME_V> instead.
 /* Private for OP_LEAVE, OP_LEAVESUB, OP_LEAVESUBLV and OP_LEAVEWRITE */
 #define OPpREFCOUNTED          64      /* op_targ carries a refcount */
 
+/* Private for OP_LEAVE and OP_LEAVELOOP */
+#define OPpLVALUE              128     /* Do not copy return value */
+
 /* Private for OP_AASSIGN */
 #define OPpASSIGN_COMMON       64      /* Left & right have syms in common. */
 
@@ -206,12 +205,38 @@ Deprecated.  Use C<GIMME_V> instead.
 #define OPpDEREF_HV            64      /*   Want ref to HV. */
 #define OPpDEREF_SV            (32|64) /*   Want ref to SV. */
 
+/* OP_ENTERSUB and OP_RV2CV flags
+
+Flags are set on entersub and rv2cv in three phases:
+  parser  - the parser passes the flag to the op constructor
+  check   - the check routine called by the op constructor sets the flag
+  context - application of scalar/ref/lvalue context applies the flag
+
+In the third stage, an entersub op might turn into an rv2cv op (undef &foo,
+\&foo, lock &foo, exists &foo, defined &foo).  The two places where that
+happens (op_lvalue_flags and doref in op.c) need to make sure the flags do
+not conflict.  Flags applied in the context phase are only set when there
+is no conversion of op type.
+
+  bit  entersub flag       phase   rv2cv flag             phase
+  ---  -------------       -----   ----------             -----
+    1  OPpENTERSUB_INARGS  context OPpMAY_RETURN_CONSTANT context
+    2  HINT_STRICT_REFS    check   HINT_STRICT_REFS       check
+    4  OPpENTERSUB_HASTARG check
+    8                              OPpENTERSUB_AMPER      parser
+   16  OPpENTERSUB_DB      check
+   32  OPpDEREF_AV         context
+   64  OPpDEREF_HV         context
+  128  OPpLVAL_INTRO       context OPpENTERSUB_NOPAREN    parser
+
+*/
+
   /* OP_ENTERSUB only */
 #define OPpENTERSUB_DB         16      /* Debug subroutine. */
 #define OPpENTERSUB_HASTARG    4       /* Called from OP tree. */
 #define OPpENTERSUB_INARGS     1       /* Lval used as arg to a sub. */
 /* used by OPpDEREF             (32|64) */
-/* used by HINT_STRICT_SUBS     2          */
+/* used by HINT_STRICT_REFS     2          */
   /* Mask for OP_ENTERSUB flags, the absence of which must be propagated
      in dynamic context */
 #define OPpENTERSUB_LVAL_MASK (OPpLVAL_INTRO|OPpENTERSUB_INARGS)
@@ -225,11 +250,18 @@ Deprecated.  Use C<GIMME_V> instead.
 #define OPpEARLY_CV            32      /* foo() called before sub foo was parsed */
   /* OP_?ELEM only */
 #define OPpLVAL_DEFER          16      /* Defer creation of array/hash elem */
+  /* OP_RV2[AH]V OP_[AH]SLICE */
+#define OPpSLICEWARNING                4       /* warn about @hash{$scalar} */
   /* OP_RV2[SAH]V, OP_GVSV, OP_ENTERITER only */
 #define OPpOUR_INTRO           16      /* Variable was in an our() */
   /* OP_RV2[AGH]V, OP_PAD[AH]V, OP_[AH]ELEM, OP_[AH]SLICE OP_AV2ARYLEN,
      OP_R?KEYS, OP_SUBSTR, OP_POS, OP_VEC */
 #define OPpMAYBE_LVSUB         8       /* We might be an lvalue to return */
+  /* OP_RV2HV and OP_PADHV */
+#define OPpTRUEBOOL            32      /* %hash in (%hash || $foo) in
+                                          void context */
+#define OPpMAYBE_TRUEBOOL      64      /* %hash in (%hash || $foo) where
+                                          cx is not known till run time */
 
   /* OP_SUBSTR only */
 #define OPpSUBSTR_REPL_FIRST   16      /* 1st arg is replacement string */
@@ -238,6 +270,11 @@ Deprecated.  Use C<GIMME_V> instead.
 #define OPpPAD_STATE           16      /* is a "state" pad */
   /* for OP_RV2?V, lower bits carry hints (currently only HINT_STRICT_REFS) */
 
+  /* OP_PADRANGE only */
+  /* bit 7 is OPpLVAL_INTRO */
+#define OPpPADRANGE_COUNTMASK  127     /* bits 6..0 hold target range, */
+#define OPpPADRANGE_COUNTSHIFT 7       /* 7 bits in total */
+
   /* OP_RV2GV only */
 #define OPpDONT_INIT_GV                4       /* Call gv_fetchpv with GV_NOINIT */
 /* (Therefore will return whatever is currently in the symbol table, not
@@ -286,9 +323,13 @@ Deprecated.  Use C<GIMME_V> instead.
 #define OPpOPEN_OUT_RAW                64      /* binmode(F,":raw") on output fh */
 #define OPpOPEN_OUT_CRLF       128     /* binmode(F,":crlf") on output fh */
 
-/* Private for OP_EXIT, HUSH also for OP_DIE */
-#define OPpHUSH_VMSISH         64      /* hush DCL exit msg vmsish mode*/
-#define OPpEXIT_VMSISH         128     /* exit(0) vs. exit(1) vmsish mode*/
+/* Private for COPs */
+#define OPpHUSH_VMSISH         32      /* hush DCL exit msg vmsish mode*/
+/* Note: Used for NATIVE_HINTS (shifted from the values in PL_hints),
+        currently defined by vms/vmsish.h:
+                               64
+                               128
+ */
 
 /* Private for OP_FTXXX */
 #define OPpFT_ACCESS           2       /* use filetest 'access' */
@@ -304,6 +345,7 @@ Deprecated.  Use C<GIMME_V> instead.
 #define OPpEVAL_UNICODE                4
 #define OPpEVAL_BYTES          8
 #define OPpEVAL_COPHH          16      /* Construct %^H from cop hints */
+#define OPpEVAL_RE_REPARSING   32      /* eval_sv(..., G_RE_REPARSING) */
     
 /* Private for OP_CALLER, OP_WANTARRAY and OP_RUNCV */
 #define OPpOFFBYONE            128     /* Treat caller(1) as caller(2) */
@@ -319,6 +361,9 @@ Deprecated.  Use C<GIMME_V> instead.
 /* Private for OP_(LAST|REDO|NEXT|GOTO|DUMP) */
 #define OPpPV_IS_UTF8          128     /* label is in UTF8 */
 
+/* Private for OP_SPLIT */
+#define OPpSPLIT_IMPLIM                128     /* implicit limit */
+
 struct op {
     BASEOP
 };
@@ -351,7 +396,7 @@ struct pmop {
     OP *       op_first;
     OP *       op_last;
 #ifdef USE_ITHREADS
-    IV          op_pmoffset;
+    PADOFFSET   op_pmoffset;
 #else
     REGEXP *    op_pmregexp;            /* compiled expression */
 #endif
@@ -367,10 +412,7 @@ struct pmop {
     union {
        OP *    op_pmreplstart; /* Only used in OP_SUBST */
 #ifdef USE_ITHREADS
-       struct {
-            char *     op_pmstashpv;   /* Only used in OP_MATCH, with PMf_ONCE set */
-            U32     op_pmstashflags;  /* currently only SVf_UTF8 or 0 */
-        } op_pmstashthr;
+       PADOFFSET op_pmstashoff; /* Only used in OP_MATCH, with PMf_ONCE set */
 #else
        HV *    op_pmstash;
 #endif
@@ -411,10 +453,7 @@ struct pmop {
  * OP_MATCH and OP_QR */
 #define PMf_ONCE       (1<<(PMf_BASE_SHIFT+1))
 
-/* replacement contains variables */
-#define PMf_MAYBE_CONST (1<<(PMf_BASE_SHIFT+2))
-
-/* PMf_ONCE has matched successfully.  Not used under threading. */
+/* PMf_ONCE, i.e. ?pat?, has matched successfully.  Not used under threading. */
 #define PMf_USED        (1<<(PMf_BASE_SHIFT+3))
 
 /* subst replacement is constant */
@@ -441,36 +480,25 @@ struct pmop {
  * code within another sub, with different pad etc */
 #define PMf_CODELIST_PRIVATE   (1<<(PMf_BASE_SHIFT+11))
 
-#if PMf_BASE_SHIFT+11 > 31
+/* 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      (1<<(PMf_BASE_SHIFT+12))
+#define PMf_USE_RE_EVAL        (1<<(PMf_BASE_SHIFT+13)) /* use re'eval' in scope */
+
+#if PMf_BASE_SHIFT+13 > 31
 #   error Too many PMf_ bits used.  See above and regnodes.h for any spare in middle
 #endif
 
 #ifdef USE_ITHREADS
 
-#  define PmopSTASHPV(o)                                               \
-    (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstashthr.op_pmstashpv : NULL)
-#  if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-#    define PmopSTASHPV_set(o,pv)      ({                              \
-       assert((o)->op_pmflags & PMf_ONCE);                             \
-       ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashpv = savesharedpv(pv));  \
-    })
-#  else
-#    define PmopSTASHPV_set(o,pv)                                      \
-    ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashpv = savesharedpv(pv))
-#  endif
-#  define PmopSTASH_flags(o)           ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashflags)
-#  define PmopSTASH_flags_set(o,flags) ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashflags = flags)
-#  define PmopSTASH(o)         (PmopSTASHPV(o)                                     \
-                                ? gv_stashpv((o)->op_pmstashstartu.op_pmstashthr.op_pmstashpv,   \
-                                            GV_ADD | PmopSTASH_flags(o)) : NULL)
-#  define PmopSTASH_set(o,hv)  (PmopSTASHPV_set(o, (hv) ? HvNAME_get(hv) : NULL), \
-                                PmopSTASH_flags_set(o,                            \
-                                            ((hv) && HvNAME_HEK(hv) &&           \
-                                                        HvNAMEUTF8(hv))           \
-                                                ? SVf_UTF8                        \
-                                                : 0))
-#  define PmopSTASH_free(o)    PerlMemShared_free(PmopSTASHPV(o))
-
+#  define PmopSTASH(o)         ((o)->op_pmflags & PMf_ONCE                         \
+                                ? PL_stashpad[(o)->op_pmstashstartu.op_pmstashoff]   \
+                                : NULL)
+#  define PmopSTASH_set(o,hv)  \
+       (assert_((o)->op_pmflags & PMf_ONCE)                            \
+        (o)->op_pmstashstartu.op_pmstashoff =                          \
+           (hv) ? alloccopstash(hv) : 0)
 #else
 #  define PmopSTASH(o)                                                 \
     (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstash : NULL)
@@ -482,13 +510,10 @@ struct pmop {
 #  else
 #    define PmopSTASH_set(o,hv)        ((o)->op_pmstashstartu.op_pmstash = (hv))
 #  endif
-#  define PmopSTASHPV(o)       (PmopSTASH(o) ? HvNAME_get(PmopSTASH(o)) : NULL)
-   /* op_pmstashstartu.op_pmstash is not refcounted */
-#  define PmopSTASHPV_set(o,pv)        PmopSTASH_set((o), gv_stashpv(pv,GV_ADD))
-/* Note that if this becomes non-empty, then S_forget_pmop in op.c will need
-   changing */
-#  define PmopSTASH_free(o)    
 #endif
+#define PmopSTASHPV(o) (PmopSTASH(o) ? HvNAME_get(PmopSTASH(o)) : NULL)
+   /* op_pmstashstartu.op_pmstash is not refcounted */
+#define PmopSTASHPV_set(o,pv)  PmopSTASH_set((o), gv_stashpv(pv,GV_ADD))
 
 struct svop {
     BASEOP
@@ -563,7 +588,8 @@ struct loop {
 #  define      cGVOPx_gv(o)    ((GV*)PAD_SVl(cPADOPx(o)->op_padix))
 #  define      IS_PADGV(v)     (v && SvTYPE(v) == SVt_PVGV && isGV_with_GP(v) \
                                 && GvIN_PAD(v))
-#  define      IS_PADCONST(v)  (v && SvREADONLY(v))
+#  define      IS_PADCONST(v) \
+       (v && (SvREADONLY(v) || (SvIsCOW(v) && !SvLEN(v))))
 #  define      cSVOPx_sv(v)    (cSVOPx(v)->op_sv \
                                 ? cSVOPx(v)->op_sv : PAD_SVl((v)->op_targ))
 #  define      cSVOPx_svp(v)   (cSVOPx(v)->op_sv \
@@ -702,19 +728,66 @@ least an C<UNOP>.
 #include "reentr.h"
 #endif
 
-#if defined(PL_OP_SLAB_ALLOC)
 #define NewOp(m,var,c,type)    \
        (var = (type *) Perl_Slab_Alloc(aTHX_ c*sizeof(type)))
 #define NewOpSz(m,var,size)    \
        (var = (OP *) Perl_Slab_Alloc(aTHX_ size))
 #define FreeOp(p) Perl_Slab_Free(aTHX_ p)
-#else
-#define NewOp(m, var, c, type) \
-       (var = (MEM_WRAP_CHECK_(c,type) \
-        (type*)PerlMemShared_calloc(c, sizeof(type))))
-#define NewOpSz(m, var, size)  \
-       (var = (OP*)PerlMemShared_calloc(1, size))
-#define FreeOp(p) PerlMemShared_free(p)
+
+/*
+ * The per-CV op slabs consist of a header (the opslab struct) and a bunch
+ * of space for allocating op slots, each of which consists of two pointers
+ * followed by an op.  The first pointer points to the next op slot.  The
+ * second points to the slab.  At the end of the slab is a null pointer,
+ * so that slot->opslot_next - slot can be used to determine the size
+ * of the op.
+ *
+ * Each CV can have multiple slabs; opslab_next points to the next slab, to
+ * form a chain.  All bookkeeping is done on the first slab, which is where
+ * all the op slots point.
+ *
+ * Freed ops are marked as freed and attached to the freed chain
+ * via op_next pointers.
+ *
+ * When there is more than one slab, the second slab in the slab chain is
+ * assumed to be the one with free space available.  It is used when allo-
+ * cating an op if there are no freed ops available or big enough.
+ */
+
+#ifdef PERL_CORE
+struct opslot {
+    /* keep opslot_next first */
+    OPSLOT *   opslot_next;            /* next slot */
+    OPSLAB *   opslot_slab;            /* owner */
+    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 */
+# ifdef PERL_DEBUG_READONLY_OPS
+    U16                opslab_size;            /* size of slab in pointers */
+    bool       opslab_readonly;
+# endif
+    OPSLOT     opslab_slots;           /* slots begin here */
+};
+
+# define OPSLOT_HEADER         STRUCT_OFFSET(OPSLOT, opslot_op)
+# 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
+# define OpslabREFCNT_dec(slab)      \
+       (((slab)->opslab_refcnt == 1) \
+        ? opslab_free_nopad(slab)     \
+        : (void)--(slab)->opslab_refcnt)
+  /* Variant that does not null out the pads */
+# define OpslabREFCNT_dec_padok(slab) \
+       (((slab)->opslab_refcnt == 1)  \
+        ? opslab_free(slab)            \
+        : (void)--(slab)->opslab_refcnt)
 #endif
 
 struct block_hooks {
@@ -790,7 +863,7 @@ preprocessing token; the type of I<arg> depends on I<which>.
 #define CALL_BLOCK_HOOKS(which, arg) \
     STMT_START { \
        if (PL_blockhooks) { \
-           I32 i; \
+           SSize_t i; \
            for (i = av_len(PL_blockhooks); i >= 0; i--) { \
                SV *sv = AvARRAY(PL_blockhooks)[i]; \
                BHK *hk; \
@@ -827,12 +900,19 @@ 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 indicating
 which entry to return. If the member is not set this will return a
-default value. The return type depends on I<which>.
+default value. The return type depends on I<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>.
 
 =for apidoc Am|void|XopENTRY_set|XOP *xop|which|value
 Set a member of the XOP structure. I<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.
+the available members and how they are used. This macro evaluates its argument
+more than once.
 
 =for apidoc Am|void|XopDISABLE|XOP *xop|which
 Temporarily disable a member of the XOP, by clearing the appropriate flag.
@@ -851,6 +931,17 @@ struct custom_op {
     void         (*xop_peep)(pTHX_ OP *o, OP *oldop);
 };
 
+/* return value of Perl_custom_op_get_field, similar to void * then casting but
+   the U32 doesn't need truncation on 64 bit platforms in the caller, also
+   for easier macro writing */
+typedef union {
+    const char    *xop_name;
+    const char    *xop_desc;
+    U32                    xop_class;
+    void         (*xop_peep)(pTHX_ OP *o, OP *oldop);
+    XOP            *xop_ptr;
+} XOPRETANY;
+
 #define XopFLAGS(xop) ((xop)->xop_flags)
 
 #define XOPf_xop_name  0x01
@@ -858,6 +949,15 @@ struct custom_op {
 #define XOPf_xop_class 0x04
 #define XOPf_xop_peep  0x08
 
+/* used by Perl_custom_op_get_field for option checking */
+typedef enum {
+    XOPe_xop_ptr = 0, /* just get the XOP *, don't look inside it */
+    XOPe_xop_name = XOPf_xop_name,
+    XOPe_xop_desc = XOPf_xop_desc,
+    XOPe_xop_class = XOPf_xop_class,
+    XOPe_xop_peep = XOPf_xop_peep,
+} xop_flags_enum;
+
 #define XOPd_xop_name  PL_op_name[OP_CUSTOM]
 #define XOPd_xop_desc  PL_op_desc[OP_CUSTOM]
 #define XOPd_xop_class OA_BASEOP
@@ -872,6 +972,9 @@ struct custom_op {
 #define XopENTRY(xop, which) \
     ((XopFLAGS(xop) & XOPf_ ## which) ? (xop)->which : XOPd_ ## which)
 
+#define XopENTRYCUSTOM(o, which) \
+    (Perl_custom_op_get_field(aTHX_ o, XOPe_ ## which).which)
+
 #define XopDISABLE(xop, which) ((xop)->xop_flags &= ~XOPf_ ## which)
 #define XopENABLE(xop, which) \
     STMT_START { \
@@ -879,6 +982,9 @@ struct custom_op {
        assert(XopENTRY(xop, which)); \
     } STMT_END
 
+#define Perl_custom_op_xop(x) \
+    (Perl_custom_op_get_field(x, XOPe_xop_ptr).xop_ptr)
+
 /*
 =head1 Optree Manipulation Functions
 
@@ -897,20 +1003,27 @@ 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.
 
+=for apidoc Am|bool|OP_TYPE_IS|OP *o, Optype type
+Returns true if the given OP is not NULL and if it is of the given
+type.
 =cut
 */
 
 #define OP_NAME(o) ((o)->op_type == OP_CUSTOM \
-                   ? XopENTRY(Perl_custom_op_xop(aTHX_ o), xop_name) \
+                    ? XopENTRYCUSTOM(o, xop_name) \
                    : PL_op_name[(o)->op_type])
 #define OP_DESC(o) ((o)->op_type == OP_CUSTOM \
-                   ? XopENTRY(Perl_custom_op_xop(aTHX_ o), xop_desc) \
+                    ? XopENTRYCUSTOM(o, xop_desc) \
                    : PL_op_desc[(o)->op_type])
 #define OP_CLASS(o) ((o)->op_type == OP_CUSTOM \
-                    ? XopENTRY(Perl_custom_op_xop(aTHX_ o), xop_class) \
+                    ? XopENTRYCUSTOM(o, xop_class) \
                     : (PL_opargs[(o)->op_type] & OA_CLASS_MASK))
 
-#define newSUB(f, o, p, b)     Perl_newATTRSUB(aTHX_ (f), (o), (p), NULL, (b))
+#define OP_TYPE_IS(o, type) ((o) && (o)->op_type == (type))
+
+
+#define newATTRSUB(f, o, p, a, b) Perl_newATTRSUB_x(aTHX_  f, o, p, a, b, FALSE)
+#define newSUB(f, o, p, b)     newATTRSUB((f), (o), (p), NULL, (b))
 
 #ifdef PERL_MAD
 #  define MAD_NULL 1