Branch: refs/heads/blead Home: https://github.com/Perl/perl5 Commit: 58cf04199f69d7a775bc88024df0bbb48712ea37 https://github.com/Perl/perl5/commit/58cf04199f69d7a775bc88024df0bbb48712ea37 Author: David Mitchell <da...@iabyn.com> Date: 2022-07-06 (Wed, 06 Jul 2022)
Changed paths: M ext/XS-APItest/APItest.pm M ext/XS-APItest/APItest.xs M pp_ctl.c M t/op/goto.t Log Message: ----------- goto(&xs_sub): provide correct caller context GH #19188 in something like sub foo { goto &xs_sub } if the XS subroutine tries to get its caller context using GIMME_V, it used to always be reported as scalar, since the OP_GOTO is the current op being executed, and that op is marked as scalar. The correct answer should be to return the context of the caller of foo(), but that information is lost as, just before calling the XS sub, pp_goto pops the CXt_SUB off the context stack which holds the recorded value of the context of the caller. The fix in principle is for goto, just before calling the XS sub, to grab the gimme value from the about-to-be-popped CXt_SUB frame, and set OP_GOTO op's op_flag field with that gimme value. However, modifying ops at runtime isn't allowed, as ops are shared between threads. So instead set up a fake copy of the OP_GOTO and alter the gimme value in that instead. I'm pretty confident that on an exception, a LEAVE_SCOPE() will always be done before the JMPENV_JUMP(), so PL_op will be restored to its original value *before* the CPU stack is restored to it's old value (leaving the temporary OP_GOTO as garbage in an abandoned stack frame).