summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wirtz <dcode@dcode.io>2019-10-11 19:35:30 +0200
committerAlon Zakai <azakai@google.com>2019-10-11 10:35:30 -0700
commit4e80fde446764102fe5685496f351f0539377ff6 (patch)
tree4de5fffd75456294c556647c6c0c480584ce73ef
parentc6cd444496c4c1b684dbc69b10fc2f5cbfdd8e47 (diff)
downloadbinaryen-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.md1
-rw-r--r--src/binaryen-c.cpp9
-rw-r--r--src/binaryen-c.h3
-rw-r--r--src/js/binaryen.js-post.js5
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt11
-rw-r--r--test/binaryen.js/reloc.js26
-rw-r--r--test/binaryen.js/reloc.js.txt13
-rw-r--r--test/example/c-api-kitchen-sink.c2
-rw-r--r--test/example/c-api-kitchen-sink.txt11
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]);
{