]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blobdiff - Upper.xs
Also preserve PL_scopestack[cx->blk_oldscopesp - 1] in formats
[perl/modules/Scope-Upper.git] / Upper.xs
index fcd40126e6bf50dd23f4bf767890f73261cee6de..5b0685d97502efdab9caa4a15d4c958615757ccf 100644 (file)
--- a/Upper.xs
+++ b/Upper.xs
@@ -1001,9 +1001,26 @@ static void su_pop(pTHX_ void *ud) {
                      ud,                24, ' ',    mark,        base));
 
  if (base < mark) {
+#if SU_HAS_PERL(5, 19, 4)
+  I32 save = -1;
+  PERL_CONTEXT *cx;
+#endif
+
   SU_D(PerlIO_printf(Perl_debug_log, "%p: clear leftovers\n", ud));
+
+#if SU_HAS_PERL(5, 19, 4)
+  cx = cxstack + cxstack_ix;
+  if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)
+   save = PL_scopestack[cx->blk_oldscopesp - 1];
+#endif
+
   PL_savestack_ix = mark;
   leave_scope(base);
+
+#if SU_HAS_PERL(5, 19, 4)
+  if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)
+   PL_scopestack[cx->blk_oldscopesp - 1] = save;
+#endif
  }
  PL_savestack_ix = base;
 
@@ -1381,6 +1398,8 @@ static su_uplevel_ud *su_uplevel_storage_new(pTHX_ I32 cxix) {
  return sud;
 }
 
+#if SU_HAS_PERL(5, 13, 7)
+
 static void su_uplevel_storage_delete(pTHX_ su_uplevel_ud *sud) {
 #define su_uplevel_storage_delete(S) su_uplevel_storage_delete(aTHX_ (S))
  dMY_CXT;
@@ -1408,6 +1427,8 @@ static void su_uplevel_storage_delete(pTHX_ su_uplevel_ud *sud) {
  }
 }
 
+#endif
+
 static int su_uplevel_goto_static(const OP *o) {
  for (; o; o = OpSIBLING(o)) {
   /* goto ops are unops with kids. */
@@ -2198,9 +2219,77 @@ static I32 su_context_gimme(pTHX_ I32 cxix) {
  return G_VOID;
 }
 
+/* --- Global setup/teardown ----------------------------------------------- */
+
+static U32 su_initialized = 0;
+
+static void su_global_teardown(pTHX_ void *root) {
+ if (!su_initialized)
+  return;
+
+#if SU_MULTIPLICITY
+ if (aTHX != root)
+  return;
+#endif
+
+ SU_LOCK(&su_uid_seq_counter_mutex);
+ PerlMemShared_free(su_uid_seq_counter.seqs);
+ su_uid_seq_counter.size = 0;
+ SU_UNLOCK(&su_uid_seq_counter_mutex);
+
+ MUTEX_DESTROY(&su_uid_seq_counter_mutex);
+
+ su_initialized = 0;
+
+ return;
+}
+
+XS(XS_Scope__Upper_unwind);
+XS(XS_Scope__Upper_yield);
+XS(XS_Scope__Upper_leave);
+
+#if SU_HAS_PERL(5, 9, 0)
+# define SU_XS_FILE_TYPE const char
+#else
+# define SU_XS_FILE_TYPE char
+#endif
+
+static void su_global_setup(pTHX_ SU_XS_FILE_TYPE *file) {
+#define su_global_setup(F) su_global_setup(aTHX_ (F))
+ HV *stash;
+
+ if (su_initialized)
+  return;
+
+ MUTEX_INIT(&su_uid_seq_counter_mutex);
+
+ SU_LOCK(&su_uid_seq_counter_mutex);
+ su_uid_seq_counter.seqs = NULL;
+ su_uid_seq_counter.size = 0;
+ SU_UNLOCK(&su_uid_seq_counter_mutex);
+
+ stash = gv_stashpv(__PACKAGE__, 1);
+ newCONSTSUB(stash, "TOP",           newSViv(0));
+ newCONSTSUB(stash, "SU_THREADSAFE", newSVuv(SU_THREADSAFE));
+
+ newXSproto("Scope::Upper::unwind", XS_Scope__Upper_unwind, file, NULL);
+ newXSproto("Scope::Upper::yield",  XS_Scope__Upper_yield,  file, NULL);
+ newXSproto("Scope::Upper::leave",  XS_Scope__Upper_leave,  file, NULL);
+
+#if SU_MULTIPLICITY
+ call_atexit(su_global_teardown, aTHX);
+#else
+ call_atexit(su_global_teardown, NULL);
+#endif
+
+ su_initialized = 1;
+
+ return;
+}
+
 /* --- Interpreter setup/teardown ------------------------------------------ */
 
-static void su_teardown(pTHX_ void *param) {
+static void su_local_teardown(pTHX_ void *param) {
  su_uplevel_ud *cur;
  su_uid **map;
  dMY_CXT;
@@ -2226,8 +2315,8 @@ static void su_teardown(pTHX_ void *param) {
  return;
 }
 
-static void su_setup(pTHX) {
-#define su_setup() su_setup(aTHX)
+static void su_local_setup(pTHX) {
+#define su_local_setup() su_local_setup(aTHX)
  MY_CXT_INIT;
 
  MY_CXT.stack_placeholder = NULL;
@@ -2257,7 +2346,7 @@ static void su_setup(pTHX) {
  MY_CXT.uid_storage.used  = 0;
  MY_CXT.uid_storage.alloc = 0;
 
- call_atexit(su_teardown, NULL);
+ call_atexit(su_local_teardown, NULL);
 
  return;
 }
@@ -2300,8 +2389,6 @@ default_cx:                     \
 # define SU_INFO_COUNT 10
 #endif
 
-XS(XS_Scope__Upper_unwind); /* prototype to pass -Wmissing-prototypes */
-
 XS(XS_Scope__Upper_unwind) {
 #ifdef dVAR
  dVAR; dXSARGS;
@@ -2346,8 +2433,6 @@ XS(XS_Scope__Upper_unwind) {
 
 static const char su_yield_name[] = "yield";
 
-XS(XS_Scope__Upper_yield); /* prototype to pass -Wmissing-prototypes */
-
 XS(XS_Scope__Upper_yield) {
 #ifdef dVAR
  dVAR; dXSARGS;
@@ -2377,8 +2462,6 @@ XS(XS_Scope__Upper_yield) {
 
 static const char su_leave_name[] = "leave";
 
-XS(XS_Scope__Upper_leave); /* prototype to pass -Wmissing-prototypes */
-
 XS(XS_Scope__Upper_leave) {
 #ifdef dVAR
  dVAR; dXSARGS;
@@ -2406,22 +2489,8 @@ PROTOTYPES: ENABLE
 
 BOOT:
 {
- HV *stash;
-
- MUTEX_INIT(&su_uid_seq_counter_mutex);
-
- su_uid_seq_counter.seqs = NULL;
- su_uid_seq_counter.size = 0;
-
- stash = gv_stashpv(__PACKAGE__, 1);
- newCONSTSUB(stash, "TOP",           newSViv(0));
- newCONSTSUB(stash, "SU_THREADSAFE", newSVuv(SU_THREADSAFE));
-
- newXSproto("Scope::Upper::unwind", XS_Scope__Upper_unwind, file, NULL);
- newXSproto("Scope::Upper::yield",  XS_Scope__Upper_yield,  file, NULL);
- newXSproto("Scope::Upper::leave",  XS_Scope__Upper_leave,  file, NULL);
-
- su_setup();
+ su_global_setup(file);
+ su_local_setup();
 }
 
 #if SU_THREADSAFE
@@ -2707,7 +2776,9 @@ PPCODE:
     goto context_info_warnings_off;
 #endif
   } else if (old_warnings == pWARN_NONE) {
+#if !SU_HAS_PERL(5, 17, 4)
 context_info_warnings_off:
+#endif
    mask = su_newmortal_pvn(WARN_NONEstring, WARNsize);
   } else if (old_warnings == pWARN_ALL) {
    HV *bits;