summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/XS-APItest/APItest.xs2
-rw-r--r--op.c40
-rw-r--r--op.h15
-rw-r--r--pod/perlguts.pod18
-rw-r--r--pod/perlhacktips.pod2
5 files changed, 44 insertions, 33 deletions
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 6171e9b3a5..c78dc7b50a 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -3677,7 +3677,7 @@ CODE:
CvROOT(PL_compcv) = (OP *)1;
o = newFOROP(0, 0, newOP(OP_PUSHMARK, 0), 0, 0);
#ifdef PERL_OP_PARENT
- if (cLOOPx(cUNOPo->op_first)->op_last->op_sibling
+ if (cLOOPx(cUNOPo->op_first)->op_last->op_sibparent
!= cUNOPo->op_first)
{
Perl_warn(aTHX_ "Op parent pointer is stale");
diff --git a/op.c b/op.c
index f912dd91db..4a920da5c8 100644
--- a/op.c
+++ b/op.c
@@ -297,10 +297,10 @@ Perl_Slab_Alloc(pTHX_ size_t sz)
DEBUG_S_warn((aTHX_ "allocating op at %p, slab %p", (void*)o, (void*)slab));
gotit:
- /* lastsib == 1, op_sibling == 0 implies a solitary unattached op */
+ /* lastsib == 1, op_sibparent == 0 implies a solitary unattached op */
o->op_lastsib = 1;
#ifdef PERL_OP_PARENT
- assert(!o->op_sibling);
+ assert(!o->op_sibparent);
#endif
return (void *)o;
@@ -1216,7 +1216,7 @@ you to delete zero or more sequential nodes, replacing them with zero or
more different nodes. Performs the necessary op_first/op_last
housekeeping on the parent node and op_sibling manipulation on the
children. The last deleted node will be marked as as the last node by
-updating the op_sibling or op_lastsib field as appropriate.
+updating the op_sibling/op_sibparent or op_lastsib field as appropriate.
Note that op_next is not manipulated, and nodes are not freed; that is the
responsibility of the caller. It also won't create a new list op for an
@@ -1328,7 +1328,7 @@ Perl_op_sibling_splice(OP *parent, OP *start, int del_count, OP* insert)
if (lastop) {
lastop->op_lastsib = 1;
#ifdef PERL_OP_PARENT
- lastop->op_sibling = parent;
+ lastop->op_sibparent = parent;
#endif
}
}
@@ -1352,7 +1352,7 @@ Perl_op_parent(OP *o)
#ifdef PERL_OP_PARENT
while (OpHAS_SIBLING(o))
o = OpSIBLING(o);
- return o->op_sibling;
+ return o->op_sibparent;
#else
PERL_UNUSED_ARG(o);
return NULL;
@@ -1413,7 +1413,7 @@ S_alloc_LOGOP(pTHX_ I32 type, OP *first, OP* other)
if (kid) {
kid->op_lastsib = 1;
#ifdef PERL_OP_PARENT
- kid->op_sibling = (OP*)logop;
+ kid->op_sibparent = (OP*)logop;
#endif
}
return logop;
@@ -2512,9 +2512,9 @@ S_finalize_op(pTHX_ OP* o)
#ifdef DEBUGGING
/* check that op_last points to the last sibling, and that
- * the last op_sibling field points back to the parent, and
- * that the only ops with KIDS are those which are entitled to
- * them */
+ * the last op_sibling/op_sibparent field points back to the
+ * parent, and that the only ops with KIDS are those which are
+ * entitled to them */
U32 type = o->op_type;
U32 family;
bool has_last;
@@ -2553,7 +2553,7 @@ S_finalize_op(pTHX_ OP* o)
if (!OpHAS_SIBLING(kid)) {
if (has_last)
assert(kid == cLISTOPo->op_last);
- assert(kid->op_sibling == o);
+ assert(kid->op_sibparent == o);
}
# else
if (has_last && !OpHAS_SIBLING(kid))
@@ -4503,7 +4503,7 @@ Perl_op_append_list(pTHX_ I32 type, OP *first, OP *last)
((LISTOP*)first)->op_last = ((LISTOP*)last)->op_last;
((LISTOP*)first)->op_last->op_lastsib = 1;
#ifdef PERL_OP_PARENT
- ((LISTOP*)first)->op_last->op_sibling = first;
+ ((LISTOP*)first)->op_last->op_sibparent = first;
#endif
first->op_flags |= (last->op_flags & OPf_KIDS);
@@ -4710,7 +4710,7 @@ Perl_newLISTOP(pTHX_ I32 type, I32 flags, OP *first, OP *last)
if (listop->op_last) {
listop->op_last->op_lastsib = 1;
#ifdef PERL_OP_PARENT
- listop->op_last->op_sibling = (OP*)listop;
+ listop->op_last->op_sibparent = (OP*)listop;
#endif
}
@@ -4804,7 +4804,7 @@ Perl_newUNOP(pTHX_ I32 type, I32 flags, OP *first)
#ifdef PERL_OP_PARENT
if (!OpHAS_SIBLING(first)) /* true unless weird syntax error */
- first->op_sibling = (OP*)unop;
+ first->op_sibparent = (OP*)unop;
#endif
unop = (UNOP*) CHECKOP(type, unop);
@@ -4842,7 +4842,7 @@ Perl_newUNOP_AUX(pTHX_ I32 type, I32 flags, OP *first, UNOP_AUX_item *aux)
#ifdef PERL_OP_PARENT
if (first && !OpHAS_SIBLING(first)) /* true unless weird syntax error */
- first->op_sibling = (OP*)unop;
+ first->op_sibparent = (OP*)unop;
#endif
unop = (UNOP_AUX*) CHECKOP(type, unop);
@@ -4882,7 +4882,7 @@ S_newMETHOP_internal(pTHX_ I32 type, I32 flags, OP* dynamic_meth, SV* const_meth
#ifdef PERL_OP_PARENT
if (!OpHAS_SIBLING(dynamic_meth))
- dynamic_meth->op_sibling = (OP*)methop;
+ dynamic_meth->op_sibparent = (OP*)methop;
#endif
}
else {
@@ -4971,13 +4971,13 @@ Perl_newBINOP(pTHX_ I32 type, I32 flags, OP *first, OP *last)
#ifdef PERL_OP_PARENT
if (!OpHAS_SIBLING(last)) /* true unless weird syntax error */
- last->op_sibling = (OP*)binop;
+ last->op_sibparent = (OP*)binop;
#endif
binop->op_last = OpSIBLING(binop->op_first);
#ifdef PERL_OP_PARENT
if (binop->op_last)
- binop->op_last->op_sibling = (OP*)binop;
+ binop->op_last->op_sibparent = (OP*)binop;
#endif
binop = (BINOP*)CHECKOP(type, binop);
@@ -7516,8 +7516,8 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
NewOp(1234,tmp,1,LOOP);
Copy(loop,tmp,1,LISTOP);
#ifdef PERL_OP_PARENT
- assert(loop->op_last->op_sibling == (OP*)loop);
- loop->op_last->op_sibling = (OP*)tmp; /*point back to new parent */
+ assert(loop->op_last->op_sibparent == (OP*)loop);
+ loop->op_last->op_sibparent = (OP*)tmp; /*point back to new parent */
#endif
S_op_destroy(aTHX_ (OP*)loop);
loop = tmp;
@@ -7526,7 +7526,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
{
loop = (LOOP*)PerlMemShared_realloc(loop, sizeof(LOOP));
#ifdef PERL_OP_PARENT
- loop->op_last->op_sibling = (OP *)loop;
+ loop->op_last->op_sibparent = (OP *)loop;
#endif
}
loop->op_targ = padoff;
diff --git a/op.h b/op.h
index 9e6bb43e1d..4eede91f14 100644
--- a/op.h
+++ b/op.h
@@ -38,12 +38,21 @@
typedef PERL_BITFIELD16 Optype;
+/* this field now either points to the next sibling or to the parent,
+ * depending on op_lastsib. So rename it from op_sibling to op_sibparent.
+ */
+#ifdef PERL_OP_PARENT
+# define _OP_SIBPARENT_FIELDNAME op_sibparent
+#else
+# define _OP_SIBPARENT_FIELDNAME op_sibling
+#endif
+
#ifdef BASEOP_DEFINITION
#define BASEOP BASEOP_DEFINITION
#else
#define BASEOP \
OP* op_next; \
- OP* op_sibling; \
+ OP* _OP_SIBPARENT_FIELDNAME;\
OP* (*op_ppaddr)(pTHX); \
PADOFFSET op_targ; \
PERL_BITFIELD16 op_type:9; \
@@ -973,8 +982,8 @@ Sets the sibling of o to sib
#ifdef PERL_OP_PARENT
# define OpHAS_SIBLING(o) (!cBOOL((o)->op_lastsib))
-# define OpSIBLING(o) (0 + (o)->op_lastsib ? NULL : (o)->op_sibling)
-# define OpSIBLING_set(o, sib) ((o)->op_sibling = (sib))
+# define OpSIBLING(o) (0 + (o)->op_lastsib ? NULL : (o)->op_sibparent)
+# define OpSIBLING_set(o, sib) ((o)->op_sibparent = (sib))
#else
# define OpHAS_SIBLING(o) (cBOOL((o)->op_sibling))
# define OpSIBLING(o) (0 + (o)->op_sibling)
diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 5e38692c89..4266cfa4d9 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -1980,7 +1980,7 @@ C<op_first> field but also an C<op_last> field. The most complex type of
op is a C<LISTOP>, which has any number of children. In this case, the
first child is pointed to by C<op_first> and the last child by
C<op_last>. The children in between can be found by iteratively
-following the C<op_sibling> pointer from the first child to the last (but
+following the C<OpSIBLING> pointer from the first child to the last (but
see below).
There are also some other op types: a C<PMOP> holds a regular expression,
@@ -1992,7 +1992,7 @@ have children in accordance with its former type.
Finally, there is a C<LOGOP>, or logic op. Like a C<LISTOP>, this has one
or more children, but it doesn't have an C<op_last> field: so you have to
-follow C<op_first> and then the C<op_sibling> chain itself to find the
+follow C<op_first> and then the C<OpSIBLING> chain itself to find the
last child. Instead it has an C<op_other> field, which is comparable to
the C<op_next> field described below, and represents an alternate
execution path. Operators like C<and>, C<or> and C<?> are C<LOGOP>s. Note
@@ -2002,12 +2002,14 @@ of the C<LOGOP>.
Starting in version 5.21.2, perls built with the experimental
define C<-DPERL_OP_PARENT> add an extra boolean flag for each op,
C<op_lastsib>. When set, this indicates that this is the last op in an
-C<op_sibling> chain. This frees up the C<op_sibling> field on the last
-sibling to point back to the parent op. The macro C<OpSIBLING(o)> wraps
-this special behaviour, and always returns NULL on the last sibling.
-With this build the C<op_parent(o)> function can be used to find the
-parent of any op. Thus for forward compatibility, you should always use
-the C<OpSIBLING(o)> macro rather than accessing C<op_sibling> directly.
+C<OpSIBLING> chain. This frees up the C<op_sibling> field on the last
+sibling to point back to the parent op. Under this build, that field is
+also renamed C<op_sibparent> to reflect its joint role. The macro
+C<OpSIBLING(o)> wraps this special behaviour, and always returns NULL on
+the last sibling. With this build the C<op_parent(o)> function can be
+used to find the parent of any op. Thus for forward compatibility, you
+should always use the C<OpSIBLING(o)> macro rather than accessing
+C<op_sibling> directly.
Another way to examine the tree is to use a compiler back-end module, such
as L<B::Concise>.
diff --git a/pod/perlhacktips.pod b/pod/perlhacktips.pod
index 834c8c8766..6d7a098a60 100644
--- a/pod/perlhacktips.pod
+++ b/pod/perlhacktips.pod
@@ -803,7 +803,7 @@ Prints the C definition of the argument given.
(gdb) ptype PL_op
type = struct op {
OP *op_next;
- OP *op_sibling;
+ OP *op_sibparent;
OP *(*op_ppaddr)(void);
PADOFFSET op_targ;
unsigned int op_type : 9;