]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commitdiff
Make the uvar user data into a proper struct
authorVincent Pit <vince@profvince.com>
Thu, 2 Aug 2012 21:52:18 +0000 (23:52 +0200)
committerVincent Pit <vince@profvince.com>
Thu, 2 Aug 2012 21:52:18 +0000 (23:52 +0200)
Magic.xs

index ccb4685953e2f119e6a1c32566c42d19762f3863..d3d17bf24b48edb3ba273309f7c2c2c19aed28bc 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
@@ -778,6 +778,11 @@ STATIC SV *vmg_data_get(pTHX_ SV *sv, const vmg_wizard *w) {
 #if VMG_UVAR
 STATIC I32 vmg_svt_val(pTHX_ IV, SV *);
 
+typedef struct {
+ struct ufuncs new_uf;
+ struct ufuncs old_uf;
+} vmg_uvar_ud;
+
 STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) {
  if (prevmagic) {
   prevmagic->mg_moremagic = moremagic;
@@ -837,14 +842,14 @@ STATIC UV vmg_cast(pTHX_ SV *sv, const vmg_wizard *w, const SV *wiz, SV **args,
 #if VMG_UVAR
  if (w->uvar) {
   MAGIC *prevmagic, *moremagic = NULL;
-  struct ufuncs uf[2];
+  vmg_uvar_ud ud;
 
-  uf[0].uf_val   = vmg_svt_val;
-  uf[0].uf_set   = NULL;
-  uf[0].uf_index = 0;
-  uf[1].uf_val   = NULL;
-  uf[1].uf_set   = NULL;
-  uf[1].uf_index = 0;
+  ud.new_uf.uf_val   = vmg_svt_val;
+  ud.new_uf.uf_set   = NULL;
+  ud.new_uf.uf_index = 0;
+  ud.old_uf.uf_val   = NULL;
+  ud.old_uf.uf_set   = NULL;
+  ud.old_uf.uf_index = 0;
 
   /* One uvar magic in the chain is enough. */
   for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic) {
@@ -854,18 +859,18 @@ STATIC UV vmg_cast(pTHX_ SV *sv, const vmg_wizard *w, const SV *wiz, SV **args,
   }
 
   if (mg) { /* Found another uvar magic. */
-   struct ufuncs *olduf = (struct ufuncs *) mg->mg_ptr;
-   if (olduf->uf_val == vmg_svt_val) {
+   struct ufuncs *uf = (struct ufuncs *) mg->mg_ptr;
+   if (uf->uf_val == vmg_svt_val) {
     /* It's our uvar magic, nothing to do. oldgmg was true. */
     goto done;
    } else {
     /* It's another uvar magic, backup it and replace it by ours. */
-    uf[1] = *olduf;
+    ud.old_uf = *uf;
     vmg_uvar_del(sv, prevmagic, mg, moremagic);
    }
   }
 
-  sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &uf, sizeof(uf));
+  sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &ud, sizeof(ud));
   vmg_mg_magical(sv);
   /* Our hash now carries uvar magic. The uvar/clear shortcoming has to be
    * handled by our uvar callback. */
@@ -942,19 +947,23 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, const vmg_wizard *w) {
   }
 
   if (uvars == 1) {
-   struct ufuncs *uf;
+   vmg_uvar_ud *ud;
+
    for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic){
     moremagic = mg->mg_moremagic;
     if (mg->mg_type == PERL_MAGIC_uvar)
      break;
    }
-   uf = (struct ufuncs *) mg->mg_ptr;
-   if (uf[1].uf_val || uf[1].uf_set) {
+
+   ud = (vmg_uvar_ud *) mg->mg_ptr;
+   if (ud->old_uf.uf_val || ud->old_uf.uf_set) {
     /* Revert the original uvar magic. */
-    uf[0] = uf[1];
-    Renew(uf, 1, struct ufuncs);
+    struct ufuncs *uf;
+    Newx(uf, 1, struct ufuncs);
+    *uf = ud->old_uf;
+    Safefree(ud);
     mg->mg_ptr = (char *) uf;
-    mg->mg_len = sizeof(struct ufuncs);
+    mg->mg_len = sizeof(*uf);
    } else {
     /* Remove the uvar magic. */
     vmg_uvar_del(sv, prevmagic, mg, moremagic);
@@ -1317,7 +1326,7 @@ STATIC OP *vmg_pp_resetuvar(pTHX) {
 }
 
 STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) {
struct ufuncs *uf;
vmg_uvar_ud *ud;
  MAGIC *mg, *umg;
  SV *key = NULL, *newkey = NULL;
  int tied = 0;
@@ -1325,12 +1334,12 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) {
  umg = mg_find(sv, PERL_MAGIC_uvar);
  /* umg can't be NULL or we wouldn't be there. */
  key = umg->mg_obj;
- uf  = (struct ufuncs *) umg->mg_ptr;
+ ud  = (vmg_uvar_ud *) umg->mg_ptr;
 
- if (uf[1].uf_val)
-  uf[1].uf_val(aTHX_ action, sv);
- if (uf[1].uf_set)
-  uf[1].uf_set(aTHX_ action, sv);
+ if (ud->old_uf.uf_val)
+  ud->old_uf.uf_val(aTHX_ action, sv);
+ if (ud->old_uf.uf_set)
+  ud->old_uf.uf_set(aTHX_ action, sv);
 
  for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
   const vmg_wizard *w;