summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2023-01-19 14:11:28 +0000
committerYves Orton <demerphq@gmail.com>2023-02-28 20:53:51 +0800
commitfecade69c526caa9c157a2405486b9089047fc72 (patch)
treed51961de6f06d4700c5bc8f6d6d96e855018999a /lib
parent214a9432e04871da2b88eba02ea3f1148a99f9c8 (diff)
downloadperl-fecade69c526caa9c157a2405486b9089047fc72.tar.gz
eval_sv(): call pp_entereval() via runops
Like the previous commit which did it for amagic_call() and call_sv(), this commit makes executing the faked-up OP_ENTEREVAL be executed as part of the runops loop rather than as a separate call. This is to allow shortly fixing up for a reference-counted stack. (CALLRUNOPS() will reify the stack if necessary, while the raw call to pp_entereval() won't fix up the stack unless its part of the runops loop too.) However, this is a bit more complex than call_sv() etc in that there is a good reason for calling pp_entereval() separately. The faked up OP_ENTEREVAL has its op_next set to NULL - this is the op which would normally be returned on failure of the eval compilation. By seeing whether the retuned value from pp_entereval() is NULL or not, eval_sv() can tell whether compilation failed. On the other hand, if pp_entereval() was made to be called as part of the runops loop, then the runops loop *always* finishes with PL_op set to NULL. So we can no lo longer distinguish between compile-failed and compile-succeeded-and-eval-ran-to-completion. This commit moves the entereval into the runops loop, but restores the ability to distinguish in a slightly hacky way. It adds a new private flag for OP_ENTEREVAL - OPpEVAL_EVALSV - which indicates to pp_entereval() that it was called from eval_sv(). And of course eval_sv() sets this flag on the OPpEVAL_EVALSV op it fakes up. If pp_entereval() fails to compile, then if that flag is set, it pushes a null pointer onto the argument stack before returning. Thus by checking whether *PL_stack_sp is NULL or not on return from CALLRUNOPS(), eval_sv() regains the ability to distinguish the two cases.
Diffstat (limited to 'lib')
-rw-r--r--lib/B/Op_private.pm5
1 files changed, 4 insertions, 1 deletions
diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm
index d04671ac68..c9d2f29c7a 100644
--- a/lib/B/Op_private.pm
+++ b/lib/B/Op_private.pm
@@ -307,7 +307,7 @@ $bits{dorassign}{0} = $bf[0];
$bits{dump}{0} = $bf[0];
$bits{each}{0} = $bf[0];
@{$bits{emptyavhv}}{5,3,2,1,0} = ('OPpEMPTYAVHV_IS_HV', $bf[4], $bf[4], $bf[4], $bf[4]);
-@{$bits{entereval}}{5,4,3,2,1,0} = ('OPpEVAL_RE_REPARSING', 'OPpEVAL_COPHH', 'OPpEVAL_BYTES', 'OPpEVAL_UNICODE', 'OPpEVAL_HAS_HH', $bf[0]);
+@{$bits{entereval}}{6,5,4,3,2,1,0} = ('OPpEVAL_EVALSV', 'OPpEVAL_RE_REPARSING', 'OPpEVAL_COPHH', 'OPpEVAL_BYTES', 'OPpEVAL_UNICODE', 'OPpEVAL_HAS_HH', $bf[0]);
$bits{entergiven}{0} = $bf[0];
$bits{enteriter}{3} = 'OPpITER_DEF';
@{$bits{entersub}}{5,4,0} = ($bf[8], $bf[8], 'OPpENTERSUB_INARGS');
@@ -637,6 +637,7 @@ our %defines = (
OPpENTERSUB_NOPAREN => 128,
OPpEVAL_BYTES => 8,
OPpEVAL_COPHH => 16,
+ OPpEVAL_EVALSV => 64,
OPpEVAL_HAS_HH => 2,
OPpEVAL_RE_REPARSING => 32,
OPpEVAL_UNICODE => 4,
@@ -751,6 +752,7 @@ our %labels = (
OPpENTERSUB_NOPAREN => 'NO()',
OPpEVAL_BYTES => 'BYTES',
OPpEVAL_COPHH => 'COPHH',
+ OPpEVAL_EVALSV => 'EVALSV',
OPpEVAL_HAS_HH => 'HAS_HH',
OPpEVAL_RE_REPARSING => 'REPARSE',
OPpEVAL_UNICODE => 'UNI',
@@ -900,6 +902,7 @@ $ops_using{OPpDONT_INIT_GV} = $ops_using{OPpALLOW_FAKE};
$ops_using{OPpENTERSUB_DB} = $ops_using{OPpENTERSUB_AMPER};
$ops_using{OPpENTERSUB_HASTARG} = $ops_using{OPpENTERSUB_AMPER};
$ops_using{OPpEVAL_COPHH} = $ops_using{OPpEVAL_BYTES};
+$ops_using{OPpEVAL_EVALSV} = $ops_using{OPpEVAL_BYTES};
$ops_using{OPpEVAL_HAS_HH} = $ops_using{OPpEVAL_BYTES};
$ops_using{OPpEVAL_RE_REPARSING} = $ops_using{OPpEVAL_BYTES};
$ops_using{OPpEVAL_UNICODE} = $ops_using{OPpEVAL_BYTES};