summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-12-20 06:50:12 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-12-21 07:06:13 -0800
commit2e4af4cf6b38b2c5a571e1232ee507b8a01cda8a (patch)
treef835bc29cc655e453334b417704045c27a1874ed /ext
parentcee11a521f0966a42b8be1949f915e0c926c9f20 (diff)
downloadperl-2e4af4cf6b38b2c5a571e1232ee507b8a01cda8a.tar.gz
Propagate context properly in Safe->reval
(or, rather, in Opcode.xs). It was providing scalar context when invoked in void context. Test- ing Safe->reval itself is complicated, because Opcode.xs, which is an essential part of the fix, is not dual-life.
Diffstat (limited to 'ext')
-rw-r--r--ext/Opcode/Opcode.xs3
-rw-r--r--ext/Opcode/t/Opcode.t17
2 files changed, 19 insertions, 1 deletions
diff --git a/ext/Opcode/Opcode.xs b/ext/Opcode/Opcode.xs
index 594f5b2723..9d657f884c 100644
--- a/ext/Opcode/Opcode.xs
+++ b/ext/Opcode/Opcode.xs
@@ -315,7 +315,8 @@ PPCODE:
hv_clear(PL_stashcache);
PUSHMARK(SP);
- perl_call_sv(codesv, GIMME|G_EVAL|G_KEEPERR); /* use callers context */
+ /* use caller’s context */
+ perl_call_sv(codesv, GIMME_V|G_EVAL|G_KEEPERR);
sv_free( (SV *) dummy_hv); /* get rid of what save_hash gave us*/
SPAGAIN; /* for the PUTBACK added by xsubpp */
LEAVE;
diff --git a/ext/Opcode/t/Opcode.t b/ext/Opcode/t/Opcode.t
index 1c0b427f9d..82028cc5b2 100644
--- a/ext/Opcode/t/Opcode.t
+++ b/ext/Opcode/t/Opcode.t
@@ -113,6 +113,23 @@ is(($s2 ^ $s3), opset('padsv','padhv'));
my @o2 = opset_to_ops(invert_opset $s3);
is_deeply(\@o1, \@o2);
+# --- test context of undocumented _safe_call_sv (used by Safe.pm)
+
+my %inc = %INC;
+my $expect;
+sub f {
+ %INC = %inc;
+ no warnings 'uninitialized';
+ is wantarray, $expect,
+ sprintf "_safe_call_sv gives %s context",
+ qw[void scalar list][$expect + defined $expect]
+};
+Opcode::_safe_call_sv("main", empty_opset, \&f);
+$expect = !1;
+$_ = Opcode::_safe_call_sv("main", empty_opset, \&f);
+$expect = !0;
+() = Opcode::_safe_call_sv("main", empty_opset, \&f);
+
# --- finally, check some opname assertions
foreach my $opname (@full_l1) {