This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[MERGE] t/TEST -deparse fixups
[perl5.git] / regen / op_private
index c1877e9..eb53edf 100644 (file)
@@ -35,7 +35,8 @@ bit bit field. Here's a general example:
 
     addbits('aelem',
             7 => qw(OPpLVAL_INTRO LVINTRO),
-       '5..6' =>  {
+            6 => qw(OPpLVAL_DEFER LVDEFER),
+       '4..5' =>  {
                        mask_def  => 'OPpDEREF',
                        enum => [ qw(
                                    1   OPpDEREF_AV   DREFAV
@@ -43,10 +44,9 @@ bit bit field. Here's a general example:
                                    3   OPpDEREF_SV   DREFSV
                                )],
                    },
-            4 => qw(OPpLVAL_DEFER LVDEFER),
     );
 
-Here for the op C<aelem>, bits 4 and 7 (bits are numbered 0..7) are
+Here for the op C<aelem>, 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<opcode.h>, and the second string is
 the label, which will be displayed by F<Concise.pm> and Perl_do_op_dump()
@@ -198,12 +198,17 @@ 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
+                       rv2hv);                  # 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
@@ -215,9 +220,6 @@ use strict;
                         qw(vec),
                         grep !$maxarg{$_} && !$args0{$_} && !$args1{$_},
                             ops_with_flag('2'), # BINOP
-                            # this is a binop, but special-cased as a
-                            # baseop in regen/opcodes
-                            'sassign',
                     );
 
     $args3{$_} = 1 for grep !$maxarg{$_} && !$args0{$_}
@@ -287,10 +289,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),
-
     );
 }
 
@@ -300,9 +298,10 @@ for (qw(nextstate dbstate)) {
 #   my $x
 
 addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO))
-    for qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice
+    for qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice split
            hslice delete padsv padav padhv enteriter entersub padrange
-           pushmark cond_expr refassign lvref lvrefslice lvavref),
+           pushmark cond_expr refassign lvref lvrefslice lvavref multideref
+           multiconcat),
            'list', # this gets set in my_attrs() for some reason
            ;
 
@@ -322,10 +321,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 +337,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 +357,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 +378,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);
 ;
 
 
@@ -394,15 +395,9 @@ addbits($_, 7 => qw(OPpLVALUE LV)) for qw(leave leaveloop);
 
 
 
-# Pattern coming in on the stack
-addbits($_, 6 => qw(OPpRUNTIME RTIME))
-    for qw(match subst substcont qr pushre);
-
-
-
 # autovivify: Want ref to something
 for (qw(rv2gv rv2sv padsv aelem helem entersub)) {
-    addbits($_, '5..6' => {
+    addbits($_, '4..5' => {
                 mask_def  => 'OPpDEREF',
                 enum => [ qw(
                             1   OPpDEREF_AV   DREFAV
@@ -416,7 +411,7 @@ for (qw(rv2gv rv2sv padsv aelem helem entersub)) {
 
 
 # Defer creation of array/hash elem
-addbits($_, 4 => qw(OPpLVAL_DEFER LVDEFER)) for qw(aelem helem);
+addbits($_, 6 => qw(OPpLVAL_DEFER LVDEFER)) for qw(aelem helem multideref);
 
 
 
@@ -427,28 +422,38 @@ addbits($_, 2 => qw(OPpSLICEWARNING SLICEWARN)) # warn about @hash{$scalar}
 
 # XXX Concise seemed to think that OPpOUR_INTRO is used in rv2gv too,
 # but I can't see it - DAPM
-addbits($_, 4 => qw(OPpOUR_INTRO OURINTR)) # Variable was in an our()
+addbits($_, 6 => qw(OPpOUR_INTRO OURINTR)) # Variable was in an our()
     for qw(gvsv rv2sv rv2av rv2hv enteriter split);
 
 
 
 # We might be an lvalue to return
+# 'values' doesn't actually use this bit, but we reserve it here as
+# pp_values may call Perl_do_kv() which is shared among several ops which
+# do.
+
 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 values);
 
 
 
-for (qw(rv2hv padhv)) {
+for (qw(rv2hv padhv ref)) {
     addbits($_,                           # e.g. %hash in (%hash || $foo) ...
-        5 => qw(OPpTRUEBOOL       BOOL),  # ... in void cxt
-        6 => qw(OPpMAYBE_TRUEBOOL BOOL?), # ... cx not known till run time
+        4 => qw(OPpMAYBE_TRUEBOOL BOOL?), # but cx not known till run time
+        5 => qw(OPpTRUEBOOL       BOOL),
+    );
+}
+for (qw(grepwhile index length padav pos rindex rv2av subst)) {
+    addbits($_,
+        5 => qw(OPpTRUEBOOL       BOOL),  # if (@a) {...}
     );
 }
 
 
-
-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 +476,33 @@ addbits($_, 7 => qw(OPpPV_IS_UTF8 UTF)) for qw(last redo next goto dump);
 
 
 
-addbits($_, 4 => qw(OPpPAD_STATE STATE))  for qw(padav padhv padsv lvavref
+# 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));
+addbits('aassign', 2 => qw(OPpASSIGN_TRUEBOOL BOOL));  # if (@a = (...)) {...}
 
 
+# NB: both sassign and aassign use the 'OPpASSIGN' naming convention
+# for their private flags
 
 addbits('sassign',
     6 => qw(OPpASSIGN_BACKWARDS BKWARD), # Left & right switched
@@ -526,9 +550,9 @@ addbits('repeat', 6 => qw(OPpREPEAT_DOLIST DOLIST)); # List replication
 #     1  HINT_STRICT_REFS    check   HINT_STRICT_REFS       check
 #     2  OPpENTERSUB_HASTARG checki  OPpENTERSUB_HASTARG
 #     3  OPpENTERSUB_AMPER   check   OPpENTERSUB_AMPER      parser
-#     4  OPpENTERSUB_DB      check   OPpENTERSUB_DB
-#     5  OPpDEREF_AV         context
-#     6  OPpDEREF_HV         context OPpMAY_RETURN_CONSTANT parser/context
+#     4  OPpDEREF_AV         context
+#     5  OPpDEREF_HV         context OPpMAY_RETURN_CONSTANT parser/context
+#     6  OPpENTERSUB_DB      check   OPpENTERSUB_DB
 #     7  OPpLVAL_INTRO       context OPpENTERSUB_NOPAREN    parser
 
 # NB: OPpHINT_STRICT_REFS must equal HINT_STRICT_REFS
@@ -538,8 +562,8 @@ addbits('entersub',
     1      => qw(OPpHINT_STRICT_REFS  STRICT), # 'use strict' in scope
     2      => qw(OPpENTERSUB_HASTARG  TARG  ), # Called from OP tree
     3      => qw(OPpENTERSUB_AMPER    AMPER),  # Used & form to call
-    4      => qw(OPpENTERSUB_DB       DBG   ), # Debug subroutine
-    # 5..6 => OPpDEREF,      already defined above
+    # 4..5 => OPpDEREF,      already defined above
+    6      => qw(OPpENTERSUB_DB       DBG   ), # Debug subroutine
     # 7    => OPpLVAL_INTRO, already defined above
 );
 
@@ -550,9 +574,9 @@ addbits('rv2cv',
     1 => qw(OPpHINT_STRICT_REFS    STRICT), # 'use strict' in scope
     2 => qw(OPpENTERSUB_HASTARG    TARG  ), # If const sub, return the const
     3 => qw(OPpENTERSUB_AMPER      AMPER ), # Used & form to call
-    4 => qw(OPpENTERSUB_DB         DBG   ), # Debug subroutine
 
-    6 => qw(OPpMAY_RETURN_CONSTANT CONST ),
+    5 => qw(OPpMAY_RETURN_CONSTANT CONST ),
+    6 => qw(OPpENTERSUB_DB         DBG   ), # Debug subroutine
     7 => qw(OPpENTERSUB_NOPAREN    NO()  ), # bare sub call (without parens)
 );
 
@@ -571,7 +595,7 @@ addbits('substr', 4 => qw(OPpSUBSTR_REPL_FIRST REPL1ST));
 addbits('padrange',
     # bits 0..6 hold target range
     '0..6' =>  {
-            label         => '-',
+            label         => 'range',
             mask_def      => 'OPpPADRANGE_COUNTMASK',
             bitcount_def  => 'OPpPADRANGE_COUNTSHIFT',
           }
@@ -583,7 +607,7 @@ addbits('padrange',
 for (qw(aelemfast aelemfast_lex)) {
     addbits($_,
         '0..7' =>  {
-                label     => '-',
+                label     => 'key',
               }
     );
 }
@@ -594,16 +618,17 @@ addbits('rv2gv',
     2 => qw(OPpDONT_INIT_GV NOINIT), # Call gv_fetchpv with GV_NOINIT
                             # (Therefore will return whatever is currently in
                             # the symbol table, not guaranteed to be a PVGV)
-    4 => qw(OPpALLOW_FAKE   FAKE),   # OK to return fake glob
+    6 => qw(OPpALLOW_FAKE   FAKE),   # OK to return fake glob
 );
 
 
+# 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));
 
 
 
@@ -627,9 +652,11 @@ addbits('list', 6 => qw(OPpLIST_GUESSED GUESSED));
 
 
 
-# Operating on a list of keys
-addbits('delete', 6 => qw(OPpSLICE SLICE));
-# also 7 => OPpLVAL_INTRO, already defined above
+addbits('delete',
+    5 => qw(OPpKVSLICE KVSLICE), # Operating on a list of key/value pairs
+    6 => qw(OPpSLICE   SLICE  ), # Operating on a list of keys
+   #7 => OPpLVAL_INTRO, already defined above
+);
 
 
 
@@ -644,8 +671,8 @@ addbits('sort',
     2 => qw(OPpSORT_REVERSE  REV    ), # Reversed sort
     3 => qw(OPpSORT_INPLACE  INPLACE), # sort in-place; eg @a = sort @a
     4 => qw(OPpSORT_DESCEND  DESC   ), # Descending sort
-    5 => qw(OPpSORT_QSORT    QSORT  ), # Use quicksort (not mergesort)
     6 => qw(OPpSORT_STABLE   STABLE ), # Use a stable algorithm
+    7 => qw(OPpSORT_UNSTABLE UNSTABLE),# Use an unstable algorithm
 );
 
 
@@ -685,11 +712,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    ),
@@ -713,14 +735,19 @@ addbits('coreargs',
 
 
 
-addbits('split', 7 => qw(OPpSPLIT_IMPLIM IMPLIM)); # implicit limit
-
+addbits('split',
+    # @a = split() has been replaced with  split() where split itself
+    # does the array assign
+    4 => qw(OPpSPLIT_ASSIGN ASSIGN), 
+    3 => qw(OPpSPLIT_LEX LEX),  # the OPpSPLIT_ASSIGN is a lexical array
+    2 => qw(OPpSPLIT_IMPLIM IMPLIM), # implicit limit
+);
 
 
 addbits($_,
     2 => qw(OPpLVREF_ELEM ELEM   ),
     3 => qw(OPpLVREF_ITER ITER   ),
-'5..6'=> {
+'4..5'=> {
            mask_def => 'OPpLVREF_TYPE',
            enum     => [ qw(
                              0   OPpLVREF_SV   SV
@@ -729,9 +756,78 @@ 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' => {
+                   mask_def  => 'OPpAVHVSWITCH_MASK',
+                   label     => 'offset',
+    }
+);
+
+
+addbits('argelem',
+   '1..2' =>  {
+                   mask_def  => 'OPpARGELEM_MASK',
+                   enum => [ qw(
+                               0   OPpARGELEM_SV   SV
+                               1   OPpARGELEM_AV   AV
+                               2   OPpARGELEM_HV   HV
+                           )],
+               },
+);
+
+
+# rv2hv and padhv in void/scalar context implementing 'keys %h'
+# directly, without a following OP_KEYS
+
+addbits('padhv',
+    0 => qw(OPpPADHV_ISKEYS KEYS),
+);
+addbits('rv2hv',
+    0 => qw(OPpRV2HV_ISKEYS KEYS),
+);
+
+# In conjunction with OPpTRUEBOOL, indicates that the test should be
+# inverted. This allows both (index() == -1) and (index() != -1)
+# to optimise away the const and eq/ne
+
+for (qw(index rindex)) {
+    addbits($_, 6 => qw(OPpINDEX_BOOLNEG NEG));
+}
+
+
+addbits('concat',
+    # OPf_STACKED normally indicates .=; but it also gets set to optimise
+    # $a . $b . $c into ($a . $b) .= $c
+    # so that the first concat's PADTMP (which holds the result of $a.$b)
+    # can be reused. Set a flag in this case to help deparse and warn
+    # distinguish the cases.
+    6 => qw(OPpCONCAT_NESTED NESTED),
+);
+
+
+addbits('multiconcat',
+  # 7       OPpLVAL_INTRO
+    6 => qw(OPpMULTICONCAT_APPEND APPEND), # $x .= ....
+    5 => qw(OPpMULTICONCAT_FAKE   FAKE),   # sprintf() optimised to MC.
+  # 4       OPpTARGET_MY
+    3 => qw(OPpMULTICONCAT_STRINGIFY STRINGIFY), # "$a$b...", (for Deparse.pm)
+);
+
+
+
 1;
 
 # ex: set ts=8 sts=4 sw=4 et: