Skip to content

Commit 03d4dc5

Browse files
committed
Define OPpSELF_IN_PAD private flag to OP_METHSTART
This flag indicates that `$self` argument handling has already been performed by the subroutine signature, so it should find the value already in the pad.
1 parent 0b0c873 commit 03d4dc5

File tree

4 files changed

+72
-57
lines changed

4 files changed

+72
-57
lines changed

class.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,14 @@ XS(injected_constructor)
254254
/* TODO: People would probably expect to find this in pp.c ;) */
255255
PP(pp_methstart)
256256
{
257-
/* note that if AvREAL(@_), be careful not to leak self:
258-
* so keep it in @_ for now, and only shift it later */
259-
SV *self = *(av_fetch(GvAV(PL_defgv), 0, 1));
257+
bool self_in_pad = PL_op->op_private & OPpSELF_IN_PAD;
258+
SV *self;
259+
if (self_in_pad)
260+
self = PAD_SVl(PADIX_SELF);
261+
else
262+
/* note that if AvREAL(@_), be careful not to leak self:
263+
* so keep it in @_ for now, and only shift it later */
264+
self = *(av_fetch(GvAV(PL_defgv), 0, 1));
260265
SV *rv = NULL;
261266

262267
/* pp_methstart happens before the first OP_NEXTSTATE of the method body,
@@ -285,8 +290,10 @@ PP(pp_methstart)
285290
croak("Cannot invoke a method of %" HvNAMEf_QUOTEDPREFIX " on an instance of %" HvNAMEf_QUOTEDPREFIX,
286291
HvNAMEfARG(CvSTASH(curcv)), HvNAMEfARG(SvSTASH(rv)));
287292

288-
save_clearsv(&PAD_SVl(PADIX_SELF));
289-
sv_setsv(PAD_SVl(PADIX_SELF), self);
293+
if (!self_in_pad) {
294+
save_clearsv(&PAD_SVl(PADIX_SELF));
295+
sv_setsv(PAD_SVl(PADIX_SELF), self);
296+
}
290297

291298
UNOP_AUX_item *aux = cUNOP_AUX->op_aux;
292299
if(aux) {
@@ -318,10 +325,12 @@ PP(pp_methstart)
318325
}
319326
}
320327

321-
/* safe to shift and free self now */
322-
self = av_shift(GvAV(PL_defgv));
323-
if (AvREAL(GvAV(PL_defgv)))
324-
SvREFCNT_dec_NN(self);
328+
if (!self_in_pad) {
329+
/* safe to shift and free self now */
330+
self = av_shift(GvAV(PL_defgv));
331+
if (AvREAL(GvAV(PL_defgv)))
332+
SvREFCNT_dec_NN(self);
333+
}
325334

326335
if(PL_op->op_private & OPpINITFIELDS) {
327336
SV *params = *av_fetch(GvAV(PL_defgv), 0, 0);

lib/B/Op_private.pm

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

opcode.h

Lines changed: 48 additions & 46 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

regen/op_private

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,8 @@ addbits('helemexistsor',
930930
);
931931

932932
addbits('methstart',
933-
7 => qw(OPpINITFIELDS INITFIELDS),
933+
7 => qw(OPpINITFIELDS INITFIELDS),
934+
6 => qw(OPpSELF_IN_PAD SELF_IN_PAD), # $self has already been set up in pad
934935
);
935936

936937
addbits('initfield',

0 commit comments

Comments
 (0)