X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/59f00321bbc2d04656a65e0e9ccbbd93a8708e71..36491eae02a83b9427d3cd26fd92b13a1c12602b:/op.h diff --git a/op.h b/op.h index aeaae1c..2720df0 100644 --- a/op.h +++ b/op.h @@ -1,7 +1,7 @@ /* op.h * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -17,6 +17,19 @@ * parent takes over role of remembering starting op.) * op_ppaddr Pointer to current ppcode's function. * 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_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 @@ -24,10 +37,12 @@ * which may or may not check number of children). */ -#ifdef DEBUGGING_OPS -#define OPCODE opcode -#else #define OPCODE U16 + +#ifdef PERL_MAD +# define MADPROP_IN_BASEOP MADPROP* op_madprop; +#else +# define MADPROP_IN_BASEOP #endif #ifdef BASEOP_DEFINITION @@ -37,9 +52,14 @@ OP* op_next; \ OP* op_sibling; \ OP* (CPERLscope(*op_ppaddr))(pTHX); \ + MADPROP_IN_BASEOP \ PADOFFSET op_targ; \ - OPCODE op_type; \ - U16 op_seq; \ + unsigned op_type:9; \ + unsigned op_opt:1; \ + unsigned op_latefree:1; \ + unsigned op_latefreed:1; \ + unsigned op_attached:1; \ + unsigned op_spare:3; \ U8 op_flags; \ U8 op_private; #endif @@ -83,6 +103,8 @@ Deprecated. Use C instead. #define OPf_STACKED 64 /* Some arg is arriving on the stack. */ #define OPf_SPECIAL 128 /* Do something weird for this op: */ /* On local LVAL, don't init local value. */ + /* On OP_CONST, value is the hints hash for + eval, so return a copy from pp_const() */ /* On OP_SORT, subroutine is inlined. */ /* On OP_NOT, inversion was implicit. */ /* On OP_LEAVE, don't restore curpm. */ @@ -94,12 +116,20 @@ Deprecated. Use C instead. /* On OP_EXISTS, treat av as av, not avhv. */ /* On OP_(ENTER|LEAVE)EVAL, don't clear $@ */ /* On OP_ENTERITER, loop var is per-thread */ - /* On pushre, re is /\s+/ imp. by 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[SG]V, don't create GV--in defined()*/ + /* On RV2[ACGHS]V, don't create GV--in + defined()*/ /* On OP_DBSTATE, indicates breakpoint * (runtime property) */ + /* On OP_AELEMFAST, indiciates pad var */ + /* On OP_REQUIRE, was seen as CORE::require */ + /* On OP_ENTERWHEN, there's no condition */ + /* On OP_BREAK, an implicit break */ + /* On OP_SMARTMATCH, an implicit smartmatch */ + /* On OP_ANONHASH and OP_ANONLIST, create a + reference to the new anon hash or array */ /* old names; don't use in new code, but don't break them, either */ #define OPf_LIST OPf_WANT_LIST @@ -126,6 +156,7 @@ Deprecated. Use C instead. /* Private for OP_SASSIGN */ #define OPpASSIGN_BACKWARDS 64 /* Left & right switched. */ +#define OPpASSIGN_CV_TO_GV 128 /* Possible optimisation for constants. */ /* Private for OP_MATCH and OP_SUBST{,CONST} */ #define OPpRUNTIME 64 /* Pattern coming in on the stack */ @@ -144,8 +175,8 @@ Deprecated. Use C instead. /* Private for OP_REPEAT */ #define OPpREPEAT_DOLIST 64 /* List replication. */ -/* Private for OP_RV2?V, OP_?ELEM */ -#define OPpDEREF (32|64) /* Want ref to something: */ +/* Private for OP_RV2GV, OP_RV2SV, OP_AELEM, OP_HELEM, OP_PADSV */ +#define OPpDEREF (32|64) /* autovivify: Want ref to something: */ #define OPpDEREF_AV 32 /* Want ref to AV. */ #define OPpDEREF_HV 64 /* Want ref to HV. */ #define OPpDEREF_SV (32|64) /* Want ref to SV. */ @@ -163,15 +194,31 @@ Deprecated. Use C instead. #define OPpLVAL_DEFER 16 /* Defer creation of array/hash elem */ /* OP_RV2?V, OP_GVSV, OP_ENTERITER only */ #define OPpOUR_INTRO 16 /* Variable was in an our() */ - /* OP_RV2[AH]V, OP_PAD[AH]V, OP_[AH]ELEM */ + /* OP_RV2[AGH]V, OP_PAD[AH]V, OP_[AH]ELEM */ #define OPpMAYBE_LVSUB 8 /* We might be an lvalue to return */ + /* OP_PADSV only */ +#define OPpPAD_STATE 16 /* is a "state" pad */ /* for OP_RV2?V, lower bits carry hints (currently only HINT_STRICT_REFS) */ + /* 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 + guaranteed to be a PVGV) */ + + /* OP_RV2CV only */ +#define OPpMAY_RETURN_CONSTANT 1 /* If a constant sub, return the constant */ + /* Private for OPs with TARGLEX */ /* (lower bits may carry MAXARG) */ #define OPpTARGET_MY 16 /* Target is PADMY. */ +/* Private for OP_ENTERITER and OP_ITER */ +#define OPpITER_REVERSED 4 /* for (reverse ...) */ +#define OPpITER_DEF 8 /* for $_ or for my $_ */ + /* Private for OP_CONST */ +#define OPpCONST_NOVER 2 /* no 6; */ +#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 || foo) */ #define OPpCONST_STRICT 8 /* bearword subject to strict 'subs' */ #define OPpCONST_ENTERED 16 /* Has been entered as symbol. */ #define OPpCONST_ARYBASE 32 /* Was a $[ translated to constant. */ @@ -193,7 +240,12 @@ Deprecated. Use C instead. /* Private for OP_SORT */ #define OPpSORT_NUMERIC 1 /* Optimized away { $a <=> $b } */ #define OPpSORT_INTEGER 2 /* Ditto while under "use integer" */ -#define OPpSORT_REVERSE 4 /* Descending sort */ +#define OPpSORT_REVERSE 4 /* Reversed sort */ +#define OPpSORT_INPLACE 8 /* sort in-place; eg @a = sort @a */ +#define OPpSORT_DESCEND 16 /* Descending sort */ +#define OPpSORT_QSORT 32 /* Use quicksort (not mergesort) */ +#define OPpSORT_STABLE 64 /* Use a stable algorithm */ + /* Private for OP_THREADSV */ #define OPpDONE_SVREF 64 /* Been through newSVREF once */ @@ -207,8 +259,9 @@ Deprecated. Use C instead. #define OPpHUSH_VMSISH 64 /* hush DCL exit msg vmsish mode*/ #define OPpEXIT_VMSISH 128 /* exit(0) vs. exit(1) vmsish mode*/ -/* Private of OP_FTXXX */ +/* Private for OP_FTXXX */ #define OPpFT_ACCESS 2 /* use filetest 'access' */ +#define OPpFT_STACKED 4 /* stacked filetest, as in "-f -x $f" */ #define OP_IS_FILETEST_ACCESS(op) \ (((op)->op_type) == OP_FTRREAD || \ ((op)->op_type) == OP_FTRWRITE || \ @@ -220,6 +273,9 @@ Deprecated. Use C instead. /* Private for OP_(MAP|GREP)(WHILE|START) */ #define OPpGREP_LEX 2 /* iterate over lexical $_ */ +/* Private for OP_ENTEREVAL */ +#define OPpEVAL_HAS_HH 2 /* Does it have a copy of %^H */ + struct op { BASEOP }; @@ -251,27 +307,36 @@ struct pmop { BASEOP OP * op_first; OP * op_last; - OP * op_pmreplroot; - OP * op_pmreplstart; - PMOP * op_pmnext; /* list of all scanpats */ #ifdef USE_ITHREADS IV op_pmoffset; #else REGEXP * op_pmregexp; /* compiled expression */ #endif - U32 op_pmflags; - U32 op_pmpermflags; - U8 op_pmdynflags; + U32 op_pmflags; + union { + OP * op_pmreplroot; /* For OP_SUBST */ #ifdef USE_ITHREADS - char * op_pmstashpv; + PADOFFSET op_pmtargetoff; /* For OP_PUSHRE */ #else - HV * op_pmstash; + GV * op_pmtargetgv; #endif + } op_pmreplrootu; + union { + OP * op_pmreplstart; /* Only used in OP_SUBST */ +#ifdef USE_ITHREADS + char * op_pmstashpv; /* Only used in OP_MATCH, with PMf_ONCE set */ +#else + HV * op_pmstash; +#endif + } op_pmstashstartu; }; #ifdef USE_ITHREADS #define PM_GETRE(o) (INT2PTR(REGEXP*,SvIVX(PL_regex_pad[(o)->op_pmoffset]))) -#define PM_SETRE(o,r) STMT_START { SV* sv = PL_regex_pad[(o)->op_pmoffset]; sv_setiv(sv, PTR2IV(r)); } STMT_END +#define PM_SETRE(o,r) STMT_START { \ + SV* const sv = PL_regex_pad[(o)->op_pmoffset]; \ + sv_setiv(sv, PTR2IV(r)); \ + } STMT_END #define PM_GETRE_SAFE(o) (PL_regex_pad ? PM_GETRE(o) : (REGEXP*)0) #define PM_SETRE_SAFE(o,r) if (PL_regex_pad) PM_SETRE(o,r) #else @@ -281,48 +346,73 @@ struct pmop { #define PM_SETRE_SAFE PM_SETRE #endif -#define PMdf_USED 0x01 /* pm has been used once already */ -#define PMdf_TAINTED 0x02 /* pm compiled from tainted pattern */ -#define PMdf_UTF8 0x04 /* pm compiled from utf8 data */ -#define PMdf_DYN_UTF8 0x08 - -#define PMdf_CMP_UTF8 (PMdf_UTF8|PMdf_DYN_UTF8) #define PMf_RETAINT 0x0001 /* taint $1 etc. if target tainted */ -#define PMf_ONCE 0x0002 /* use pattern only once per reset */ +#define PMf_ONCE 0x0002 /* 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_UNUSED 0x0004 /* free for use */ #define PMf_MAYBE_CONST 0x0008 /* replacement contains variables */ -#define PMf_SKIPWHITE 0x0010 /* skip leading whitespace for split */ -#define PMf_WHITE 0x0020 /* pattern is \s+ */ + +#define PMf_USED 0x0010 /* PMf_ONCE has matched successfully. + Not used under threading. */ + #define PMf_CONST 0x0040 /* subst replacement is constant */ #define PMf_KEEP 0x0080 /* keep 1st runtime pattern forever */ #define PMf_GLOBAL 0x0100 /* pattern had a g modifier */ #define PMf_CONTINUE 0x0200 /* don't reset pos() if //g fails */ #define PMf_EVAL 0x0400 /* evaluating replacement as expr */ -#define PMf_LOCALE 0x0800 /* use locale for character types */ -#define PMf_MULTILINE 0x1000 /* assume multiple lines */ -#define PMf_SINGLELINE 0x2000 /* assume single line */ -#define PMf_FOLD 0x4000 /* case insensitivity */ -#define PMf_EXTENDED 0x8000 /* chuck embedded whitespace */ -/* mask of bits stored in regexp->reganch */ -#define PMf_COMPILETIME (PMf_MULTILINE|PMf_SINGLELINE|PMf_LOCALE|PMf_FOLD|PMf_EXTENDED) +/* The following flags have exact equivalents in regcomp.h with the prefix RXf_ + * which are stored in the regexp->extflags member. + */ +#define PMf_LOCALE 0x00800 /* use locale for character types */ +#define PMf_MULTILINE 0x01000 /* assume multiple lines */ +#define PMf_SINGLELINE 0x02000 /* assume single line */ +#define PMf_FOLD 0x04000 /* case insensitivity */ +#define PMf_EXTENDED 0x08000 /* chuck embedded whitespace */ +#define PMf_KEEPCOPY 0x10000 /* copy the string when matching */ + +/* mask of bits that need to be transfered to re->extflags */ +#define PMf_COMPILETIME (PMf_MULTILINE|PMf_SINGLELINE|PMf_LOCALE|PMf_FOLD|PMf_EXTENDED|PMf_KEEPCOPY) #ifdef USE_ITHREADS -# define PmopSTASHPV(o) ((o)->op_pmstashpv) -# define PmopSTASHPV_set(o,pv) (PmopSTASHPV(o) = savesharedpv(pv)) +# define PmopSTASHPV(o) \ + (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.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_pmstashpv = savesharedpv(pv)); \ + }) +# else +# define PmopSTASHPV_set(o,pv) \ + ((o)->op_pmstashstartu.op_pmstashpv = savesharedpv(pv)) +# endif # define PmopSTASH(o) (PmopSTASHPV(o) \ - ? gv_stashpv(PmopSTASHPV(o),GV_ADD) : Nullhv) -# define PmopSTASH_set(o,hv) PmopSTASHPV_set(o, ((hv) ? HvNAME(hv) : Nullch)) + ? gv_stashpv((o)->op_pmstashstartu.op_pmstashpv,GV_ADD) : NULL) +# define PmopSTASH_set(o,hv) PmopSTASHPV_set(o, ((hv) ? HvNAME_get(hv) : NULL)) # define PmopSTASH_free(o) PerlMemShared_free(PmopSTASHPV(o)) #else -# define PmopSTASH(o) ((o)->op_pmstash) -# define PmopSTASH_set(o,hv) ((o)->op_pmstash = (hv)) -# define PmopSTASHPV(o) (PmopSTASH(o) ? HvNAME(PmopSTASH(o)) : Nullch) - /* op_pmstash is not refcounted */ +# define PmopSTASH(o) \ + (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstash : NULL) +# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define PmopSTASH_set(o,hv) ({ \ + assert((o)->op_pmflags & PMf_ONCE); \ + ((o)->op_pmstashstartu.op_pmstash = (hv)); \ + }) +# 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 @@ -397,7 +487,8 @@ struct loop { #ifdef USE_ITHREADS # define cGVOPx_gv(o) ((GV*)PAD_SVl(cPADOPx(o)->op_padix)) -# define IS_PADGV(v) (v && SvTYPE(v) == SVt_PVGV && GvIN_PAD(v)) +# define IS_PADGV(v) (v && SvTYPE(v) == SVt_PVGV && isGV_with_GP(v) \ + && GvIN_PAD(v)) # define IS_PADCONST(v) (v && SvREADONLY(v)) # define cSVOPx_sv(v) (cSVOPx(v)->op_sv \ ? cSVOPx(v)->op_sv : PAD_SVl((v)->op_targ)) @@ -463,10 +554,24 @@ struct loop { #define OA_SCALARREF 7 #define OA_OPTIONAL 8 +/* Op_REFCNT is a reference count at the head of each op tree: needed + * since the tree is shared between threads, and between cloned closure + * copies in the same thread. OP_REFCNT_LOCK/UNLOCK is used when modifying + * this count. + * The same mutex is used to protect the refcounts of the reg_trie_data + * and reg_ac_data structures, which are shared between duplicated + * regexes. + */ + #ifdef USE_ITHREADS # define OP_REFCNT_INIT MUTEX_INIT(&PL_op_mutex) -# define OP_REFCNT_LOCK MUTEX_LOCK(&PL_op_mutex) -# define OP_REFCNT_UNLOCK MUTEX_UNLOCK(&PL_op_mutex) +# ifdef PERL_CORE +# define OP_REFCNT_LOCK MUTEX_LOCK(&PL_op_mutex) +# define OP_REFCNT_UNLOCK MUTEX_UNLOCK(&PL_op_mutex) +# else +# define OP_REFCNT_LOCK op_refcnt_lock() +# define OP_REFCNT_UNLOCK op_refcnt_unlock() +# endif # define OP_REFCNT_TERM MUTEX_DESTROY(&PL_op_mutex) #else # define OP_REFCNT_INIT NOOP @@ -476,27 +581,151 @@ struct loop { #endif #define OpREFCNT_set(o,n) ((o)->op_targ = (n)) -#define OpREFCNT_inc(o) ((o) ? (++(o)->op_targ, (o)) : Nullop) -#define OpREFCNT_dec(o) (--(o)->op_targ) +#ifdef PERL_DEBUG_READONLY_OPS +# define OpREFCNT_inc(o) Perl_op_refcnt_inc(aTHX_ o) +# define OpREFCNT_dec(o) Perl_op_refcnt_dec(aTHX_ o) +#else +# define OpREFCNT_inc(o) ((o) ? (++(o)->op_targ, (o)) : NULL) +# define OpREFCNT_dec(o) (--(o)->op_targ) +#endif /* flags used by Perl_load_module() */ #define PERL_LOADMOD_DENY 0x1 #define PERL_LOADMOD_NOIMPORT 0x2 #define PERL_LOADMOD_IMPORT_OPS 0x4 +#if defined(PERL_IN_PERLY_C) || defined(PERL_IN_OP_C) +#define ref(o, type) doref(o, type, TRUE) +#endif + +/* no longer used anywhere in core */ +#ifndef PERL_CORE +#define cv_ckproto(cv, gv, p) \ + cv_ckproto_len((cv), (gv), (p), (p) ? strlen(p) : 0) +#endif + #ifdef USE_REENTRANT_API #include "reentr.h" #endif #if defined(PL_OP_SLAB_ALLOC) #define NewOp(m,var,c,type) \ - (var = (type *) Perl_Slab_Alloc(aTHX_ m,c*sizeof(type))) + (var = (type *) Perl_Slab_Alloc(aTHX_ c*sizeof(type))) #define NewOpSz(m,var,size) \ - (var = (OP *) Perl_Slab_Alloc(aTHX_ m,size)) + (var = (OP *) Perl_Slab_Alloc(aTHX_ size)) #define FreeOp(p) Perl_Slab_Free(aTHX_ p) #else -#define NewOp(m, var, c, type) Newz(m, var, c, type) +#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*)safemalloc(size), memzero(var, size)) -#define FreeOp(p) Safefree(p) + (var = (OP*)PerlMemShared_calloc(1, size)) +#define FreeOp(p) PerlMemShared_free(p) +#endif + +#ifdef PERL_MAD +# define MAD_NULL 1 +# define MAD_PV 2 +# define MAD_OP 3 +# define MAD_SV 4 + +struct madprop { + MADPROP* mad_next; + const void *mad_val; + U32 mad_vlen; +/* short mad_count; */ + char mad_key; + char mad_type; +}; + +struct token { + I32 tk_type; + YYSTYPE tk_lval; + MADPROP* tk_mad; +}; #endif + +/* + * Values that can be held by mad_key : + * ^ unfilled head spot + * , literal , + * ; literal ; (blank if implicit ; at end of block) + * : literal : from ?: or attr list + * + unary + + * ? literal ? from ?: + * ( literal ( + * ) literal ) + * [ literal [ + * ] literal ] + * { literal { + * } literal } + * @ literal @ sigil + * $ literal $ sigil + * * literal * sigil + * ! use is source filtered + * & & or sub + * # whitespace/comment following ; or } + * # $# sigil + * 1 1st ; from for(;;) + * 1 retired protasis + * 2 2nd ; from for(;;) + * 2 retired apodosis + * 3 C-style for list + * a sub or var attributes + * a non-method arrow operator + * A method arrow operator + * A use import args + * b format block + * B retired stub block + * C constant conditional op + * d declarator + * D do block + * e unreached "else" (see C) + * e expression producing E + * E tr/E/R/, /E/ + * f folded constant op + * F peg op for format + * g op was forced to be a word + * i if/unless modifier + * I if/elsif/unless statement + * k local declarator + * K retired kid op + * l last index of array ($#foo) + * L label + * m modifier on regex + * n sub or format name + * o current operator/declarator name + * o else/continue + * O generic optimized op + * p peg to hold extra whitespace at statement level + * P peg op for package declaration + * q opening quote + * = quoted material + * Q closing quote + * Q optimized qw// + * r expression producing R + * R tr/E/R/ s/E/R/ + * s sub signature + * S use import stub (no import) + * S retired sort block + * t unreached "then" (see C) + * U use import op + * v private sv of for loop + * V use version + * w while/until modifier + * W while/for statement + * x optimized qw + * X random thing + * _ whitespace/comments preceding anything else + * ~ =~ operator + */ + +/* + * Local variables: + * c-indentation-style: bsd + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * + * ex: set ts=8 sts=4 sw=4 noet: + */