Closed mauke closed 1 month ago
The various builtin:: pp_ funcs assume TARG is available, and when called from a normal entersub OP, it is, since one was added to every* normal entersub in d30110745a to speed up any XS that uses dXSTARG
(originally dXS_TARGET
).
But goto OPs don't have a TARG, so we see the panic we get here.
We have a similar problem when calling with call_sv():
$ ./perl -Ilib -MXS::APItest=call_sv -e 'call_sv(\&builtin::refaddr, 0, [])'
panic: pad_sv po at -e line 1.
since call_sv() doesn't add a targ to the entersub OP it mocks up.
I think the fix is to have the builtin:: pp_ funcs use dXSTARG
and have ck_builtin_func1
set OPpENTERSUB_HASTARG
.
@tonycoz Hrm; a likely-sounding idea, but at first attempt it falls over:
pp.c: In function ‘Perl_pp_reftype’:
pp.c:7929:5: error: ‘dXSTARG’ undeclared (first use in this function); did you mean ‘dTAR
’?
7929 | dXSTARG;
| ^~~~~~~
| dTARG
This because dXSTARG
comes from XSUB.h
which we don't pull into pp.c
.
Such a fix works fine for the XS_builtin_trim
that appears in builtin.c
though.
This because
dXSTARG
comes fromXSUB.h
which we don't pull intopp.c
.
If we want these functions to be used both as XSUBs and pp funcs that will need to change, or we need to move the pp funcs into builtin.c
.
Or not use TARG in them, which loses performance.
Another option would be to use the coresub mechanism (handles &CORE::opname) to handle it, but nightmares lurk there (it would make the XSUBs slower too).
My assumptions:
Many builtin::*
functions call Perl_pp_*
directly. The Perl_pp_*
functions assume they can place their result in a pre-allocated SV slot (the "target"), which they access using PL_curpad[PL_op->op_targ]
. In normal code, these slots are created by the compiler depending on what operations appear in a given scope.
If my understanding of the situation is correct, then I see two ways forward:
builtin::*
functions allocate dummy PL_curpad
and PL_op
structures, and temporarily switch to them for the call to Perl_pp_*
.Perl_pp_*
logic into separate functions that take (SV *targ, SV *arg)
arguments. The Perl_pp_*
functions become wrappers that do their usual dTARGET; ... rpp_replace_1_1_NN(TARG);
dance, and the builtin::*
functions can call the underlying implementation directly without worrying about targets.On Sat, Sep 07, 2024 at 11:08:28PM -0700, mauke wrote:
If my understanding of the situation is correct, then I see two ways forward:
Or 3) reuse whatever mechanism the CORE namespace uses. Every perl builtin op is accessible as a function, .e.g.:
my $r = [];
# prints "ARRAY ARRAY"
printf "%s %s\n",
ref($r),
&CORE::ref($r);
I can't recall off the top of my head how it's implemented.
-- Modern art: "That's easy, I could have done that!" "Ah, but you didn't!"
Description Some of the built-in functions in
builtin::
crash when called viagoto &builtin::X
.This is (one of) the underlying issue(s) from #22528. I'm reporting it separately so it doesn't get lost even if Tie::RefHash::Weak gets fixed (or rather, a workaround is deployed in Tie::RefHash). As noted in https://github.com/Perl/perl5/issues/22528#issuecomment-2302576538 by @leonerd:
Steps to Reproduce
Expected behavior No crash.
Perl configuration