X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=op.h;h=65102ba9c718f4ee3d7477e75e08f7a1a44057d8;hb=e9d185f8391f09209c11be82e97358d853f1ba30;hp=f84f123efffee52f57ab43f1ded9dd11f4ea78d9;hpb=699a97de988b5b9b54375d79201e72f1c259685c;p=p5sagit%2Fp5-mst-13.2.git diff --git a/op.h b/op.h index f84f123..65102ba 100644 --- a/op.h +++ b/op.h @@ -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 @@ -63,11 +60,10 @@ 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; \ + unsigned op_spare:3; \ U8 op_flags; \ U8 op_private; #endif @@ -111,6 +107,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. */ @@ -122,7 +120,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 @@ -164,9 +162,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 */ @@ -203,14 +198,14 @@ 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 8 /* Call gv_fetchpv with GV_NOINIT */ +#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) */ @@ -316,22 +311,28 @@ 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 @@ -349,50 +350,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->extflags - these all are also called RXf_PMf_xyz + +/* The following flags have exact equivalents in regcomp.h with the prefix RXf_ + * which are stored in the regexp->extflags member. */ -#define PMf_COMPILETIME (PMf_MULTILINE|PMf_SINGLELINE|PMf_LOCALE|PMf_FOLD|PMf_EXTENDED) +#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) : 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 @@ -561,8 +585,13 @@ 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 @@ -575,7 +604,8 @@ struct loop { /* 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) +#define cv_ckproto(cv, gv, p) \ + cv_ckproto_len((cv), (gv), (p), (p) ? strlen(p) : 0) #endif #ifdef USE_REENTRANT_API @@ -584,9 +614,9 @@ struct loop { #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) \ @@ -659,13 +689,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 @@ -678,7 +709,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 @@ -693,3 +723,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: + */