Skip to content

Commit 4e80fde

Browse files
dcodeIOkripken
authored andcommitted
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.
1 parent c6cd444 commit 4e80fde

9 files changed

Lines changed: 63 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Current Trunk
2626
- Added `mutable` parameter to BinaryenAddGlobalImport.
2727
- Replace BinaryenSIMDBitselect* with BinaryenSIMDTernary* in the C API and add
2828
qfma/qfms instructions.
29+
- Added `offset` parameter to BinaryenSetFunctionTable.
2930

3031
v88
3132
---

src/binaryen-c.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,7 +3449,8 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module,
34493449
BinaryenIndex initial,
34503450
BinaryenIndex maximum,
34513451
const char** funcNames,
3452-
BinaryenIndex numFuncNames) {
3452+
BinaryenIndex numFuncNames,
3453+
BinaryenExpressionRef offset) {
34533454
if (tracing) {
34543455
std::cout << " {\n";
34553456
std::cout << " const char* funcNames[] = { ";
@@ -3461,13 +3462,13 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module,
34613462
}
34623463
std::cout << " };\n";
34633464
std::cout << " BinaryenSetFunctionTable(the_module, " << initial << ", "
3464-
<< maximum << ", funcNames, " << numFuncNames << ");\n";
3465+
<< maximum << ", funcNames, " << numFuncNames << ", expressions["
3466+
<< expressions[offset] << "]);\n";
34653467
std::cout << " }\n";
34663468
}
34673469

34683470
auto* wasm = (Module*)module;
3469-
Table::Segment segment(
3470-
wasm->allocator.alloc<Const>()->set(Literal(int32_t(0))));
3471+
Table::Segment segment((Expression*)offset);
34713472
for (BinaryenIndex i = 0; i < numFuncNames; i++) {
34723473
segment.data.push_back(funcNames[i]);
34733474
}

src/binaryen-c.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,8 @@ BINARYEN_API void BinaryenSetFunctionTable(BinaryenModuleRef module,
11441144
BinaryenIndex initial,
11451145
BinaryenIndex maximum,
11461146
const char** funcNames,
1147-
BinaryenIndex numFuncNames);
1147+
BinaryenIndex numFuncNames,
1148+
BinaryenExpressionRef offset);
11481149

11491150
// Memory. One per module
11501151

src/js/binaryen.js-post.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,11 +2056,12 @@ function wrapModule(module, self) {
20562056
return Module['_BinaryenRemoveExport'](module, strToStack(externalName));
20572057
});
20582058
};
2059-
self['setFunctionTable'] = function(initial, maximum, funcNames) {
2059+
self['setFunctionTable'] = function(initial, maximum, funcNames, offset) {
20602060
return preserveStack(function() {
20612061
return Module['_BinaryenSetFunctionTable'](module, initial, maximum,
20622062
i32sToStack(funcNames.map(strToStack)),
2063-
funcNames.length
2063+
funcNames.length,
2064+
offset || self['i32']['const'](0)
20642065
);
20652066
});
20662067
};

test/binaryen.js/kitchen-sink.js.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5471,28 +5471,29 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
54715471
BinaryenFunctionGetVar(functions[0], 0);
54725472
BinaryenFunctionGetVar(functions[0], 1);
54735473
BinaryenFunctionGetBody(functions[0]);
5474+
expressions[777] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
54745475
{
54755476
const char* funcNames[] = { "kitchen()sinker" };
5476-
BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1);
5477+
BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1, expressions[777]);
54775478
}
5478-
expressions[777] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
5479+
expressions[778] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
54795480
{
54805481
const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 };
54815482
const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 };
54825483
const char* segments[] = { segment0, segment1 };
54835484
int8_t segmentPassive[] = { 0, 1 };
5484-
BinaryenExpressionRef segmentOffsets[] = { expressions[777], expressions[0] };
5485+
BinaryenExpressionRef segmentOffsets[] = { expressions[778], expressions[0] };
54855486
BinaryenIndex segmentSizes[] = { 12, 12 };
54865487
BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1);
54875488
}
54885489
{
54895490
BinaryenType paramTypes[] = { 0 };
54905491
functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0);
54915492
}
5492-
expressions[778] = BinaryenNop(the_module);
5493+
expressions[779] = BinaryenNop(the_module);
54935494
{
54945495
BinaryenType varTypes[] = { 0 };
5495-
functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[778]);
5496+
functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[779]);
54965497
}
54975498
BinaryenSetStart(the_module, functions[1]);
54985499
{

test/binaryen.js/reloc.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function assert(x) {
2+
if (!x) throw 'error!';
3+
}
4+
5+
var module = new Binaryen.Module();
6+
7+
// memory with offset
8+
9+
module.addGlobalImport("memory_base", "env", "memory_base", Binaryen.i32, false);
10+
module.setMemory(1, -1, null, [
11+
{
12+
offset: module.global.get("memory_base", Binaryen.i32),
13+
data: "data data".split('').map(function(x) { return x.charCodeAt(0) })
14+
}
15+
]);
16+
17+
// table with offset
18+
19+
var signature = module.addFunctionType("v", Binaryen.none, []);
20+
var func = module.addFunction("func", signature, [], module.nop());
21+
22+
module.addGlobalImport("table_base", "env", "table_base", Binaryen.i32, false);
23+
module.setFunctionTable(1, -1, [ "func", "func" ], module.global.get("table_base", Binaryen.i32));
24+
25+
assert(module.validate());
26+
console.log(module.emitText());

test/binaryen.js/reloc.js.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(module
2+
(type $v (func))
3+
(import "env" "memory_base" (global $memory_base i32))
4+
(import "env" "table_base" (global $table_base i32))
5+
(memory $0 1)
6+
(data (global.get $memory_base) "data data")
7+
(table $0 1 funcref)
8+
(elem (global.get $table_base) $func $func)
9+
(func $func (; 0 ;) (type $v)
10+
(nop)
11+
)
12+
)
13+

test/example/c-api-kitchen-sink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ void test_core() {
637637

638638
// Function table. One per module
639639
const char* funcNames[] = { BinaryenFunctionGetName(sinker) };
640-
BinaryenSetFunctionTable(module, 1, 1, funcNames, 1);
640+
BinaryenSetFunctionTable(module, 1, 1, funcNames, 1, BinaryenConst(module, BinaryenLiteralInt32(0)));
641641

642642
// Memory. One per module
643643

test/example/c-api-kitchen-sink.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3771,28 +3771,29 @@ int main() {
37713771
BinaryenAddFunctionImport(the_module, "an-imported", "module", "base", functionTypes[2]);
37723772
exports[0] = BinaryenAddFunctionExport(the_module, "kitchen()sinker", "kitchen_sinker");
37733773
BinaryenFunctionGetName(functions[0]);
3774+
expressions[758] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
37743775
{
37753776
const char* funcNames[] = { "kitchen()sinker" };
3776-
BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1);
3777+
BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1, expressions[758]);
37773778
}
3778-
expressions[758] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
3779+
expressions[759] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
37793780
{
37803781
const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 };
37813782
const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 };
37823783
const char* segments[] = { segment0, segment1 };
37833784
int8_t segmentPassive[] = { 0, 1 };
3784-
BinaryenExpressionRef segmentOffsets[] = { expressions[758], expressions[0] };
3785+
BinaryenExpressionRef segmentOffsets[] = { expressions[759], expressions[0] };
37853786
BinaryenIndex segmentSizes[] = { 12, 12 };
37863787
BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1);
37873788
}
37883789
{
37893790
BinaryenType paramTypes[] = { 0 };
37903791
functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0);
37913792
}
3792-
expressions[759] = BinaryenNop(the_module);
3793+
expressions[760] = BinaryenNop(the_module);
37933794
{
37943795
BinaryenType varTypes[] = { 0 };
3795-
functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[759]);
3796+
functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[760]);
37963797
}
37973798
BinaryenSetStart(the_module, functions[1]);
37983799
{

0 commit comments

Comments
 (0)