summaryrefslogtreecommitdiff
path: root/ext/B/B.xs
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-10-27 17:33:32 +0000
committerDavid Mitchell <davem@iabyn.com>2014-12-07 09:07:30 +0000
commit2f7c6295c991839e20b09fbf3107b861d511de31 (patch)
tree0fdd9d2c00a5c76657a8f6b8a51612b0dd86fef7 /ext/B/B.xs
parenta644a388ed31c256984f12dd1869bbc141de76e5 (diff)
downloadperl-2f7c6295c991839e20b09fbf3107b861d511de31.tar.gz
add UNOP_AUX OP class
This is the same as a UNOP, but with the addition of an op_aux field, which points to an array of UNOP_AUX_item unions. It is intended as a general escape mechanism for adding per-op-type extra fields (or arrays of items) to UNOPs. Its class character (for regen/opcodes etc) is '+'. Currently there are no ops of this type; but shortly, OP_MULTIDEREF will be added, which is the original motivation for this new op type.
Diffstat (limited to 'ext/B/B.xs')
-rw-r--r--ext/B/B.xs55
1 files changed, 52 insertions, 3 deletions
diff --git a/ext/B/B.xs b/ext/B/B.xs
index da05cc18f2..937ef2c43f 100644
--- a/ext/B/B.xs
+++ b/ext/B/B.xs
@@ -61,7 +61,8 @@ typedef enum {
OPc_PVOP, /* 9 */
OPc_LOOP, /* 10 */
OPc_COP, /* 11 */
- OPc_METHOP /* 12 */
+ OPc_METHOP, /* 12 */
+ OPc_UNOP_AUX /* 13 */
} opclass;
static const char* const opclassnames[] = {
@@ -77,7 +78,8 @@ static const char* const opclassnames[] = {
"B::PVOP",
"B::LOOP",
"B::COP",
- "B::METHOP"
+ "B::METHOP",
+ "B::UNOP_AUX"
};
static const size_t opsizes[] = {
@@ -93,7 +95,8 @@ static const size_t opsizes[] = {
sizeof(PVOP),
sizeof(LOOP),
sizeof(COP),
- sizeof(METHOP)
+ sizeof(METHOP),
+ sizeof(UNOP_AUX),
};
#define MY_CXT_KEY "B::_guts" XS_VERSION
@@ -240,6 +243,8 @@ cc_opclass(pTHX_ const OP *o)
return OPc_PVOP;
case OA_METHOP:
return OPc_METHOP;
+ case OA_UNOP_AUX:
+ return OPc_UNOP_AUX;
}
warn("can't determine class of operator %s, assuming BASEOP\n",
OP_NAME(o));
@@ -1317,6 +1322,50 @@ oplist(o)
SP = oplist(aTHX_ o, SP);
+
+MODULE = B PACKAGE = B::UNOP_AUX
+
+# UNOP_AUX class ops are like UNOPs except that they have an extra
+# op_aux pointer that points to an array of UNOP_AUX_item unions.
+# Element -1 of the array contains the length
+
+
+# return a string representation of op_aux where possible The op's CV is
+# needed as an extra arg to allow GVs and SVs moved into the pad to be
+# accessed okay.
+
+void
+string(o, cv)
+ B::OP o
+ B::CV cv
+ PREINIT:
+ SV *ret;
+ PPCODE:
+ switch (o->op_type) {
+ default:
+ ret = sv_2mortal(newSVpvn("", 0));
+ }
+ ST(0) = ret;
+ XSRETURN(1);
+
+
+# Return the contents of the op_aux array as a list of IV/GV/etc objects.
+# How to interpret each array element is op-dependent. The op's CV is
+# needed as an extra arg to allow GVs and SVs which have been moved into
+# the pad to be accessed okay.
+
+void
+aux_list(o, cv)
+ B::OP o
+ B::CV cv
+ PPCODE:
+ switch (o->op_type) {
+ default:
+ XSRETURN(0); /* by default, an empty list */
+ } /* switch */
+
+
+
MODULE = B PACKAGE = B::SV
#define MAGICAL_FLAG_BITS (SVs_GMG|SVs_SMG|SVs_RMG)