diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-03-26 16:33:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-26 16:33:35 -0700 |
commit | 9101f65c7b18ab607c472a3d50b52db66497402f (patch) | |
tree | 9ffa1174a01162e750966ba39e7a3ca86c2e18ec /src | |
parent | ce6ae49863d7d2da54aabf9637ee299659f4bd0c (diff) | |
download | binaryen-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.cpp | 196 | ||||
-rw-r--r-- | src/binaryen-c.h | 18 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 26 |
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, |