This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
op_private: Update note about targlex and trans
[perl5.git] / regen / op_private
index d5da55e..9cb1206 100644 (file)
@@ -35,7 +35,7 @@ bit bit field. Here's a general example:
 
     addbits('aelem',
             7 => qw(OPpLVAL_INTRO LVINTRO),
-       '5..6' =>  {
+       '4..5' =>  {
                        mask_def  => 'OPpDEREF',
                        enum => [ qw(
                                    1   OPpDEREF_AV   DREFAV
@@ -43,7 +43,7 @@ bit bit field. Here's a general example:
                                    3   OPpDEREF_SV   DREFSV
                                )],
                    },
-            4 => qw(OPpLVAL_DEFER LVDEFER),
+            6 => qw(OPpLVAL_DEFER LVDEFER),
     );
 
 Here for the op C<aelem>, bits 4 and 7 (bits are numbered 0..7) are
@@ -204,10 +204,12 @@ use strict;
                         qw(reverse), # ck_fun(), but most bits stolen
                         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
                             ops_with_flag('}'), # LOOPEXOP
+                            ops_with_flag('.'), # METHOP
                     );
 
     $args2{$_} = 1 for (
@@ -238,6 +240,7 @@ use strict;
                             ops_with_check('ck_lfun'),
                             ops_with_check('ck_open'),
                             ops_with_check('ck_select'),
+                            ops_with_check('ck_stringify'),
                             ops_with_check('ck_tell'),
                             ops_with_check('ck_trunc'),
                             ;
@@ -285,19 +288,18 @@ 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),
-
     );
 }
 
 
+# op is in local context, or pad variable is being introduced, e.g.
+#   local $h{foo}
+#   my $x
 
 addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO))
-    for qw(pos substr vec gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice
+    for qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice
            hslice delete padsv padav padhv enteriter entersub padrange
-           pushmark cond_expr),
+           pushmark cond_expr refassign lvref lvrefslice lvavref multideref),
            'list', # this gets set in my_attrs() for some reason
            ;
 
@@ -312,6 +314,66 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO))
 # the pp function just updates the SV pointed to by op_targ, and doesn't
 # care whether that's a PADTMP or a lexical var.
 
+# Some comments about when its safe to use T/OPpTARGET_MY.
+#
+# 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]
+#
+# 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).
+# If the target coincides with one of the arguments ==> kaboom.
+#
+# pp.c pos substr each not OK (RETPUSHUNDEF)
+#      ref not OK (RETPUSHNO)
+#      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 - unknown whether it is safe
+#      sprintf: is calling do_sprintf(TARG,...) which can act on TARG
+#        before other args are processed.
+#
+#      Suspicious wrt "additional mode of failure" (and only it):
+#      schop, chop, postinc/dec, bit_and etc, negate, complement.
+#
+#      Also suspicious: 4-arg substr, sprintf, uc/lc (POK_only), reverse, pack.
+#
+#      substr/vec: doing TAINT_off()???
+#
+# pp_hot.c
+#      readline - unknown whether it is safe
+#      match subst not OK (dTARG)
+#      grepwhile not OK (not always setting)
+#      join not OK (unsafe when TARG == arg)
+#
+#      concat - pp_concat special-cases TARG==arg to avoid
+#              "additional mode of failure"
+#
+# pp_ctl.c
+#      mapwhile flip caller not OK (not always setting)
+#
+# pp_sys.c
+#      backtick glob warn die not OK (not always setting)
+#      warn not OK (RETPUSHYES)
+#      open fileno getc sysread syswrite ioctl accept shutdown
+#       ftsize(etc) readlink telldir fork alarm getlogin not OK (RETPUSHUNDEF)
+#      umask select not OK (XPUSHs(&PL_sv_undef);)
+#      fileno getc sysread syswrite tell not OK (meth("FILENO" "GETC"))
+#      sselect shm* sem* msg* syscall - unknown whether they are safe
+#      gmtime not OK (list context)
+#
+#      Suspicious wrt "additional mode of failure": warn, die, select.
+
+
 addbits($_, 4 => qw(OPpTARGET_MY TARGMY))
     for ops_with_flag('T'),
     # This flag is also used to indicate matches against implicit $_,
@@ -342,7 +404,7 @@ addbits($_, 6 => qw(OPpRUNTIME RTIME))
 
 # 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
@@ -356,7 +418,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);
 
 
 
@@ -367,28 +429,29 @@ 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()
-    for qw(gvsv rv2sv rv2av rv2hv enteriter);
+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
 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 rkeys kvaslice kvhslice substr pos vec multideref);
 
 
 
 for (qw(rv2hv padhv)) {
     addbits($_,                           # e.g. %hash in (%hash || $foo) ...
+        4 => qw(OPpMAYBE_TRUEBOOL BOOL?), # ... cx not known till run time
         5 => qw(OPpTRUEBOOL       BOOL),  # ... in void cxt
-        6 => qw(OPpMAYBE_TRUEBOOL BOOL?), # ... cx not known till run time
     );
 }
 
 
 
-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);
 
 
 
@@ -411,7 +474,8 @@ 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 pushmark);
+addbits($_, 6 => qw(OPpPAD_STATE STATE))  for qw(padav padhv padsv lvavref
+                                                 lvref refassign pushmark);
 
 
 
@@ -463,11 +527,11 @@ addbits('repeat', 6 => qw(OPpREPEAT_DOLIST DOLIST)); # List replication
 #   ---  -------------       -----   ----------             -----
 #     0  OPpENTERSUB_INARGS  context
 #     1  HINT_STRICT_REFS    check   HINT_STRICT_REFS       check
-#     2  OPpENTERSUB_HASTARG check
+#     2  OPpENTERSUB_HASTARG checki  OPpENTERSUB_HASTARG
 #     3  OPpENTERSUB_AMPER   check   OPpENTERSUB_AMPER      parser
-#     4  OPpENTERSUB_DB      check
-#     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
@@ -477,28 +541,22 @@ 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
 );
-addbits('rv2cv',
-    # If a constant sub, return the constant
-    1 => qw(OPpHINT_STRICT_REFS    STRICT),  # 'use strict' in scope
-
-    3 => qw(OPpENTERSUB_AMPER      AMPER),  # Used & form to call
-
-    6 => qw(OPpMAY_RETURN_CONSTANT CONST),
-    7 => qw(OPpENTERSUB_NOPAREN    NO() ),  # bare sub call (without parens)
-);
 
-# XXX perhaps ought the clear these flags in Perl_doref when converting
-# and entersub into an rv2cv???? Failing that, update the comments above
-# and add them as part of the main addbits('rv2cv'.
+# note that some of these flags are just left-over from when an entersub
+# is converted into an rv2cv, and could probably be cleared/re-assigned
 
 addbits('rv2cv',
-              # If a constant sub, return the constant
-    2 => qw(OPpENTERSUB_HASTARG TARG),
-    4 => qw(OPpENTERSUB_DB       DBG   ), # Debug subroutine
+    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
+
+    5 => qw(OPpMAY_RETURN_CONSTANT CONST ),
+    6 => qw(OPpENTERSUB_DB         DBG   ), # Debug subroutine
+    7 => qw(OPpENTERSUB_NOPAREN    NO()  ), # bare sub call (without parens)
 );
 
 
@@ -539,7 +597,7 @@ 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
 );
 
 
@@ -660,6 +718,30 @@ addbits('coreargs',
 
 addbits('split', 7 => qw(OPpSPLIT_IMPLIM IMPLIM)); # implicit limit
 
+
+
+addbits($_,
+    2 => qw(OPpLVREF_ELEM ELEM   ),
+    3 => qw(OPpLVREF_ITER ITER   ),
+'4..5'=> {
+           mask_def => 'OPpLVREF_TYPE',
+           enum     => [ qw(
+                             0   OPpLVREF_SV   SV
+                             1   OPpLVREF_AV   AV
+                             2   OPpLVREF_HV   HV
+                             3   OPpLVREF_CV   CV
+                         )],
+         },
+   #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
+);
+
 1;
 
 # ex: set ts=8 sts=4 sw=4 et: