]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - Magic.xs
Stop leaking objects stored in the data slot
[perl/modules/Variable-Magic.git] / Magic.xs
index a3f40c8a3015cc416450c43f623a33168d2cb419..df86b33edfd7ee6dd994d48b6d87721fbac39800 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
@@ -394,8 +394,7 @@ STATIC void vmg_mgwiz_free(pTHX_ MGWIZ *w) {
 #if VMG_THREADSAFE
 
 #define VMG_CLONE_CB(N) \
- z->cb_ ## N = (w->cb_ ## N) ? newRV_noinc(vmg_clone(SvRV(w->cb_ ## N), \
-                                           w->owner))                   \
+ z->cb_ ## N = (w->cb_ ## N) ? vmg_clone(w->cb_ ## N, w->owner) \
                              : NULL;
 
 STATIC MGWIZ *vmg_mgwiz_clone(pTHX_ const MGWIZ *w) {
@@ -610,10 +609,10 @@ STATIC const MAGIC *vmg_find(const SV *sv, const SV *wiz) {
 
 /* ... Construct private data .............................................. */
 
-STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, AV *args) {
-#define vmg_data_new(C, S, A) vmg_data_new(aTHX_ (C), (S), (A))
+STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, SV **args, I32 items) {
+#define vmg_data_new(C, S, A, I) vmg_data_new(aTHX_ (C), (S), (A), (I))
+ I32 i;
  SV *nsv;
- I32 i, alen = (args == NULL) ? 0 : av_len(args);
 
  dSP;
 
@@ -621,10 +620,10 @@ STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, AV *args) {
  SAVETMPS;
 
  PUSHMARK(SP);
- EXTEND(SP, alen + 1);
+ EXTEND(SP, items + 1);
  PUSHs(sv_2mortal(newRV_inc(sv)));
- for (i = 0; i < alen; ++i)
-  PUSHs(*av_fetch(args, i, 0));
+ for (i = 0; i < items; ++i)
+  PUSHs(args[i]);
  PUTBACK;
 
  call_sv(ctor, G_SCALAR);
@@ -667,8 +666,8 @@ STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic)
 }
 #endif /* VMG_UVAR */
 
-STATIC UV vmg_cast(pTHX_ SV *sv, const SV *wiz, AV *args) {
-#define vmg_cast(S, W, A) vmg_cast(aTHX_ (S), (W), (A))
+STATIC UV vmg_cast(pTHX_ SV *sv, const SV *wiz, SV **args, I32 items) {
+#define vmg_cast(S, W, A, I) vmg_cast(aTHX_ (S), (W), (A), (I))
  MAGIC       *mg, *moremagic = NULL;
  SV          *data;
  const MGWIZ *w;
@@ -680,8 +679,9 @@ STATIC UV vmg_cast(pTHX_ SV *sv, const SV *wiz, AV *args) {
  w = vmg_wizard_mgwiz(wiz);
  oldgmg = SvGMAGICAL(sv);
 
- data = (w->cb_data) ? vmg_data_new(w->cb_data, sv, args) : NULL;
+ data = (w->cb_data) ? vmg_data_new(w->cb_data, sv, args, items) : NULL;
  mg = sv_magicext(sv, data, PERL_MAGIC_ext, w->vtbl, (const char *) wiz, HEf_SVKEY);
+ SvREFCNT_dec(data);
  mg->mg_private = SIG_WIZ;
 #if MGf_COPY
  if (w->cb_copy)
@@ -1232,13 +1232,13 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) {
 
 #define VMG_SET_CB(S, N)              \
  cb = (S);                            \
- w->cb_ ## N = (SvOK(cb) && SvROK(cb)) ? newRV_inc(SvRV(cb)) : NULL;
+ w->cb_ ## N = (SvOK(cb) && SvROK(cb)) ? SvREFCNT_inc(SvRV(cb)) : NULL;
 
 #define VMG_SET_SVT_CB(S, N)          \
  cb = (S);                            \
  if (SvOK(cb) && SvROK(cb)) {         \
   t->svt_ ## N = vmg_svt_ ## N;       \
-  w->cb_  ## N = newRV_inc(SvRV(cb)); \
+  w->cb_  ## N = SvREFCNT_inc(SvRV(cb)); \
  } else {                             \
   t->svt_ ## N = NULL;                \
   w->cb_  ## N = NULL;                \
@@ -1410,20 +1410,15 @@ OUTPUT:
 SV *cast(SV *sv, SV *wiz, ...)
 PROTOTYPE: \[$@%&*]$@
 PREINIT:
- AV *args = NULL;
+ SV **args = NULL;
+ I32 i = 0;
  SV *ret;
 CODE:
  if (items > 2) {
-  I32 i;
-  args = newAV();
-  av_fill(args, items - 2);
-  for (i = 2; i < items; ++i) {
-   SV *arg = ST(i);
-   SvREFCNT_inc(arg);
-   if (av_store(args, i - 2, arg) == NULL) croak(vmg_argstorefailed);
-  }
+  i = items - 2;
+  args = &ST(2);
  }
- ret = newSVuv(vmg_cast(SvRV(sv), vmg_wizard_validate(wiz), args));
+ ret = newSVuv(vmg_cast(SvRV(sv), vmg_wizard_validate(wiz), args, i));
  SvREFCNT_dec(args);
  RETVAL = ret;
 OUTPUT: