]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blobdiff - Upper.xs
Factor all the LEAVE/ENTER logic in su_init()
[perl/modules/Scope-Upper.git] / Upper.xs
index 799a2f38b63ba48f3efc2ec7b105c3f7034f466c..bf520ceff3e66bca5c9e32b088619c2d0550293f 100644 (file)
--- a/Upper.xs
+++ b/Upper.xs
@@ -76,8 +76,7 @@ STATIC I32 su_av_preeminent(pTHX_ AV *av, I32 key) {
  MAGIC *mg;
  HV *stash;
 
- if (!av)
-  return 0;
+ if (!av) return 0;
  if (SvCANEXISTDELETE(av))
   return av_exists(av, key);
 
@@ -131,8 +130,7 @@ STATIC I32 su_hv_preeminent(pTHX_ HV *hv, SV *keysv) {
  MAGIC *mg;
  HV *stash;
 
- if (!hv)
-  return 0;
+ if (!hv) return 0;
  if (SvCANEXISTDELETE(hv) || mg_find((SV *) hv, PERL_MAGIC_env))
   return hv_exists_ent(hv, keysv, 0);
 
@@ -145,13 +143,13 @@ STATIC void su_save_helem(pTHX_ HV *hv, SV *keysv, SV **svp, I32 preeminent) {
   save_gp((GV *) *svp, 0);
   return;
  }
- if (!preeminent) {
+ if (preeminent)
+  save_helem(hv, keysv, svp);
+ else {
   STRLEN keylen;
   const char * const key = SvPV_const(keysv, keylen);
   SAVEDELETE(hv, savepvn(key, keylen),
                  SvUTF8(keysv) ? -(I32)keylen : (I32)keylen);
- } else {
-  save_helem(hv, keysv, svp);
  }
 }
 
@@ -167,10 +165,10 @@ typedef struct {
 #define SU_UD_ORIGIN(U)  (((su_ud_common *) (U))->origin)
 #define SU_UD_HANDLER(U) (((su_ud_common *) (U))->handler)
 
-#define SU_UD_FREE(U) do { \
+#define SU_UD_FREE(U) STMT_START { \
  if (SU_UD_ORIGIN(U)) Safefree(SU_UD_ORIGIN(U)); \
  Safefree(U); \
-} while (0)
+} STMT_END
 
 /* ... Reap ................................................................ */
 
@@ -403,6 +401,13 @@ STATIC I32 su_init(pTHX_ I32 level, void *ud, I32 size) {
  I32 i, depth = 0, *origin;
  I32 cur, last, step;
 
+ LEAVE;
+
+ if (level <= 0) {
+  SU_UD_HANDLER(ud)(aTHX_ ud);
+  goto done;
+ }
+
  SU_D(PerlIO_printf(Perl_debug_log, "%p: ### init for level %d\n", ud, level));
 
  for (i = 0; i < level; ++i) {
@@ -449,6 +454,15 @@ STATIC I32 su_init(pTHX_ I32 level, void *ud, I32 size) {
 
  SU_UD_ORIGIN(ud) = origin;
  SU_UD_DEPTH(ud)  = depth;
+
+ SU_D(PerlIO_printf(Perl_debug_log, "%p: set original destructor at %d [%d]\n",
+                                     ud, PL_savestack_ix, depth));
+
+ SAVEDESTRUCTOR_X(su_pop, ud);
+
+done:
+ ENTER;
+
  return depth;
 }
 
@@ -489,15 +503,7 @@ CODE:
  SU_UD_ORIGIN(ud)  = NULL;
  SU_UD_HANDLER(ud) = su_reap;
  ud->cb = newSVsv(hook);
- LEAVE;
- if (level) {
-  I32 depth = su_init(level, ud, 3);
-  SU_D(PerlIO_printf(Perl_debug_log, "%p: set original destructor at %d [%d]\n",
-                                      ud, PL_savestack_ix, depth));
-  SAVEDESTRUCTOR_X(su_pop, ud);
- } else
-  su_reap(ud);
- ENTER;
+ su_init(level, ud, 3);
 
 void
 localize(SV *sv, SV *val, ...)
@@ -514,15 +520,7 @@ CODE:
  ud->sv   = sv;
  ud->val  = newSVsv(val);
  ud->elem = NULL;
- LEAVE;
- if (level) {
-  I32 depth = su_init(level, ud, 3);
-  SU_D(PerlIO_printf(Perl_debug_log, "%p: set original destructor at %d [%d]\n",
-                                      ud, PL_savestack_ix, depth));
-  SAVEDESTRUCTOR_X(su_pop, ud);
- } else
-  su_localize(ud);
- ENTER;
+ su_init(level, ud, 3);
 
 void
 localize_elem(SV *sv, SV *elem, SV *val, ...)
@@ -540,13 +538,4 @@ CODE:
  ud->val  = newSVsv(val);
  SvREFCNT_inc(elem);
  ud->elem = elem;
- LEAVE;
- if (level) {
-  I32 depth = su_init(level, ud, 4);
-  SU_D(PerlIO_printf(Perl_debug_log, "%p: set original destructor at %d [%d]\n",
-                                      ud, PL_savestack_ix, depth));
-  SAVEDESTRUCTOR_X(su_pop, ud);
- } else
-  su_localize(ud);
- ENTER;
-
+ su_init(level, ud, 4);