X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/9e209402444aedd210f045f2557e631ca974dda2..6985230a6e9dafc0b356186a2513961407efe2da:/regen/op_private diff --git a/regen/op_private b/regen/op_private index 090df37..4781442 100644 --- a/regen/op_private +++ b/regen/op_private @@ -35,6 +35,7 @@ bit bit field. Here's a general example: addbits('aelem', 7 => qw(OPpLVAL_INTRO LVINTRO), + 6 => qw(OPpLVAL_DEFER LVDEFER), '4..5' => { mask_def => 'OPpDEREF', enum => [ qw( @@ -43,10 +44,9 @@ bit bit field. Here's a general example: 3 OPpDEREF_SV DREFSV )], }, - 6 => qw(OPpLVAL_DEFER LVDEFER), ); -Here for the op C, bits 4 and 7 (bits are numbered 0..7) are +Here for the op C, bits 6 and 7 (bits are numbered 0..7) are defined as single-bit flags. The first string following the bit number is the define name that gets emitted in F, and the second string is the label, which will be displayed by F and Perl_do_op_dump() @@ -198,12 +198,16 @@ use strict; # find which ops use 0,1,2,3 or 4 bits of op_private for arg count info - $args0{$_} = 1 for qw(entersub); # UNOPs that usurp bit 0 + $args0{$_} = 1 for qw(entersub avhvswitch); # UNOPs that usurp bit 0 $args1{$_} = 1 for ( qw(reverse), # ck_fun(), but most bits stolen + qw(mapstart grepstart), # set in ck_fun, but + # cleared in ck_grep, + # unless there is an error grep !$maxarg{$_} && !$args0{$_}, ops_with_flag('1'), # UNOP + ops_with_flag('+'), # UNOP_AUX ops_with_flag('%'), # BASEOP/UNOP ops_with_flag('|'), # LOGOP ops_with_flag('-'), # FILESTATOP @@ -287,10 +291,6 @@ use strict; for (qw(nextstate dbstate)) { addbits($_, 5 => qw(OPpHUSH_VMSISH HUSH), - # should match HINT_M_VMSISH_STATUS, HINT_M_VMSISH_TIME - 6 => qw(OPpHINT_M_VMSISH_STATUS VMSISH_STATUS), - 7 => qw(OPpHINT_M_VMSISH_TIME VMSISH_TIME), - ); } @@ -302,7 +302,7 @@ for (qw(nextstate dbstate)) { addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO)) for qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice hslice delete padsv padav padhv enteriter entersub padrange - pushmark cond_expr refassign lvref lvrefslice lvavref), + pushmark cond_expr refassign lvref lvrefslice lvavref multideref), 'list', # this gets set in my_attrs() for some reason ; @@ -322,10 +322,15 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO)) # Safe to set if the ppcode uses: # tryAMAGICbin, tryAMAGICun, SETn, SETi, SETu, PUSHn, PUSHTARG, SETTARG, # SETs(TARG), XPUSHn, XPUSHu, +# but make sure set-magic is invoked separately for SETs(TARG) (or change +# it to SETTARG). # # Unsafe to set if the ppcode uses dTARG or [X]RETPUSH[YES|NO|UNDEF] # -# lt and friends do SETs (including ncmp, but not scmp) +# Only the code paths that handle scalar rvalue context matter. If dTARG +# or RETPUSHNO occurs only in list or lvalue paths, T is safe. +# +# lt and friends do SETs (including ncmp, but not scmp or i_ncmp) # # Additional mode of failure: the opcode can modify TARG before it "used" # all the arguments (or may call an external function which does the same). @@ -333,10 +338,10 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO)) # # pp.c pos substr each not OK (RETPUSHUNDEF) # ref not OK (RETPUSHNO) -# trans not OK (dTARG; TARG = sv_newmortal();) +# trans not OK (target is used for lhs, not retval) # ucfirst etc not OK: TMP arg processed inplace # quotemeta not OK (unsafe when TARG == arg) -# pack split - unknown whether they are safe +# pack - unknown whether it is safe # sprintf: is calling do_sprintf(TARG,...) which can act on TARG # before other args are processed. # @@ -353,8 +358,8 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO)) # grepwhile not OK (not always setting) # join not OK (unsafe when TARG == arg) # -# Suspicious wrt "additional mode of failure": concat (dealt with -# in ck_sassign()), join (same). +# concat - pp_concat special-cases TARG==arg to avoid +# "additional mode of failure" # # pp_ctl.c # mapwhile flip caller not OK (not always setting) @@ -374,9 +379,6 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO)) addbits($_, 4 => qw(OPpTARGET_MY TARGMY)) for ops_with_flag('T'), - # This flag is also used to indicate matches against implicit $_, - # where $_ is lexical; e.g. my $_; ....; /foo/ - qw(match subst trans transr); ; @@ -416,7 +418,7 @@ for (qw(rv2gv rv2sv padsv aelem helem entersub)) { # Defer creation of array/hash elem -addbits($_, 6 => qw(OPpLVAL_DEFER LVDEFER)) for qw(aelem helem); +addbits($_, 6 => qw(OPpLVAL_DEFER LVDEFER)) for qw(aelem helem multideref); @@ -435,7 +437,8 @@ addbits($_, 6 => qw(OPpOUR_INTRO OURINTR)) # Variable was in an our() # We might be an lvalue to return addbits($_, 3 => qw(OPpMAYBE_LVSUB LVSUB)) for qw(aassign rv2av rv2gv rv2hv padav padhv aelem helem aslice hslice - av2arylen keys rkeys kvaslice kvhslice substr pos vec); + av2arylen keys akeys avhvswitch kvaslice kvhslice substr pos vec + multideref); @@ -448,7 +451,8 @@ for (qw(rv2hv padhv)) { -addbits($_, 1 => qw(OPpHINT_STRICT_REFS STRICT)) for qw(rv2sv rv2av rv2hv rv2gv); +addbits($_, 1 => qw(OPpHINT_STRICT_REFS STRICT)) + for qw(rv2sv rv2av rv2hv rv2gv multideref); @@ -471,14 +475,32 @@ addbits($_, 7 => qw(OPpPV_IS_UTF8 UTF)) for qw(last redo next goto dump); +# note that for refassign, this bit can mean either OPpPAD_STATE or +# OPpOUR_INTRO depending on the type of the LH child, .e.g. +# \our $foo = ... +# \state $foo = ... + addbits($_, 6 => qw(OPpPAD_STATE STATE)) for qw(padav padhv padsv lvavref lvref refassign pushmark); +# NB: both sassign and aassign use the 'OPpASSIGN' naming convention +# for their private flags +# there *may* be common scalar items on both sides of a list assign: +# run-time checking will be needed. +addbits('aassign', 6 => qw(OPpASSIGN_COMMON_SCALAR COM_SCALAR)); +# +# as above, but it's possible to check for non-commonality with just +# a SvREFCNT(lhs) == 1 test for each lhs element +addbits('aassign', 5 => qw(OPpASSIGN_COMMON_RC1 COM_RC1)); + +# run-time checking is required for an aggregate on the LHS +addbits('aassign', 4 => qw(OPpASSIGN_COMMON_AGG COM_AGG)); -addbits('aassign', 6 => qw(OPpASSIGN_COMMON COMMON)); +# NB: both sassign and aassign use the 'OPpASSIGN' naming convention +# for their private flags addbits('sassign', 6 => qw(OPpASSIGN_BACKWARDS BKWARD), # Left & right switched @@ -598,12 +620,13 @@ addbits('rv2gv', ); +# NB OPpITER_REVERSED must always be bit 1: see pp_iter() addbits('enteriter', - 2 => qw(OPpITER_REVERSED REVERSED),# for (reverse ...) - 3 => qw(OPpITER_DEF DEF), # 'for $_' or 'for my $_' + 1 => qw(OPpITER_REVERSED REVERSED),# for (reverse ...) + 3 => qw(OPpITER_DEF DEF), # 'for $_' ); -addbits('iter', 2 => qw(OPpITER_REVERSED REVERSED)); +addbits('iter', 1 => qw(OPpITER_REVERSED REVERSED)); @@ -685,11 +708,6 @@ for (grep { $_ !~ /^l?stat$/ } ops_with_flag('-')) { -addbits($_, 1 => qw(OPpGREP_LEX GREPLEX)) # iterate over lexical $_ - for qw(mapwhile mapstart grepwhile grepstart); - - - addbits('entereval', 1 => qw(OPpEVAL_HAS_HH HAS_HH ), # Does it have a copy of %^H ? 2 => qw(OPpEVAL_UNICODE UNI ), @@ -729,9 +747,33 @@ addbits($_, 3 OPpLVREF_CV CV )], }, + #6 => qw(OPpPAD_STATE STATE), #7 => qw(OPpLVAL_INTRO LVINTRO), ) for 'refassign', 'lvref'; + + +addbits('multideref', + 4 => qw(OPpMULTIDEREF_EXISTS EXISTS), # deref is actually exists + 5 => qw(OPpMULTIDEREF_DELETE DELETE), # deref is actually delete +); + + + +addbits('avhvswitch', '0..1' => { }); + +addbits('argelem', + '1..2' => { + mask_def => 'OPpARGELEM_MASK', + enum => [ qw( + 0 OPpARGELEM_SV SV + 1 OPpARGELEM_AV AV + 2 OPpARGELEM_HV HV + )], + }, +); + + 1; # ex: set ts=8 sts=4 sw=4 et: