diff options
author | Daniel Wirtz <dcode@dcode.io> | 2019-10-11 19:35:30 +0200 |
---|---|---|
committer | Alon Zakai <azakai@google.com> | 2019-10-11 10:35:30 -0700 |
commit | 4e80fde446764102fe5685496f351f0539377ff6 (patch) | |
tree | 4de5fffd75456294c556647c6c0c480584ce73ef | |
parent | c6cd444496c4c1b684dbc69b10fc2f5cbfdd8e47 (diff) | |
download | binaryen-4e80fde446764102fe5685496f351f0539377ff6.tar.gz binaryen-4e80fde446764102fe5685496f351f0539377ff6.tar.bz2 binaryen-4e80fde446764102fe5685496f351f0539377ff6.zip |
Add offset parameter to BinaryenSetFunctionTable (#2380)
This PR adds an offset parameter to BinaryenSetFunctionTable so table elements
can start at the value of an (imported constant) global. Previously, the offset
was fixed to zero. As usual this is a breaking change to the C-API but backwards
compatible when using the JS-API.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 9 | ||||
-rw-r--r-- | src/binaryen-c.h | 3 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 5 | ||||
-rw-r--r-- | test/binaryen.js/kitchen-sink.js.txt | 11 | ||||
-rw-r--r-- | test/binaryen.js/reloc.js | 26 | ||||
-rw-r--r-- | test/binaryen.js/reloc.js.txt | 13 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 2 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 11 |
9 files changed, 63 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0775ab552..3dc5eedf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Current Trunk - Added `mutable` parameter to BinaryenAddGlobalImport. - Replace BinaryenSIMDBitselect* with BinaryenSIMDTernary* in the C API and add qfma/qfms instructions. +- Added `offset` parameter to BinaryenSetFunctionTable. v88 --- diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 7b4ee2bc5..2307de3e6 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -3449,7 +3449,8 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char** funcNames, - BinaryenIndex numFuncNames) { + BinaryenIndex numFuncNames, + BinaryenExpressionRef offset) { if (tracing) { std::cout << " {\n"; std::cout << " const char* funcNames[] = { "; @@ -3461,13 +3462,13 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module, } std::cout << " };\n"; std::cout << " BinaryenSetFunctionTable(the_module, " << initial << ", " - << maximum << ", funcNames, " << numFuncNames << ");\n"; + << maximum << ", funcNames, " << numFuncNames << ", expressions[" + << expressions[offset] << "]);\n"; std::cout << " }\n"; } auto* wasm = (Module*)module; - Table::Segment segment( - wasm->allocator.alloc<Const>()->set(Literal(int32_t(0)))); + Table::Segment segment((Expression*)offset); for (BinaryenIndex i = 0; i < numFuncNames; i++) { segment.data.push_back(funcNames[i]); } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 3d15a7efe..ab159695a 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -1144,7 +1144,8 @@ BINARYEN_API void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char** funcNames, - BinaryenIndex numFuncNames); + BinaryenIndex numFuncNames, + BinaryenExpressionRef offset); // Memory. One per module diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 8f49b105c..03e57d3d5 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -2056,11 +2056,12 @@ function wrapModule(module, self) { return Module['_BinaryenRemoveExport'](module, strToStack(externalName)); }); }; - self['setFunctionTable'] = function(initial, maximum, funcNames) { + self['setFunctionTable'] = function(initial, maximum, funcNames, offset) { return preserveStack(function() { return Module['_BinaryenSetFunctionTable'](module, initial, maximum, i32sToStack(funcNames.map(strToStack)), - funcNames.length + funcNames.length, + offset || self['i32']['const'](0) ); }); }; diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 1bf0b3b54..87a6bc97c 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -5471,17 +5471,18 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} BinaryenFunctionGetVar(functions[0], 0); BinaryenFunctionGetVar(functions[0], 1); BinaryenFunctionGetBody(functions[0]); + expressions[777] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); { const char* funcNames[] = { "kitchen()sinker" }; - BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1); + BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1, expressions[777]); } - expressions[777] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[778] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); { const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 }; const char* segments[] = { segment0, segment1 }; int8_t segmentPassive[] = { 0, 1 }; - BinaryenExpressionRef segmentOffsets[] = { expressions[777], expressions[0] }; + BinaryenExpressionRef segmentOffsets[] = { expressions[778], expressions[0] }; BinaryenIndex segmentSizes[] = { 12, 12 }; BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); } @@ -5489,10 +5490,10 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} BinaryenType paramTypes[] = { 0 }; functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0); } - expressions[778] = BinaryenNop(the_module); + expressions[779] = BinaryenNop(the_module); { BinaryenType varTypes[] = { 0 }; - functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[778]); + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[779]); } BinaryenSetStart(the_module, functions[1]); { diff --git a/test/binaryen.js/reloc.js b/test/binaryen.js/reloc.js new file mode 100644 index 000000000..68c29228d --- /dev/null +++ b/test/binaryen.js/reloc.js @@ -0,0 +1,26 @@ +function assert(x) { + if (!x) throw 'error!'; +} + +var module = new Binaryen.Module(); + +// memory with offset + +module.addGlobalImport("memory_base", "env", "memory_base", Binaryen.i32, false); +module.setMemory(1, -1, null, [ + { + offset: module.global.get("memory_base", Binaryen.i32), + data: "data data".split('').map(function(x) { return x.charCodeAt(0) }) + } +]); + +// table with offset + +var signature = module.addFunctionType("v", Binaryen.none, []); +var func = module.addFunction("func", signature, [], module.nop()); + +module.addGlobalImport("table_base", "env", "table_base", Binaryen.i32, false); +module.setFunctionTable(1, -1, [ "func", "func" ], module.global.get("table_base", Binaryen.i32)); + +assert(module.validate()); +console.log(module.emitText()); diff --git a/test/binaryen.js/reloc.js.txt b/test/binaryen.js/reloc.js.txt new file mode 100644 index 000000000..901499f98 --- /dev/null +++ b/test/binaryen.js/reloc.js.txt @@ -0,0 +1,13 @@ +(module + (type $v (func)) + (import "env" "memory_base" (global $memory_base i32)) + (import "env" "table_base" (global $table_base i32)) + (memory $0 1) + (data (global.get $memory_base) "data data") + (table $0 1 funcref) + (elem (global.get $table_base) $func $func) + (func $func (; 0 ;) (type $v) + (nop) + ) +) + diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index ba546e408..32443a850 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -637,7 +637,7 @@ void test_core() { // Function table. One per module const char* funcNames[] = { BinaryenFunctionGetName(sinker) }; - BinaryenSetFunctionTable(module, 1, 1, funcNames, 1); + BinaryenSetFunctionTable(module, 1, 1, funcNames, 1, BinaryenConst(module, BinaryenLiteralInt32(0))); // Memory. One per module diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index f76bb02b9..25338bc42 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -3771,17 +3771,18 @@ int main() { BinaryenAddFunctionImport(the_module, "an-imported", "module", "base", functionTypes[2]); exports[0] = BinaryenAddFunctionExport(the_module, "kitchen()sinker", "kitchen_sinker"); BinaryenFunctionGetName(functions[0]); + expressions[758] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); { const char* funcNames[] = { "kitchen()sinker" }; - BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1); + BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1, expressions[758]); } - expressions[758] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[759] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); { const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 }; const char* segments[] = { segment0, segment1 }; int8_t segmentPassive[] = { 0, 1 }; - BinaryenExpressionRef segmentOffsets[] = { expressions[758], expressions[0] }; + BinaryenExpressionRef segmentOffsets[] = { expressions[759], expressions[0] }; BinaryenIndex segmentSizes[] = { 12, 12 }; BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); } @@ -3789,10 +3790,10 @@ int main() { BinaryenType paramTypes[] = { 0 }; functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0); } - expressions[759] = BinaryenNop(the_module); + expressions[760] = BinaryenNop(the_module); { BinaryenType varTypes[] = { 0 }; - functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[759]); + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[760]); } BinaryenSetStart(the_module, functions[1]); { |