# define HvNAME_get(H) HvNAME(H)
#endif
+#ifndef ENTER_with_name
+# define ENTER_with_name(N) ENTER
+#endif
+
+#ifndef LEAVE_with_name
+# define LEAVE_with_name(N) LEAVE
+#endif
+
#ifndef gv_fetchpvn_flags
# define gv_fetchpvn_flags(A, B, C, D) gv_fetchpv((A), (C), (D))
#endif
STATIC void su_call(pTHX_ void *ud_) {
su_ud_reap *ud = (su_ud_reap *) ud_;
-#if SU_HAS_PERL(5, 10, 0)
+#if SU_HAS_PERL(5, 9, 5)
+ PERL_CONTEXT saved_cx;
I32 dieing = PL_op->op_type == OP_DIE;
+ I32 cxix;
#endif
dSP;
PUSHMARK(SP);
PUTBACK;
- /* If cxstack_ix isn't incremented there, the eval context will be overwritten
- * when the new sub scope will be created in call_sv. */
+ /* If the recently popped context isn't saved there, it will be overwritten by
+ * the sub scope from call_sv, although it's still needed in our caller. */
-#if SU_HAS_PERL(5, 10, 0)
+#if SU_HAS_PERL(5, 9, 5)
if (dieing) {
if (cxstack_ix < cxstack_max)
- ++cxstack_ix;
+ cxix = cxstack_ix + 1;
else
- cxstack_ix = Perl_cxinc(aTHX);
+ cxix = Perl_cxinc(aTHX);
+ saved_cx = cxstack[cxix];
}
#endif
call_sv(ud->cb, G_VOID);
-#if SU_HAS_PERL(5, 10, 0)
- if (dieing && cxstack_ix > 0)
- --cxstack_ix;
+#if SU_HAS_PERL(5, 9, 5)
+ if (dieing)
+ cxstack[cxix] = saved_cx;
#endif
- SPAGAIN;
PUTBACK;
FREETMPS;
if (SvTYPE(sv) >= SVt_PVGV) {
gv = (GV *) sv;
- if (!val) { /* local *x; */
+ if (!val || !SvROK(val)) { /* local *x; or local *x = $val; */
t = SVt_PVGV;
- } else if (!SvROK(val)) { /* local *x = $val; */
- goto assign;
- } else { /* local *x = \$val; */
+ } else { /* local *x = \$val; */
t = SvTYPE(SvRV(val));
deref = 1;
}
ud, PL_savestack_ix,
PL_scopestack[PL_scopestack_ix]));
-assign:
if (val)
SvSetMagicSV((SV *) gv, val);
ud, PL_savestack_ix, depth));
} else {
SU_UD_HANDLER(ud)(aTHX_ ud);
+#if SU_DEBUG
+ if (PL_scopestack[PL_scopestack_ix] != PL_savestack_ix)
+ PerlIO_printf(Perl_debug_log, "%p: expected: %2d got: %2d\n", ud, PL_scopestack_ix, PL_savestack_ix);
+#endif /* SU_DEBUG */
}
}
#define su_init(L, U, S) su_init(aTHX_ (L), (U), (S))
I32 i, depth = 0, *origin;
- LEAVE;
+ LEAVE_with_name("sub");
if (cxix >= cxstack_ix) {
SU_UD_HANDLER(ud)(aTHX_ ud);
for (i = cxstack_ix; i > cxix; --i) {
PERL_CONTEXT *cx = cxstack + i;
switch (CxTYPE(cx)) {
+#if SU_HAS_PERL(5, 10, 0)
+ case CXt_BLOCK:
+ SU_D(PerlIO_printf(Perl_debug_log, "%p: cx %d is block\n", ud, i));
+ /* Given and when blocks are actually followed by a simple block, so skip
+ * it if needed. */
+ if (cxix > 0) { /* Implies i > 0 */
+ PERL_CONTEXT *next = cx - 1;
+ if (CxTYPE(next) == CXt_GIVEN || CxTYPE(next) == CXt_WHEN)
+ --cxix;
+ }
+ depth++;
+ break;
+#endif
#if SU_HAS_PERL(5, 11, 0)
case CXt_LOOP_FOR:
case CXt_LOOP_PLAIN:
depth += 2;
break;
default:
- SU_D(PerlIO_printf(Perl_debug_log, "%p: cx %d is normal\n", ud, i));
+ SU_D(PerlIO_printf(Perl_debug_log, "%p: cx %d is other\n", ud, i));
depth++;
break;
}
SAVEDESTRUCTOR_X(su_pop, ud);
done:
- ENTER;
+ ENTER_with_name("sub");
return depth;
}
HV *stash;
MY_CXT_INIT;
stash = gv_stashpv(__PACKAGE__, 1);
- newCONSTSUB(stash, "TOP", newSViv(0));
+ newCONSTSUB(stash, "TOP", newSViv(0));
+ newCONSTSUB(stash, "SU_THREADSAFE", newSVuv(SU_THREADSAFE));
newXSproto("Scope::Upper::unwind", XS_Scope__Upper_unwind, file, NULL);
}
PROTOTYPE: DISABLE
CODE:
PERL_UNUSED_VAR(items);
- MY_CXT_CLONE;
+ {
+ MY_CXT_CLONE;
+ }
#endif /* SU_THREADSAFE */