]> git.vpit.fr Git - perl/modules/indirect.git/blobdiff - indirect.xs
Turn on CvCLONE for all anonymous subs passed as hooks
[perl/modules/indirect.git] / indirect.xs
index 36585193fdfaedb6bed331987d7d42b84430df9a..8e6c789b1b0098315650bf8b05193aac0eb0c77e 100644 (file)
 # define SvPVX_const SvPVX
 #endif
 
+#ifndef SvREFCNT_inc_simple_NN
+# define SvREFCNT_inc_simple_NN SvREFCNT_inc
+#endif
+
 #ifndef sv_catpvn_nomg
 # define sv_catpvn_nomg sv_catpvn
 #endif
@@ -260,12 +264,21 @@ STATIC void indirect_thread_cleanup(pTHX_ void *ud) {
 STATIC SV *indirect_tag(pTHX_ SV *value) {
 #define indirect_tag(V) indirect_tag(aTHX_ (V))
  indirect_hint_t *h;
+ SV *code = NULL;
  dMY_CXT;
 
- value = SvOK(value) && SvROK(value) ? SvRV(value) : NULL;
+ if (SvOK(value) && SvROK(value)) {
+  value = SvRV(value);
+  if (SvTYPE(value) >= SVt_PVCV) {
+   code = value;
+   if (CvANON(code) && !CvCLONED(code))
+    CvCLONE_on(code);
+   SvREFCNT_inc_simple_NN(code);
+  }
+ }
 
  h = PerlMemShared_malloc(sizeof *h);
- h->code = SvREFCNT_inc(value);
+ h->code = code;
 
 #if I_WORKAROUND_REQUIRE_PROPAGATION
  {
@@ -600,17 +613,8 @@ STATIC OP *indirect_ck_scope(pTHX_ OP *o) {
  return o;
 }
 
-/* ... ck_leave ............................................................ */
-
-STATIC OP *(*indirect_old_ck_leave)(pTHX_ OP *) = 0;
-
-STATIC OP *indirect_ck_leave(pTHX_ OP *o) {
- o = CALL_FPTR(indirect_old_ck_leave)(aTHX_ o);
-
- /* Cleanup relevant entries in case ck_method catches them later. */
- indirect_map_delete(o);
- return o;
-}
+/* We don't need to clean the map entries for leave ops because they can only
+ * be created by mutating from a lineseq. */
 
 /* ... ck_method ........................................................... */
 
@@ -780,8 +784,6 @@ BOOT:
   PL_check[OP_SCOPE]       = MEMBER_TO_FPTR(indirect_ck_scope);
   indirect_old_ck_lineseq  = PL_check[OP_LINESEQ];
   PL_check[OP_LINESEQ]     = MEMBER_TO_FPTR(indirect_ck_scope);
-  indirect_old_ck_leave    = PL_check[OP_LEAVE];
-  PL_check[OP_LEAVE]       = MEMBER_TO_FPTR(indirect_ck_leave);
 
   indirect_old_ck_method   = PL_check[OP_METHOD];
   PL_check[OP_METHOD]      = MEMBER_TO_FPTR(indirect_ck_method);