-
Notifications
You must be signed in to change notification settings - Fork 584
Perl_newSLICEOP: Optimise '(caller)[0]' into 'scalar caller' #23369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: blead
Are you sure you want to change the base?
Conversation
A subroutine can obtain just the package of its caller in a couple of ways. Both seem somewhat common. * `caller` - in scaler context, as in `my $x = caller;` * `(caller)[0]`, as in `my $x = (caller)[0];` In the first, `caller` finds the package name, sticks it in a new SV, and puts that (or `undef`) on the stack: <0> caller[t2] s In the second, `caller` (a) finds the package name, filename, and line (b) creates three new SVs to hold them all (c) puts those SVs on the stack (d) does a list slice to leave just the package SV on the stack. 7 <2> lslice sK/2 ->8 - <1> ex-list lK ->5 3 <0> pushmark s ->4 4 <$> const[IV 0] s ->5 - <1> ex-list lK ->7 5 <0> pushmark s ->6 6 <0> caller[t2] l ->7 This commit checks for the second case inside `Perl_newSLICEOP` and instead of constructing a `lslice` OP, returns just the `caller` OP with scalar context applied.
Should've been done 30 years ago. Most PP devs think
Rich, would you pretty please be able to tackle adding OP tree compile time next gen |
Hmmm, if I can co-opt |
pp_caller() has 3 return prototypes, -1 SV* All that is needed is a room to put a U16 variable in OP_CALLER's OP struct, or 10 unused bits somewhere. 10 bits will allow a fast and easy pattern of
inside pp_caller. My thought 5 years ago was to add a 2nd integer argument, allowing the end use to pick 1 of 10 elements to return, but I didn't like my proposal, since it would only help new code, and heavily policed and evangelized new code. My wishlist quickly changed to, the existing production in the field deployed perl code needs to be left un-touched, the correct fix would be from the P5P side, from the 'yylex'/'ck_op_()' side by analyzing the scalar or list context
I don't know how |
I didn't do an exhaustive grep of CPAN on the train this morning, but it did seem like handling only the first 4 SVs would cover the vast majority of actually-encounted slice cases. Hence abuse of |
values 0-9 aka 10 SVs fit in 4 bits. Picking 1, 2 , 3 or more non linear SVs out of 10, requires 10 bits of space. IDK how to read all the lines below, but my eyes see worst case ever 3 bits free, at minimum case a U8 available, getting creative steal some bits from
There is also the sneaky solution of |
Yeah, but
We could have a new |
A subroutine can obtain just the package of its caller in a couple of ways. Both seem somewhat common.
caller
- in scaler context, as inmy $x = caller;
(caller)[0]
, as inmy $x = (caller)[0];
In the first,
caller
finds the package name, sticks it in a new SV, and puts that (orundef
) on the stack:In the second,
caller
(a) finds the package name, filename, and line (b) creates three new SVs to hold them all (c) puts those SVs on the stack (d) does a list slice to leave just the package SV on the stack.This commit checks for the second case inside
Perl_newSLICEOP
and instead of constructing alslice
OP, returns just thecaller
OP with scalar context applied.