]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - Magic.xs
Reference count vmg_op_name_len
[perl/modules/Variable-Magic.git] / Magic.xs
index 985b37ff1771e3fbc3984062f2963e105b138700..d9eab57a9589b31e160ffc517d3b58892c656e75 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
@@ -498,7 +498,8 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, U16 sig) {
 #define VMG_OP_INFO_NAME   1
 #define VMG_OP_INFO_OBJECT 2
 
-STATIC STRLEN *vmg_op_name_len = NULL;
+STATIC U32     vmg_op_name_refcnt = 0;
+STATIC STRLEN *vmg_op_name_len    = NULL;
 
 STATIC HV *vmg_b__op_stash = NULL;
 
@@ -512,6 +513,7 @@ STATIC void vmg_op_info_init(pTHX_ unsigned int opinfo) {
     for (t = 0; t < OP_max; ++t)
      vmg_op_name_len[t] = strlen(PL_op_name[t]);
    }
+   ++vmg_op_name_refcnt;
    break;
   case VMG_OP_INFO_OBJECT:
    if (!vmg_b__op_stash) {
@@ -524,6 +526,22 @@ STATIC void vmg_op_info_init(pTHX_ unsigned int opinfo) {
  }
 }
 
+STATIC void vmg_op_info_deinit(unsigned int opinfo) {
+ switch (opinfo) {
+  case VMG_OP_INFO_NAME:
+   if (vmg_op_name_refcnt > 0)
+    --vmg_op_name_refcnt;
+   if (!vmg_op_name_refcnt && vmg_op_name_len) {
+    Safefree(vmg_op_name_len);
+    vmg_op_name_len = NULL;
+   }
+   break;
+  case VMG_OP_INFO_OBJECT:
+  default:
+   break;
+ }
+}
+
 STATIC SV *vmg_op_info(pTHX_ unsigned int opinfo) {
 #define vmg_op_info(W) vmg_op_info(aTHX_ (W))
  if (!PL_op)
@@ -877,6 +895,9 @@ STATIC int vmg_wizard_free(pTHX_ SV *wiz, MAGIC *mg) {
  if (w->cb_delete != NULL) { SvREFCNT_dec(SvRV(w->cb_delete)); }
 #endif /* VMG_UVAR */
 
+ if (w->opinfo)
+  vmg_op_info_deinit(w->opinfo);
+
  Safefree(w->vtbl);
  Safefree(w);
 
@@ -905,6 +926,7 @@ STATIC const char vmg_invalid_sig[]    = "Invalid numeric signature";
 STATIC const char vmg_wrongargnum[]    = "Wrong number of arguments";
 STATIC const char vmg_toomanysigs[]    = "Too many magic signatures used";
 STATIC const char vmg_argstorefailed[] = "Error while storing arguments";
+STATIC const char vmg_globstorefail[]  = "Couldn't store global wizard information";
 
 STATIC U16 vmg_sv2sig(pTHX_ SV *sv) {
 #define vmg_sv2sig(S) vmg_sv2sig(aTHX_ (S))
@@ -1094,7 +1116,7 @@ CODE:
    mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);
    mg->mg_private = SIG_WIZ;
    SvREADONLY_on(sv);
-   hv_store(hv, sig, len, sv, HeHASH(key));
+   if (!hv_store(hv, sig, len, sv, HeHASH(key))) croak("%s during CLONE", vmg_globstorefail);
   }
  }
  {
@@ -1194,7 +1216,7 @@ CODE:
  mg->mg_private = SIG_WIZ;
  SvREADONLY_on(sv);
 
hv_store(MY_CXT, buf, sprintf(buf, "%u", sig), sv, 0);
if (!hv_store(MY_CXT, buf, sprintf(buf, "%u", sig), sv, 0)) croak(vmg_globstorefail);
 
  RETVAL = newRV_noinc(sv);
 OUTPUT:
@@ -1242,12 +1264,13 @@ CODE:
 OUTPUT:
  RETVAL
 
-SV *getdata(SV *sv, SV *wiz)
+void
+getdata(SV *sv, SV *wiz)
 PROTOTYPE: \[$@%&*]$
 PREINIT:
  SV *data;
  U16 sig;
-CODE:
+PPCODE:
  sig = vmg_wizard_sig(wiz);
  if (!sig)
   XSRETURN_UNDEF;
@@ -1267,13 +1290,3 @@ CODE:
  RETVAL = newSVuv(vmg_dispell(SvRV(sv), sig));
 OUTPUT:
  RETVAL
-
-void
-_cleanup()
-PROTOTYPE:
-PPCODE:
- if (vmg_op_name_len) {
-  Safefree(vmg_op_name_len);
-  vmg_op_name_len = NULL;
- }
- XSRETURN(0);