summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-06-23 09:48:34 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-06-29 00:20:55 -0700
commitbb38a9e0f528ce1ecffe4f8c3c76984148803932 (patch)
tree7a2a6d40014705c9a079ad16e1cfbae4a040be41
parentbfbc3ad9dfc28552739737eb87f09552732c0e95 (diff)
downloadperl-bb38a9e0f528ce1ecffe4f8c3c76984148803932.tar.gz
Flag ops that are on the savestack
This is to allow future commits to free dangling ops after errors. If an op is on the savestack, then it is going to be freed by scope.c, and op_free must not be called on it by anyone else. So we flag such ops new.
-rw-r--r--op.h6
-rw-r--r--scope.h16
2 files changed, 19 insertions, 3 deletions
diff --git a/op.h b/op.h
index 7be9bf5ce7..7e20c70fe6 100644
--- a/op.h
+++ b/op.h
@@ -28,8 +28,9 @@
* the op may be safely op_free()d multiple times
* op_latefreed an op_latefree op has been op_free()d
* op_attached this op (sub)tree has been attached to a CV
+ * op_savefree on savestack via SAVEFREEOP
*
- * op_spare three spare bits!
+ * op_spare two spare bits!
* op_flags Flags common to all operations. See OPf_* below.
* op_private Flags peculiar to a particular operation (BUT,
* by default, set to the number of children until
@@ -62,7 +63,8 @@ typedef PERL_BITFIELD16 Optype;
PERL_BITFIELD16 op_latefree:1; \
PERL_BITFIELD16 op_latefreed:1; \
PERL_BITFIELD16 op_attached:1; \
- PERL_BITFIELD16 op_spare:3; \
+ PERL_BITFIELD16 op_savefree:1; \
+ PERL_BITFIELD16 op_spare:2; \
U8 op_flags; \
U8 op_private;
#endif
diff --git a/scope.h b/scope.h
index 74ebed9e65..f8df5b4354 100644
--- a/scope.h
+++ b/scope.h
@@ -269,7 +269,21 @@ scope has the given name. Name must be a literal string.
#define save_freesv(op) save_pushptr((void *)(op), SAVEt_FREESV)
#define save_mortalizesv(op) save_pushptr((void *)(op), SAVEt_MORTALIZESV)
-#define save_freeop(op) save_pushptr((void *)(op), SAVEt_FREEOP)
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+# define save_freeop(op) \
+ ({ \
+ OP * const _o = (OP *)(op); \
+ _o->op_savefree = 1; \
+ save_pushptr((void *)(_o), SAVEt_FREEOP); \
+ })
+#else
+# define save_freeop(op) \
+ ( \
+ PL_Xpv = (XPV *)(op), \
+ ((OP *)PL_Xpv)->op_savefree = 1, \
+ save_pushptr((void *)(PL_Xpv), SAVEt_FREEOP) \
+ )
+#endif
#define save_freepv(pv) save_pushptr((void *)(pv), SAVEt_FREEPV)
#define save_op() save_pushptr((void *)(PL_op), SAVEt_OP)