From 91ec8d530b7933f9701720fb4384ad8e3be30415 Mon Sep 17 00:00:00 2001 From: dcode Date: Fri, 8 May 2020 12:32:45 +0200 Subject: [PATCH 1/3] Add C/JS APIs to copy expressions --- src/binaryen-c.cpp | 13 +++++++++ src/binaryen-c.h | 2 ++ src/js/binaryen.js-post.js | 3 ++ test/binaryen.js/copy-expression.js | 28 +++++++++++++++++++ test/binaryen.js/copy-expression.js.txt | 37 +++++++++++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 test/binaryen.js/copy-expression.js create mode 100644 test/binaryen.js/copy-expression.js.txt diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index a9bc9e2b6c9..95a536badd3 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1962,6 +1962,19 @@ void BinaryenExpressionPrint(BinaryenExpressionRef expr) { std::cout << '\n'; } +BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, + BinaryenModuleRef module) { + auto* wasm = (Module*)module; + auto* ret = ExpressionManipulator::copy(expr, *wasm); + if (tracing) { + auto id = noteExpression(ret); + std::cout << " expressions[" << id + << "] = BinaryenExpressionCopy(expressions[" << expressions[expr] + << "], theModule);\n"; + } + return ret; +} + // Specific expression utility // Block diff --git a/src/binaryen-c.h b/src/binaryen-c.h index b8cd3c37d2e..b9a534a7591 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -848,6 +848,8 @@ BINARYEN_API BinaryenExpressionId BinaryenExpressionGetId(BinaryenExpressionRef expr); BINARYEN_API BinaryenType BinaryenExpressionGetType(BinaryenExpressionRef expr); BINARYEN_API void BinaryenExpressionPrint(BinaryenExpressionRef expr); +BINARYEN_API BinaryenExpressionRef +BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module); BINARYEN_API const char* BinaryenBlockGetName(BinaryenExpressionRef expr); BINARYEN_API BinaryenIndex diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 3bc0fa4a370..9572cd8d073 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -2407,6 +2407,9 @@ function wrapModule(module, self) { self['setDebugLocation'] = function(func, expr, fileIndex, lineNumber, columnNumber) { return Module['_BinaryenFunctionSetDebugLocation'](func, expr, fileIndex, lineNumber, columnNumber); }; + self['copyExpression'] = function(expr) { + return Module['_BinaryenExpressionCopy'](expr, module); + }; return self; } diff --git a/test/binaryen.js/copy-expression.js b/test/binaryen.js/copy-expression.js new file mode 100644 index 00000000000..91041863f4f --- /dev/null +++ b/test/binaryen.js/copy-expression.js @@ -0,0 +1,28 @@ +binaryen.setAPITracing(true); + +var module = new binaryen.Module(); + +// Create an expression and copy it +var original = module.block(null, [ + module.if( + module.local.get(0, binaryen.i32), + module.i32.const(1), + module.i32.const(2) + ) +], binaryen.i32); +var copy = module.copyExpression(original); + +// Check that the expression incl. sub-expressions are copies +assert(original !== copy); +var originalIf = binaryen._BinaryenBlockGetChild(original, 0); +var copyIf = binaryen._BinaryenBlockGetChild(copy, 0); +assert(originalIf !== copyIf); +assert(binaryen._BinaryenIfGetCondition(originalIf) !== binaryen._BinaryenIfGetCondition(copyIf)); +assert(binaryen._BinaryenIfGetIfTrue(originalIf) !== binaryen._BinaryenIfGetIfTrue(copyIf)); +assert(binaryen._BinaryenIfGetIfFalse(originalIf) !== binaryen._BinaryenIfGetIfFalse(copyIf)); + +binaryen.setAPITracing(false); + +// Check that both are otherwise identical, but do it after tracing so +// emitText and tracing output don't conflict on stdout +assert(binaryen.emitText(original) === binaryen.emitText(copy)); diff --git a/test/binaryen.js/copy-expression.js.txt b/test/binaryen.js/copy-expression.js.txt new file mode 100644 index 00000000000..a96d86c996e --- /dev/null +++ b/test/binaryen.js/copy-expression.js.txt @@ -0,0 +1,37 @@ +// beginning a Binaryen API trace +#include +#include +#include "binaryen-c.h" +int main() { + std::map types; + std::map expressions; + std::map functions; + std::map globals; + std::map events; + std::map exports; + std::map relooperBlocks; + std::map expressionRunners; + BinaryenModuleRef the_module = NULL; + RelooperRef the_relooper = NULL; + the_module = BinaryenModuleCreate(); + expressions[size_t(NULL)] = BinaryenExpressionRef(NULL); + expressions[1] = BinaryenLocalGet(the_module, 0, BinaryenTypeInt32()); + expressions[2] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[3] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[4] = BinaryenIf(the_module, expressions[1], expressions[2], expressions[3]); + { + BinaryenExpressionRef children[] = { expressions[4] }; + expressions[5] = BinaryenBlock(the_module, NULL, children, 1, BinaryenTypeInt32()); + } + expressions[6] = BinaryenExpressionCopy(expressions[5], theModule); + BinaryenBlockGetChild(expressions[5], 0); + BinaryenBlockGetChild(expressions[6], 0); + BinaryenIfGetCondition(expressions[4]); + BinaryenIfGetCondition(expressions[0]); // this is bad + BinaryenIfGetIfTrue(expressions[4]); + BinaryenIfGetIfTrue(expressions[0]); // this is bad + BinaryenIfGetIfFalse(expressions[4]); + BinaryenIfGetIfFalse(expressions[0]); // this is bad + return 0; +} +// ending a Binaryen API trace From b2844ba7ea309bcd9f677701975c570aaaf32257 Mon Sep 17 00:00:00 2001 From: dcode Date: Fri, 8 May 2020 14:09:51 +0200 Subject: [PATCH 2/3] theModule -> the_module --- src/binaryen-c.cpp | 2 +- test/binaryen.js/copy-expression.js.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 95a536badd3..7b5c3771e6b 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1970,7 +1970,7 @@ BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, auto id = noteExpression(ret); std::cout << " expressions[" << id << "] = BinaryenExpressionCopy(expressions[" << expressions[expr] - << "], theModule);\n"; + << "], the_module);\n"; } return ret; } diff --git a/test/binaryen.js/copy-expression.js.txt b/test/binaryen.js/copy-expression.js.txt index a96d86c996e..2a0e40f3a4d 100644 --- a/test/binaryen.js/copy-expression.js.txt +++ b/test/binaryen.js/copy-expression.js.txt @@ -23,7 +23,7 @@ int main() { BinaryenExpressionRef children[] = { expressions[4] }; expressions[5] = BinaryenBlock(the_module, NULL, children, 1, BinaryenTypeInt32()); } - expressions[6] = BinaryenExpressionCopy(expressions[5], theModule); + expressions[6] = BinaryenExpressionCopy(expressions[5], the_module); BinaryenBlockGetChild(expressions[5], 0); BinaryenBlockGetChild(expressions[6], 0); BinaryenIfGetCondition(expressions[4]); From 73202b9059e3eeaafcf08f229123631d340618ff Mon Sep 17 00:00:00 2001 From: dcode Date: Sat, 9 May 2020 11:02:26 +0200 Subject: [PATCH 3/3] update --- src/binaryen-c.cpp | 10 +------ test/binaryen.js/copy-expression.js | 25 +++++++++-------- test/binaryen.js/copy-expression.js.txt | 37 ------------------------- 3 files changed, 15 insertions(+), 57 deletions(-) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index c39db2b008b..a64c46fbf19 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1321,15 +1321,7 @@ void BinaryenExpressionPrint(BinaryenExpressionRef expr) { BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module) { - auto* wasm = (Module*)module; - auto* ret = ExpressionManipulator::copy(expr, *wasm); - if (tracing) { - auto id = noteExpression(ret); - std::cout << " expressions[" << id - << "] = BinaryenExpressionCopy(expressions[" << expressions[expr] - << "], the_module);\n"; - } - return ret; + return ExpressionManipulator::copy(expr, *(Module*)module); } // Specific expression utility diff --git a/test/binaryen.js/copy-expression.js b/test/binaryen.js/copy-expression.js index 91041863f4f..261c028faba 100644 --- a/test/binaryen.js/copy-expression.js +++ b/test/binaryen.js/copy-expression.js @@ -1,5 +1,3 @@ -binaryen.setAPITracing(true); - var module = new binaryen.Module(); // Create an expression and copy it @@ -14,15 +12,20 @@ var copy = module.copyExpression(original); // Check that the expression incl. sub-expressions are copies assert(original !== copy); -var originalIf = binaryen._BinaryenBlockGetChild(original, 0); -var copyIf = binaryen._BinaryenBlockGetChild(copy, 0); -assert(originalIf !== copyIf); -assert(binaryen._BinaryenIfGetCondition(originalIf) !== binaryen._BinaryenIfGetCondition(copyIf)); -assert(binaryen._BinaryenIfGetIfTrue(originalIf) !== binaryen._BinaryenIfGetIfTrue(copyIf)); -assert(binaryen._BinaryenIfGetIfFalse(originalIf) !== binaryen._BinaryenIfGetIfFalse(copyIf)); -binaryen.setAPITracing(false); +var originalInfo = binaryen.getExpressionInfo(original); +assert(originalInfo.children.length === 1); + +var copyInfo = binaryen.getExpressionInfo(copy); +assert(originalInfo.children.length === copyInfo.children.length); +assert(originalInfo.children[0] !== copyInfo.children[0]); + +var originalIfInfo = binaryen.getExpressionInfo(originalInfo.children[0]); +var copyIfInfo = binaryen.getExpressionInfo(copyInfo.children[0]); + +assert(originalIfInfo.condition !== copyIfInfo.condition); +assert(originalIfInfo.ifTrue !== copyIfInfo.ifTrue); +assert(originalIfInfo.ifFalse !== copyIfInfo.ifFalse); -// Check that both are otherwise identical, but do it after tracing so -// emitText and tracing output don't conflict on stdout +// Check that both are otherwise identical assert(binaryen.emitText(original) === binaryen.emitText(copy)); diff --git a/test/binaryen.js/copy-expression.js.txt b/test/binaryen.js/copy-expression.js.txt index 2a0e40f3a4d..e69de29bb2d 100644 --- a/test/binaryen.js/copy-expression.js.txt +++ b/test/binaryen.js/copy-expression.js.txt @@ -1,37 +0,0 @@ -// beginning a Binaryen API trace -#include -#include -#include "binaryen-c.h" -int main() { - std::map types; - std::map expressions; - std::map functions; - std::map globals; - std::map events; - std::map exports; - std::map relooperBlocks; - std::map expressionRunners; - BinaryenModuleRef the_module = NULL; - RelooperRef the_relooper = NULL; - the_module = BinaryenModuleCreate(); - expressions[size_t(NULL)] = BinaryenExpressionRef(NULL); - expressions[1] = BinaryenLocalGet(the_module, 0, BinaryenTypeInt32()); - expressions[2] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); - expressions[3] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); - expressions[4] = BinaryenIf(the_module, expressions[1], expressions[2], expressions[3]); - { - BinaryenExpressionRef children[] = { expressions[4] }; - expressions[5] = BinaryenBlock(the_module, NULL, children, 1, BinaryenTypeInt32()); - } - expressions[6] = BinaryenExpressionCopy(expressions[5], the_module); - BinaryenBlockGetChild(expressions[5], 0); - BinaryenBlockGetChild(expressions[6], 0); - BinaryenIfGetCondition(expressions[4]); - BinaryenIfGetCondition(expressions[0]); // this is bad - BinaryenIfGetIfTrue(expressions[4]); - BinaryenIfGetIfTrue(expressions[0]); // this is bad - BinaryenIfGetIfFalse(expressions[4]); - BinaryenIfGetIfFalse(expressions[0]); // this is bad - return 0; -} -// ending a Binaryen API trace