I accidentally broke these in commit
85ffec3682, yet everything passed
for me under threads+mad.
PL_compcv is usually restored to its previous value at the end of
newATTRSUB when LEAVE_SCOPE is called. But BEGIN blocks are called
before that. I needed PL_compcv to be restored to its previ-
ous value before it was called, so I added LEAVE_SCOPE before
process_special_blocks.
But that caused the name to be freed before S_process_special_blocks
got a chance to look at it.
So I have now added a new parameter to S_process_special_blocks to
allow *it* to call LEAVE_SCOPE after it determines that it is a BEGIN
block, but before it calls it.
|I32 enter_opcode|I32 leave_opcode \
|PADOFFSET entertarg
s |OP* |ref_array_or_hash|NULLOK OP* cond
-s |void |process_special_blocks |NN const char *const fullname\
+s |void |process_special_blocks |I32 floor \
+ |NN const char *const fullname\
|NN GV *const gv|NN CV *const cv
#endif
Xpa |void* |Slab_Alloc |size_t sz
#define op_integerize(a) S_op_integerize(aTHX_ a)
#define op_std_init(a) S_op_std_init(aTHX_ a)
#define pmtrans(a,b,c) S_pmtrans(aTHX_ a,b,c)
-#define process_special_blocks(a,b,c) S_process_special_blocks(aTHX_ a,b,c)
+#define process_special_blocks(a,b,c,d) S_process_special_blocks(aTHX_ a,b,c,d)
#define ref_array_or_hash(a) S_ref_array_or_hash(aTHX_ a)
#define refkids(a,b) S_refkids(aTHX_ a,b)
#define scalar_mod_type S_scalar_mod_type
}
if (name && ! (PL_parser && PL_parser->error_count))
- {
- LEAVE_SCOPE(floor);
- process_special_blocks(name, gv, cv);
- }
+ process_special_blocks(floor, name, gv, cv);
}
done:
}
STATIC void
-S_process_special_blocks(pTHX_ const char *const fullname, GV *const gv,
+S_process_special_blocks(pTHX_ I32 floor, const char *const fullname,
+ GV *const gv,
CV *const cv)
{
const char *const colon = strrchr(fullname,':');
if (*name == 'B') {
if (strEQ(name, "BEGIN")) {
const I32 oldscope = PL_scopestack_ix;
+ if (floor) LEAVE_SCOPE(floor);
ENTER;
SAVECOPFILE(&PL_compiling);
SAVECOPLINE(&PL_compiling);
CvXSUB(cv) = subaddr;
if (name)
- process_special_blocks(name, gv, cv);
+ process_special_blocks(0, name, gv, cv);
}
if (flags & XS_DYNAMIC_FILENAME) {
#define PERL_ARGS_ASSERT_PMTRANS \
assert(o); assert(expr); assert(repl)
-STATIC void S_process_special_blocks(pTHX_ const char *const fullname, GV *const gv, CV *const cv)
- __attribute__nonnull__(pTHX_1)
+STATIC void S_process_special_blocks(pTHX_ I32 floor, const char *const fullname, GV *const gv, CV *const cv)
__attribute__nonnull__(pTHX_2)
- __attribute__nonnull__(pTHX_3);
+ __attribute__nonnull__(pTHX_3)
+ __attribute__nonnull__(pTHX_4);
#define PERL_ARGS_ASSERT_PROCESS_SPECIAL_BLOCKS \
assert(fullname); assert(gv); assert(cv)
#define ENTER_with_name(name) ENTER
#define LEAVE_with_name(name) LEAVE
#endif
-#define LEAVE_SCOPE(old) if (PL_savestack_ix > old) leave_scope(old)
+#define LEAVE_SCOPE(old) STMT_START { \
+ if (PL_savestack_ix > old) leave_scope(old); \
+ } STMT_END
#define SAVEI8(i) save_I8((I8*)&(i))
#define SAVEI16(i) save_I16((I16*)&(i))