X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/cb0d96b9c873979acbc861b2863a39dda41d3ace..580561a3a5dd3bfef87627781ac362004e3d87b5:/op.h diff --git a/op.h b/op.h index 1505932..25b59ea 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, 2004, 2005, 2006 by Larry Wall and others + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -19,20 +19,17 @@ * op_type The type of the operation. * op_opt Whether or not the op has been optimised by the * peephole optimiser. - * op_static Whether or not the op is statically defined. - * This flag is used by the B::C compiler backend - * and indicates that the op should not be freed. * * 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 two spare bits! + * 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 @@ -40,11 +37,7 @@ * which may or may not check number of children). */ -#ifdef DEBUGGING_OPS -#define OPCODE opcode -#else #define OPCODE U16 -#endif #ifdef PERL_MAD # define MADPROP_IN_BASEOP MADPROP* op_madprop; @@ -52,6 +45,8 @@ # define MADPROP_IN_BASEOP #endif +typedef PERL_BITFIELD16 Optype; + #ifdef BASEOP_DEFINITION #define BASEOP BASEOP_DEFINITION #else @@ -61,23 +56,29 @@ OP* (CPERLscope(*op_ppaddr))(pTHX); \ MADPROP_IN_BASEOP \ PADOFFSET op_targ; \ - unsigned op_type:9; \ - unsigned op_opt:1; \ - unsigned op_static:1; \ - unsigned op_latefree:1; \ - unsigned op_latefreed:1; \ - unsigned op_attached:1; \ - unsigned op_spare:2; \ + 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; \ U8 op_flags; \ U8 op_private; #endif +/* If op_type:9 is changed to :10, also change PUSHEVAL in cop.h. + 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 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) +#define OP_GIMME_REVERSE(flags) ((flags) & G_WANT) + /* =head1 "Gimme" Values @@ -122,7 +123,7 @@ 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[ACGHS]V, don't create GV--in @@ -136,6 +137,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_ENTER, store caller context */ + /* 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) */ /* old names; don't use in new code, but don't break them, either */ #define OPf_LIST OPf_WANT_LIST @@ -164,9 +169,6 @@ Deprecated. Use C instead. #define OPpASSIGN_BACKWARDS 64 /* Left & right switched. */ #define OPpASSIGN_CV_TO_GV 128 /* Possible optimisation for constants. */ -/* Private for OP_[AS]ASSIGN */ -#define OPpASSIGN_STATE 32 /* Assign to a "state" variable */ - /* Private for OP_MATCH and OP_SUBST{,CONST} */ #define OPpRUNTIME 64 /* Pattern coming in on the stack */ @@ -193,7 +195,7 @@ Deprecated. Use C instead. #define OPpENTERSUB_DB 16 /* Debug subroutine. */ #define OPpENTERSUB_HASTARG 32 /* Called from OP tree. */ #define OPpENTERSUB_NOMOD 64 /* Immune to mod() for :attrlist. */ - /* OP_RV2CV only */ + /* OP_ENTERSUB and OP_RV2CV only */ #define OPpENTERSUB_AMPER 8 /* Used & form to call. */ #define OPpENTERSUB_NOPAREN 128 /* bare sub call (without parens) */ #define OPpENTERSUB_INARGS 4 /* Lval used as arg to a sub. */ @@ -242,6 +244,7 @@ Deprecated. Use C instead. /* Private for OP_DELETE */ #define OPpSLICE 64 /* Operating on a list of keys */ +/* Also OPpLVAL_INTRO (128) */ /* Private for OP_EXISTS */ #define OPpEXISTS_SUB 64 /* Checking for &sub, not {} or []. */ @@ -255,8 +258,8 @@ Deprecated. Use C instead. #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 */ +/* Private for OP_REVERSE */ +#define OPpREVERSE_INPLACE 8 /* reverse in-place (@a = reverse @a) */ /* Private for OP_OPEN and OP_BACKTICK */ #define OPpOPEN_IN_RAW 16 /* binmode(F,":raw") on input fh */ @@ -271,13 +274,6 @@ Deprecated. Use C instead. /* 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 || \ - ((op)->op_type) == OP_FTREXEC || \ - ((op)->op_type) == OP_FTEREAD || \ - ((op)->op_type) == OP_FTEWRITE || \ - ((op)->op_type) == OP_FTEEXEC) /* Private for OP_(MAP|GREP)(WHILE|START) */ #define OPpGREP_LEX 2 /* iterate over lexical $_ */ @@ -316,86 +312,119 @@ struct pmop { BASEOP OP * op_first; OP * op_last; - OP * op_pmreplroot; /* (type is really union {OP*,GV*,PADOFFSET}) */ - 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 + PADOFFSET op_pmtargetoff; /* For OP_PUSHRE */ +#else + GV * op_pmtargetgv; +#endif + } op_pmreplrootu; + union { + OP * op_pmreplstart; /* Only used in OP_SUBST */ #ifdef USE_ITHREADS - char * op_pmstashpv; + char * op_pmstashpv; /* Only used in OP_MATCH, with PMf_ONCE set */ #else - HV * op_pmstash; + 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* const sv = PL_regex_pad[(o)->op_pmoffset]; \ - sv_setiv(sv, PTR2IV(r)); \ +#define PM_GETRE(o) (SvTYPE(PL_regex_pad[(o)->op_pmoffset]) == SVt_REGEXP \ + ? (REGEXP*)(PL_regex_pad[(o)->op_pmoffset]) : NULL) +/* The assignment is just to enforce type safety (or at least get a warning). + */ +/* With first class regexps not via a reference one needs to assign + &PL_sv_undef under ithreads. (This would probably work unthreaded, but NULL + is cheaper. I guess we could allow NULL, but the check above would get + more complex, and we'd have an AV with (SV*)NULL in it, which feels bad */ +/* BEWARE - something that calls this macro passes (r) which has a side + effect. */ +#define PM_SETRE(o,r) STMT_START { \ + REGEXP *const _pm_setre = (r); \ + assert(_pm_setre); \ + PL_regex_pad[(o)->op_pmoffset] = MUTABLE_SV(_pm_setre); \ } 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 #define PM_GETRE(o) ((o)->op_pmregexp) #define PM_SETRE(o,r) ((o)->op_pmregexp = (r)) -#define PM_GETRE_SAFE PM_GETRE -#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_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_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_RETAINT 0x00000040 /* taint $1 etc. if target tainted */ +#define PMf_ONCE 0x00000080 /* 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 0x00000100 /* free for use */ +#define PMf_MAYBE_CONST 0x00000200 /* replacement contains variables */ + +#define PMf_USED 0x00000400 /* PMf_ONCE has matched successfully. + Not used under threading. */ + +#define PMf_CONST 0x00000800 /* subst replacement is constant */ +#define PMf_KEEP 0x00001000 /* keep 1st runtime pattern forever */ +#define PMf_GLOBAL 0x00002000 /* pattern had a g modifier */ +#define PMf_CONTINUE 0x00004000 /* don't reset pos() if //g fails */ +#define PMf_EVAL 0x00008000 /* evaluating replacement as expr */ /* The following flags have exact equivalents in regcomp.h with the prefix RXf_ - * which are stored in the regexp->extflags member. + * which are stored in the regexp->extflags member. If you change them here, + * you have to change them there, and vice versa. */ -#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 */ +#define PMf_MULTILINE 0x00000001 /* assume multiple lines */ +#define PMf_SINGLELINE 0x00000002 /* assume single line */ +#define PMf_FOLD 0x00000004 /* case insensitivity */ +#define PMf_EXTENDED 0x00000008 /* chuck embedded whitespace */ +#define PMf_KEEPCOPY 0x00000010 /* copy the string when matching */ +#define PMf_LOCALE 0x00000020 /* use locale for character types */ /* 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) : NULL) + ? 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 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_pmstash is not refcounted */ + /* 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 @@ -492,7 +521,9 @@ struct loop { #define cSVOPo_sv cSVOPx_sv(o) #define kSVOP_sv cSVOPx_sv(kid) -#define Nullop Null(OP*) +#ifndef PERL_CORE +# define Nullop ((OP*)NULL) +#endif /* Lowest byte-and-a-bit of PL_opargs */ #define OA_MARK 1 @@ -564,13 +595,18 @@ struct loop { #endif #define OpREFCNT_set(o,n) ((o)->op_targ = (n)) -#define OpREFCNT_inc(o) ((o) ? (++(o)->op_targ, (o)) : NULL) -#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 +#define PERL_LOADMOD_DENY 0x1 /* no Module */ +#define PERL_LOADMOD_NOIMPORT 0x2 /* use Module () */ +#define PERL_LOADMOD_IMPORT_OPS 0x4 /* use Module (...) */ #if defined(PERL_IN_PERLY_C) || defined(PERL_IN_OP_C) #define ref(o, type) doref(o, type, TRUE) @@ -582,15 +618,19 @@ struct loop { cv_ckproto_len((cv), (gv), (p), (p) ? strlen(p) : 0) #endif +#ifdef PERL_CORE +# define my(o) my_attrs((o), NULL) +#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) \ @@ -624,7 +664,7 @@ struct token { #endif /* - * Values that can be hold by mad_key : + * Values that can be held by mad_key : * ^ unfilled head spot * , literal , * ; literal ; (blank if implicit ; at end of block) @@ -663,13 +703,14 @@ struct token { * 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 - * M my assignment slurped into some other operator's target * n sub or format name * o current operator/declarator name * o else/continue @@ -682,7 +723,6 @@ struct token { * Q optimized qw// * r expression producing R * R tr/E/R/ s/E/R/ - * R assign slurped by split * s sub signature * S use import stub (no import) * S retired sort block @@ -697,3 +737,13 @@ struct token { * _ 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: + */