summaryrefslogtreecommitdiff
path: root/ext/arybase
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-06-16 14:34:14 +0100
committerDavid Mitchell <davem@iabyn.com>2014-07-08 16:40:03 +0100
commit3253bf854af27f38b67fb3a8dfeee758885f3ae9 (patch)
tree9aac72f516a0892094fdcfda8f56b9cdbd7e1bbd /ext/arybase
parente864b323d8621840aac1fda03b2bf69dba6336ff (diff)
downloadperl-3253bf854af27f38b67fb3a8dfeee758885f3ae9.tar.gz
add op_sibling_splice() fn and make core use it
The op_sibling_splice() is a new general-purpose OP manipulation function designed to edit the children of an op, in an analogous manner in which the perl splice() function manipulates arrays. This commit also edits op.c and a few other places to remove most direct manipulation of op_sibling, op_first and op_last, and replace that with calls to op_sibling_splice(). This has two advantages. First, by using the one function consistently throughout, it makes it clearer what a particular piece of of code is doing, rather than having to decipher lots of of ad-hoc cLISTOPo->op_first = OP_SIBLING(kid); style stuff. Second, it will make it easier to later add a facility for child OPs to find their parent, since the changes now only need to be made in a few places. In theory this commit should make no functional change to the code.
Diffstat (limited to 'ext/arybase')
-rw-r--r--ext/arybase/arybase.xs13
1 files changed, 10 insertions, 3 deletions
diff --git a/ext/arybase/arybase.xs b/ext/arybase/arybase.xs
index 48358b564a..a44233dc2c 100644
--- a/ext/arybase/arybase.xs
+++ b/ext/arybase/arybase.xs
@@ -156,7 +156,8 @@ STATIC void ab_neuter_dollar_bracket(pTHX_ OP *o) {
oldc = cUNOPx(o)->op_first;
newc = newGVOP(OP_GV, 0,
gv_fetchpvs("arybase::leftbrack", GV_ADDMULTI, SVt_PVGV));
- cUNOPx(o)->op_first = newc;
+ /* replace oldc with newc */
+ op_sibling_splice(o, NULL, 1, newc);
op_free(oldc);
}
@@ -378,8 +379,14 @@ static OP *ab_ck_base(pTHX_ OP *o)
/* Break the aelemfast optimisation */
if (o->op_type == OP_AELEM) {
OP *const first = cBINOPo->op_first;
- if ( OP_SIBLING(first)->op_type == OP_CONST) {
- OP_SIBLING_set(first, newUNOP(OP_NULL,0,OP_SIBLING(first)));
+ OP *second = OP_SIBLING(first);
+ OP *newop;
+ if (second->op_type == OP_CONST) {
+ /* cut out second arg and replace it with a new unop which is
+ * the parent of that arg */
+ op_sibling_splice(o, first, 1, NULL);
+ newop = newUNOP(OP_NULL,0,second);
+ op_sibling_splice(o, first, 0, newop);
}
}
}