Don't call DESTROY if it's a constant subroutine.
Ap |OP* |newANONSUB |I32 floor|NULLOK OP* proto|NULLOK OP* block
Apa |OP* |newASSIGNOP |I32 flags|NULLOK OP* left|I32 optype|NULLOK OP* right
Apa |OP* |newCONDOP |I32 flags|NN OP* first|NULLOK OP* trueop|NULLOK OP* falseop
-Apd |CV* |newCONSTSUB |NULLOK HV* stash|NULLOK const char* name|NN SV* sv
+Apd |CV* |newCONSTSUB |NULLOK HV* stash|NULLOK const char* name|NULLOK SV* sv
#ifdef PERL_MAD
Ap |OP* |newFORM |I32 floor|NULLOK OP* o|NULLOK OP* block
#else
Creates a constant sub equivalent to Perl C<sub FOO () { 123 }> which is
eligible for inlining at compile-time.
+Passing NULL for SV creates a constant sub equivalent to C<sub BAR () {}>,
+which won't be called if used as a destructor, but will suppress the overhead
+of a call to C<AUTOLOAD>. (This form, however, isn't eligible for inlining at
+compile time.)
+
=cut
*/
{
dVAR;
dXSARGS;
+ SV *const sv = MUTABLE_SV(XSANY.any_ptr);
if (items != 0) {
NOOP;
#if 0
HvNAME_get(GvSTASH(CvGV(cv))), GvNAME(CvGV(cv)));
#endif
}
+ if (!sv) {
+ XSRETURN(0);
+ }
EXTEND(sp, 1);
- ST(0) = MUTABLE_SV(XSANY.any_ptr);
+ ST(0) = sv;
XSRETURN(1);
}
Creates a constant sub equivalent to Perl C<sub FOO () { 123 }> which is
eligible for inlining at compile-time.
+Passing NULL for SV creates a constant sub equivalent to C<sub BAR () {}>,
+which won't be called if used as a destructor, but will suppress the overhead
+of a call to C<AUTOLOAD>. (This form, however, isn't eligible for inlining at
+compile time.)
+
CV* newCONSTSUB(HV* stash, const char* name, SV* sv)
=for hackers
#define PERL_ARGS_ASSERT_NEWCONDOP \
assert(first)
-PERL_CALLCONV CV* Perl_newCONSTSUB(pTHX_ HV* stash, const char* name, SV* sv)
- __attribute__nonnull__(pTHX_3);
-#define PERL_ARGS_ASSERT_NEWCONSTSUB \
- assert(sv)
-
+PERL_CALLCONV CV* Perl_newCONSTSUB(pTHX_ HV* stash, const char* name, SV* sv);
#ifdef PERL_MAD
PERL_CALLCONV OP* Perl_newFORM(pTHX_ I32 floor, OP* o, OP* block);
#else
stash = SvSTASH(sv);
destructor = StashHANDLER(stash,DESTROY);
if (destructor
+ /* A constant subroutine can have no side effects, so
+ don't bother calling it. */
+ && !CvCONST(destructor)
/* Don't bother calling an empty destructor */
&& (CvISXSUB(destructor)
|| CvSTART(destructor)->op_next->op_type != OP_LEAVESUB))