summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-03-26 16:33:35 -0700
committerGitHub <noreply@github.com>2020-03-26 16:33:35 -0700
commit9101f65c7b18ab607c472a3d50b52db66497402f (patch)
tree9ffa1174a01162e750966ba39e7a3ca86c2e18ec /src
parentce6ae49863d7d2da54aabf9637ee299659f4bd0c (diff)
downloadbinaryen-9101f65c7b18ab607c472a3d50b52db66497402f.tar.gz
binaryen-9101f65c7b18ab607c472a3d50b52db66497402f.tar.bz2
binaryen-9101f65c7b18ab607c472a3d50b52db66497402f.zip
Tuple operations in C and JS APIs (#2711)
Adds functions for creating and inspecting tuple.make and tuple.extract expressions in the C and JS APIs.
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp196
-rw-r--r--src/binaryen-c.h18
-rw-r--r--src/js/binaryen.js-post.js26
3 files changed, 174 insertions, 66 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 97565688a..84612d0e4 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -264,6 +264,31 @@ void traceExpression(BinaryenExpressionRef expr,
}
}
+template<typename F>
+void traceWithExpressionArray(const char* name,
+ BinaryenExpressionRef* exprs,
+ BinaryenIndex numExprs,
+ F body) {
+ std::cout << " {\n";
+ std::cout << " BinaryenExpressionRef " << name << "[] = { ";
+ for (BinaryenIndex i = 0; i < numExprs; i++) {
+ if (i > 0) {
+ std::cout << ", ";
+ }
+ if (i % 6 == 5) {
+ std::cout << "\n "; // don't create hugely long lines
+ }
+ std::cout << "expressions[" << expressions[exprs[i]] << "]";
+ }
+ if (numExprs == 0) {
+ // ensure the array is not empty, otherwise a compiler error on VS
+ std::cout << "0";
+ }
+ std::cout << " };\n ";
+ body();
+ std::cout << " }\n";
+}
+
extern "C" {
//
@@ -429,6 +454,12 @@ BinaryenExpressionId BinaryenRethrowId(void) {
BinaryenExpressionId BinaryenBrOnExnId(void) {
return Expression::Id::BrOnExnId;
}
+BinaryenExpressionId BinaryenTupleMakeId(void) {
+ return Expression::Id::TupleMakeId;
+}
+BinaryenExpressionId BinaryenTupleExtractId(void) {
+ return Expression::Id::TupleExtractId;
+}
BinaryenExpressionId BinaryenPushId(void) { return Expression::Id::PushId; }
BinaryenExpressionId BinaryenPopId(void) { return Expression::Id::PopId; }
@@ -981,25 +1012,10 @@ BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module,
}
if (tracing) {
- std::cout << " {\n";
- std::cout << " BinaryenExpressionRef children[] = { ";
- for (BinaryenIndex i = 0; i < numChildren; i++) {
- if (i > 0) {
- std::cout << ", ";
- }
- if (i % 6 == 5) {
- std::cout << "\n "; // don't create hugely long lines
- }
- std::cout << "expressions[" << expressions[children[i]] << "]";
- }
- if (numChildren == 0) {
- // ensure the array is not empty, otherwise a compiler error on VS
- std::cout << "0";
- }
- std::cout << " };\n ";
- traceExpression(
- ret, "BinaryenBlock", StringLit(name), "children", numChildren, type);
- std::cout << " }\n";
+ traceWithExpressionArray("children", children, numChildren, [&]() {
+ traceExpression(
+ ret, "BinaryenBlock", StringLit(name), "children", numChildren, type);
+ });
}
return static_cast<Expression*>(ret);
@@ -1095,26 +1111,14 @@ static BinaryenExpressionRef makeBinaryenCall(BinaryenModuleRef module,
auto* ret = ((Module*)module)->allocator.alloc<Call>();
if (tracing) {
- std::cout << " {\n";
- std::cout << " BinaryenExpressionRef operands[] = { ";
- for (BinaryenIndex i = 0; i < numOperands; i++) {
- if (i > 0) {
- std::cout << ", ";
- }
- std::cout << "expressions[" << expressions[operands[i]] << "]";
- }
- if (numOperands == 0) {
- // ensure the array is not empty, otherwise a compiler error on VS
- std::cout << "0";
- }
- std::cout << " };\n ";
- traceExpression(ret,
- (isReturn ? "BinaryenReturnCall" : "BinaryenCall"),
- StringLit(target),
- "operands",
- numOperands,
- returnType);
- std::cout << " }\n";
+ traceWithExpressionArray("operands", operands, numOperands, [&]() {
+ traceExpression(ret,
+ (isReturn ? "BinaryenReturnCall" : "BinaryenCall"),
+ StringLit(target),
+ "operands",
+ numOperands,
+ returnType);
+ });
}
ret->target = target;
@@ -1717,6 +1721,35 @@ BinaryenExpressionRef BinaryenMemoryFill(BinaryenModuleRef module,
}
return static_cast<Expression*>(ret);
}
+
+BinaryenExpressionRef BinaryenTupleMake(BinaryenModuleRef module,
+ BinaryenExpressionRef* operands,
+ BinaryenIndex numOperands) {
+ std::vector<Expression*> ops;
+ ops.resize(numOperands);
+ for (size_t i = 0; i < numOperands; ++i) {
+ ops[i] = (Expression*)operands[i];
+ }
+ auto* ret = Builder(*(Module*)module).makeTupleMake(ops);
+ if (tracing) {
+ traceWithExpressionArray("operands", operands, numOperands, [&]() {
+ traceExpression(ret, "BinaryenTupleMake", "operands", numOperands);
+ });
+ }
+ return static_cast<Expression*>(ret);
+}
+
+BinaryenExpressionRef BinaryenTupleExtract(BinaryenModuleRef module,
+ BinaryenExpressionRef tuple,
+ BinaryenIndex index) {
+ auto* ret =
+ Builder(*(Module*)module).makeTupleExtract((Expression*)tuple, index);
+ if (tracing) {
+ traceExpression(ret, "BinaryenTupleExtract", tuple, index);
+ }
+ return ret;
+}
+
BinaryenExpressionRef BinaryenPush(BinaryenModuleRef module,
BinaryenExpressionRef value) {
auto* ret = Builder(*(Module*)module).makePush((Expression*)value);
@@ -1781,22 +1814,10 @@ BinaryenExpressionRef BinaryenThrow(BinaryenModuleRef module,
auto* ret = Builder(*(Module*)module).makeThrow(event, args);
if (tracing) {
- std::cout << " {\n";
- std::cout << " BinaryenExpressionRef operands[] = { ";
- for (BinaryenIndex i = 0; i < numOperands; i++) {
- if (i > 0) {
- std::cout << ", ";
- }
- std::cout << "expressions[" << expressions[operands[i]] << "]";
- }
- if (numOperands == 0) {
- // ensure the array is not empty, otherwise a compiler error on VS
- std::cout << "0";
- }
- std::cout << " };\n ";
- traceExpression(
- ret, "BinaryenThrow", StringLit(event), "operands", numOperands);
- std::cout << " }\n";
+ traceWithExpressionArray("operands", operands, numOperands, [&]() {
+ traceExpression(
+ ret, "BinaryenThrow", StringLit(event), "operands", numOperands);
+ });
}
return static_cast<Expression*>(ret);
}
@@ -3017,17 +3038,6 @@ BinaryenExpressionRef BinaryenMemoryFillGetSize(BinaryenExpressionRef expr) {
assert(expression->is<MemoryFill>());
return static_cast<MemoryFill*>(expression)->size;
}
-// Push
-BinaryenExpressionRef BinaryenPushGetValue(BinaryenExpressionRef expr) {
- if (tracing) {
- std::cout << " BinaryenPushGetValue(expressions[" << expressions[expr]
- << "]);\n";
- }
-
- auto* expression = (Expression*)expr;
- assert(expression->is<Push>());
- return static_cast<Push*>(expression)->value;
-}
// RefIsNull
BinaryenExpressionRef BinaryenRefIsNullGetValue(BinaryenExpressionRef expr) {
if (tracing) {
@@ -3146,6 +3156,60 @@ BinaryenExpressionRef BinaryenBrOnExnGetExnref(BinaryenExpressionRef expr) {
assert(expression->is<BrOnExn>());
return static_cast<BrOnExn*>(expression)->exnref;
}
+// TupleMake
+BinaryenIndex BinaryenTupleMakeGetNumOperands(BinaryenExpressionRef expr) {
+ if (tracing) {
+ std::cout << " BinaryenTupleMakeGetNumOperands(expressions["
+ << expressions[expr] << "]);\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<TupleMake>());
+ return static_cast<TupleMake*>(expression)->operands.size();
+}
+BinaryenExpressionRef BinaryenTupleMakeGetOperand(BinaryenExpressionRef expr,
+ BinaryenIndex index) {
+ if (tracing) {
+ std::cout << " BinaryenTupleMakeGetOperand(expressions["
+ << expressions[expr] << "], " << index << ");\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<TupleMake>());
+ return static_cast<TupleMake*>(expression)->operands[index];
+}
+// TupleExtract
+BinaryenExpressionRef BinaryenTupleExtractGetTuple(BinaryenExpressionRef expr) {
+ if (tracing) {
+ std::cout << " BinaryenTupleExtractGetTuple(expressions["
+ << expressions[expr] << "]);\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<TupleExtract>());
+ return static_cast<TupleExtract*>(expression)->tuple;
+}
+BinaryenIndex BinaryenTupleExtractGetIndex(BinaryenExpressionRef expr) {
+ if (tracing) {
+ std::cout << " BinaryenTupleExtractGetIndex(expressions["
+ << expressions[expr] << "]);\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<TupleExtract>());
+ return static_cast<TupleExtract*>(expression)->index;
+}
+// Push
+BinaryenExpressionRef BinaryenPushGetValue(BinaryenExpressionRef expr) {
+ if (tracing) {
+ std::cout << " BinaryenPushGetValue(expressions[" << expressions[expr]
+ << "]);\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<Push>());
+ return static_cast<Push*>(expression)->value;
+}
// Functions
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index b820bbdcb..33faab45d 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -167,6 +167,8 @@ BINARYEN_API BinaryenExpressionId BinaryenTryId(void);
BINARYEN_API BinaryenExpressionId BinaryenThrowId(void);
BINARYEN_API BinaryenExpressionId BinaryenRethrowId(void);
BINARYEN_API BinaryenExpressionId BinaryenBrOnExnId(void);
+BINARYEN_API BinaryenExpressionId BinaryenTupleMakeId(void);
+BINARYEN_API BinaryenExpressionId BinaryenTupleExtractId(void);
BINARYEN_API BinaryenExpressionId BinaryenPushId(void);
BINARYEN_API BinaryenExpressionId BinaryenPopId(void);
@@ -831,6 +833,12 @@ BinaryenBrOnExn(BinaryenModuleRef module,
const char* name,
const char* eventName,
BinaryenExpressionRef exnref);
+BINARYEN_API BinaryenExpressionRef
+BinaryenTupleMake(BinaryenModuleRef module,
+ BinaryenExpressionRef* operands,
+ BinaryenIndex numOperands);
+BINARYEN_API BinaryenExpressionRef BinaryenTupleExtract(
+ BinaryenModuleRef module, BinaryenExpressionRef tuple, BinaryenIndex index);
BINARYEN_API BinaryenExpressionRef BinaryenPush(BinaryenModuleRef module,
BinaryenExpressionRef value);
BINARYEN_API BinaryenExpressionRef BinaryenPop(BinaryenModuleRef module,
@@ -1078,6 +1086,16 @@ BINARYEN_API const char* BinaryenBrOnExnGetName(BinaryenExpressionRef expr);
BINARYEN_API BinaryenExpressionRef
BinaryenBrOnExnGetExnref(BinaryenExpressionRef expr);
+BINARYEN_API BinaryenIndex
+BinaryenTupleMakeGetNumOperands(BinaryenExpressionRef expr);
+BINARYEN_API BinaryenExpressionRef
+BinaryenTupleMakeGetOperand(BinaryenExpressionRef expr, BinaryenIndex index);
+
+BINARYEN_API BinaryenExpressionRef
+BinaryenTupleExtractGetTuple(BinaryenExpressionRef expr);
+BINARYEN_API BinaryenIndex
+BinaryenTupleExtractGetIndex(BinaryenExpressionRef expr);
+
BINARYEN_API BinaryenExpressionRef
BinaryenPushGetValue(BinaryenExpressionRef expr);
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 49b02d336..44dc7174b 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -95,6 +95,8 @@ function initializeConstants() {
'Throw',
'Rethrow',
'BrOnExn',
+ 'TupleMake',
+ 'TupleExtract',
'Push',
'Pop'
].forEach(function(name) {
@@ -2091,6 +2093,17 @@ function wrapModule(module, self) {
return Module['_BinaryenPush'](module, value);
};
+ self['tuple'] = {
+ 'make': function(elements) {
+ return preserveStack(function() {
+ return Module['_BinaryenTupleMake'](module, i32sToStack(elements), elements.length);
+ });
+ },
+ 'extract': function(tuple, index) {
+ return Module['_BinaryenTupleExtract'](module, tuple, index);
+ }
+ };
+
// 'Module' operations
self['addFunction'] = function(name, params, results, varTypes, body) {
return preserveStack(function() {
@@ -2790,6 +2803,19 @@ Module['getExpressionInfo'] = function(expr) {
'event': UTF8ToString(Module['_BinaryenBrOnExnGetEvent'](expr)),
'exnref': Module['_BinaryenBrOnExnGetExnref'](expr)
};
+ case Module['TupleMakeId']:
+ return {
+ 'id': id,
+ 'type': type,
+ 'operands': getAllNested(expr, Module['_BinaryenTupleMakeGetNumOperands'], Module['_BinaryenTupleMakeGetOperand'])
+ };
+ case Module['TupleExtractId']:
+ return {
+ 'id': id,
+ 'type': type,
+ 'tuple': Module['_BinaryenTupleExtractGetTuple'](expr),
+ 'index': Module['_BinaryenTupleExtractGetIndex'](expr)
+ };
case Module['PushId']:
return {
'id': id,