Skip to content

[reference-types] remove single table restriction in IR #3517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 52 commits into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
917ac8a
remove single table constraint from modules
martianboy Jan 26, 2021
45edfa6
a few fixes
martianboy Jan 26, 2021
def024d
fix BinaryenAddTable
martianboy Jan 26, 2021
9f99c84
lint
martianboy Jan 26, 2021
e47c72a
lint
martianboy Jan 26, 2021
f74f8a1
adapt to c74acc0
martianboy Jan 26, 2021
9bae447
fix memory leak in copyTable
martianboy Jan 26, 2021
affa243
revert internal table naming with prefix
martianboy Jan 27, 2021
7113a62
add table name getter to c api
martianboy Jan 27, 2021
ead9806
don't rely on CallIndirect to always have a tableName
martianboy Jan 27, 2021
80b8f83
fix call_indirect validation if target unreachable
martianboy Jan 28, 2021
c378d6f
lint
martianboy Jan 28, 2021
24ff11c
various fixes
martianboy Jan 28, 2021
98e1e42
lint: clang-format
martianboy Jan 28, 2021
73a761b
add an example for c api
martianboy Jan 28, 2021
efb6e9c
apply name change suggestion
martianboy Jan 29, 2021
563861d
don't add unnecessary table when splitting
martianboy Jan 29, 2021
9c02a5d
assert conditions
martianboy Jan 29, 2021
5a2991a
elem header format 0x2 for multiple active tables
martianboy Jan 30, 2021
31ca44e
lint
martianboy Jan 30, 2021
6a3a91e
apply minor suggestions
martianboy Jan 30, 2021
20f3dd0
fix multi-table test case and related bugs
martianboy Jan 30, 2021
46852aa
lint
martianboy Jan 30, 2021
e2c0c8c
error out early in wasm2js if module has multiple tables
martianboy Feb 1, 2021
4f6ccf0
print table name in call indirect
martianboy Feb 1, 2021
6565460
apply suggestions
martianboy Feb 1, 2021
e94b291
fix remove-unused-module-elements and add more tests
martianboy Feb 2, 2021
086759f
add test for directize pass
martianboy Feb 2, 2021
b3b8f39
Merge branch 'main' into multi-table
martianboy Feb 2, 2021
a3f99ec
create a Builder::makeTable method
martianboy Feb 2, 2021
3379198
Merge remote-tracking branch 'upstream/main' into multi-table
martianboy Feb 3, 2021
f51bd42
make sure CallIndirect always has a table name
martianboy Feb 3, 2021
eb116e7
define an enum for elem segment flag bits
martianboy Feb 3, 2021
d3d6cb5
merge SegmentFlag and ElementFlag enums
martianboy Feb 3, 2021
2478ea8
support parsing numeric index exports
martianboy Feb 3, 2021
306fcdb
fix emscripten test?
martianboy Feb 3, 2021
c1cf5a2
lint
martianboy Feb 3, 2021
755537e
don't forget about legacy elem segments!
martianboy Feb 4, 2021
1a27c6a
update js tests
martianboy Feb 4, 2021
8bb5cd6
fix js api
martianboy Feb 4, 2021
5240f7b
prevent fuzzer from adding more tables for now
martianboy Feb 4, 2021
b8f3702
lint
martianboy Feb 4, 2021
4faff51
polish
martianboy Feb 4, 2021
a7631dc
format
martianboy Feb 4, 2021
6c7ed38
add more c & js apis
martianboy Feb 5, 2021
ac73dbf
add removeTable js api
martianboy Feb 5, 2021
21f50ce
update changelog
martianboy Feb 5, 2021
c3f1736
improved c api multiple tables test
martianboy Feb 5, 2021
ae96436
Merge remote-tracking branch 'upstream/main' into multi-table
martianboy Feb 6, 2021
aaa12df
adapt
martianboy Feb 6, 2021
0d0c18e
Merge branch 'main' of https://github.com/WebAssembly/binaryen into m…
martianboy Feb 8, 2021
d902590
apply suggestions
martianboy Feb 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,32 @@ Current Trunk
-------------

- `wasm-dis` now supports options to enable or disable Wasm features.
- Reference types support has been improved by allowing multiple tables in a
module.
- `call_indirect` and `return_call_indirect` now take an additional table name
parameter. This is necessary for reference types support.
- New getter/setter methods have been introduced for `call_indirect` table name:
- `BinaryenCallIndirectGetTable`
- `BinaryenCallIndirectSetTable`
- JS API `CallIndirect.table`
- New APIs have been added to add and manipulate multiple tables in a module:
- `BinaryenAddTable`
- `BinaryenRemoveTable`
- `BinaryenGetNumTables`
- `BinaryenGetTable`
- `BinaryenGetTableByIndex`
- `BinaryenTableGetName`
- `BinaryenTableGetInitial`
- `BinaryenTableHasMax`
- `BinaryenTableGetMax`
- `BinaryenTableImportGetModule`
- `BinaryenTableImportGetBase`
- `module.addTable`
- `module.removeTable`
- `module.getTable`
- `module.getTableByIndex`
- `module.getNumTables`
- `binaryen.getTableInfo`

v99
---
Expand Down
145 changes: 128 additions & 17 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,13 +805,15 @@ BinaryenExpressionRef BinaryenReturnCall(BinaryenModuleRef module,
}
static BinaryenExpressionRef
makeBinaryenCallIndirect(BinaryenModuleRef module,
const char* table,
BinaryenExpressionRef target,
BinaryenExpressionRef* operands,
BinaryenIndex numOperands,
BinaryenType params,
BinaryenType results,
bool isReturn) {
auto* ret = ((Module*)module)->allocator.alloc<CallIndirect>();
ret->table = table;
ret->target = (Expression*)target;
for (BinaryenIndex i = 0; i < numOperands; i++) {
ret->operands.push_back((Expression*)operands[i]);
Expand All @@ -823,23 +825,25 @@ makeBinaryenCallIndirect(BinaryenModuleRef module,
return static_cast<Expression*>(ret);
}
BinaryenExpressionRef BinaryenCallIndirect(BinaryenModuleRef module,
const char* table,
BinaryenExpressionRef target,
BinaryenExpressionRef* operands,
BinaryenIndex numOperands,
BinaryenType params,
BinaryenType results) {
return makeBinaryenCallIndirect(
module, target, operands, numOperands, params, results, false);
module, table, target, operands, numOperands, params, results, false);
}
BinaryenExpressionRef
BinaryenReturnCallIndirect(BinaryenModuleRef module,
const char* table,
BinaryenExpressionRef target,
BinaryenExpressionRef* operands,
BinaryenIndex numOperands,
BinaryenType params,
BinaryenType results) {
return makeBinaryenCallIndirect(
module, target, operands, numOperands, params, results, true);
module, table, target, operands, numOperands, params, results, true);
}
BinaryenExpressionRef BinaryenLocalGet(BinaryenModuleRef module,
BinaryenIndex index,
Expand Down Expand Up @@ -1610,6 +1614,19 @@ void BinaryenCallIndirectSetTarget(BinaryenExpressionRef expr,
assert(targetExpr);
static_cast<CallIndirect*>(expression)->target = (Expression*)targetExpr;
}
const char* BinaryenCallIndirectGetTable(BinaryenExpressionRef expr) {
auto* expression = (Expression*)expr;
assert(expression->is<CallIndirect>());
return static_cast<CallIndirect*>(expression)->table.c_str();
}
void BinaryenCallIndirectSetTable(BinaryenExpressionRef expr,
const char* table) {
Name name(table);
auto* expression = (Expression*)expr;

assert(expression->is<CallIndirect>());
static_cast<CallIndirect*>(expression)->table = name;
}
BinaryenIndex BinaryenCallIndirectGetNumOperands(BinaryenExpressionRef expr) {
auto* expression = (Expression*)expr;
assert(expression->is<CallIndirect>());
Expand Down Expand Up @@ -3154,9 +3171,11 @@ void BinaryenAddTableImport(BinaryenModuleRef module,
const char* internalName,
const char* externalModuleName,
const char* externalBaseName) {
auto& table = ((Module*)module)->table;
table.module = externalModuleName;
table.base = externalBaseName;
auto table = std::make_unique<Table>();
table->name = internalName;
table->module = externalModuleName;
table->base = externalBaseName;
((Module*)module)->addTable(std::move(table));
}
void BinaryenAddMemoryImport(BinaryenModuleRef module,
const char* internalName,
Expand Down Expand Up @@ -3273,43 +3292,100 @@ BinaryenExportRef BinaryenGetExportByIndex(BinaryenModuleRef module,
return exports[index].get();
}

// Function table. One per module

// TODO(reference-types): maybe deprecate this function?
void BinaryenSetFunctionTable(BinaryenModuleRef module,
BinaryenIndex initial,
BinaryenIndex maximum,
const char** funcNames,
BinaryenIndex numFuncNames,
BinaryenExpressionRef offset) {
auto* wasm = (Module*)module;
if (wasm->tables.empty()) {
wasm->addTable(Builder::makeTable(Name::fromInt(0)));
}

auto& table = wasm->tables.front();
table->initial = initial;
table->max = maximum;

Table::Segment segment((Expression*)offset);
for (BinaryenIndex i = 0; i < numFuncNames; i++) {
segment.data.push_back(funcNames[i]);
}
auto& table = ((Module*)module)->table;
table.initial = initial;
table.max = maximum;
table.exists = true;
table.segments.push_back(segment);
table->segments.push_back(segment);
}

BinaryenTableRef BinaryenAddTable(BinaryenModuleRef module,
const char* name,
BinaryenIndex initial,
BinaryenIndex maximum,
const char** funcNames,
BinaryenIndex numFuncNames,
BinaryenExpressionRef offset) {
auto table = Builder::makeTable(name, initial, maximum);
table->hasExplicitName = true;

Table::Segment segment((Expression*)offset);
for (BinaryenIndex i = 0; i < numFuncNames; i++) {
segment.data.push_back(funcNames[i]);
}
table->segments.push_back(segment);
((Module*)module)->addTable(std::move(table));

return ((Module*)module)->getTable(name);
}
void BinaryenRemoveTable(BinaryenModuleRef module, const char* table) {
((Module*)module)->removeTable(table);
}
BinaryenIndex BinaryenGetNumTables(BinaryenModuleRef module) {
return ((Module*)module)->tables.size();
}
BinaryenTableRef BinaryenGetTable(BinaryenModuleRef module, const char* name) {
return ((Module*)module)->getTableOrNull(name);
}
BinaryenTableRef BinaryenGetTableByIndex(BinaryenModuleRef module,
BinaryenIndex index) {
const auto& tables = ((Module*)module)->tables;
if (tables.size() <= index) {
Fatal() << "invalid table index.";
}
return tables[index].get();
}

int BinaryenIsFunctionTableImported(BinaryenModuleRef module) {
return ((Module*)module)->table.imported();
if (((Module*)module)->tables.size() > 0) {
return ((Module*)module)->tables[0]->imported();
}

return false;
}
BinaryenIndex BinaryenGetNumFunctionTableSegments(BinaryenModuleRef module) {
return ((Module*)module)->table.segments.size();
if (((Module*)module)->tables.size() > 0) {
return ((Module*)module)->tables[0]->segments.size();
}

return 0;
}
BinaryenExpressionRef
BinaryenGetFunctionTableSegmentOffset(BinaryenModuleRef module,
BinaryenIndex segmentId) {
const auto& segments = ((Module*)module)->table.segments;
if (((Module*)module)->tables.empty()) {
Fatal() << "module has no tables.";
}

const auto& segments = ((Module*)module)->tables[0]->segments;
if (segments.size() <= segmentId) {
Fatal() << "invalid function table segment id.";
}
return segments[segmentId].offset;
}
BinaryenIndex BinaryenGetFunctionTableSegmentLength(BinaryenModuleRef module,
BinaryenIndex segmentId) {
const auto& segments = ((Module*)module)->table.segments;
if (((Module*)module)->tables.empty()) {
Fatal() << "module has no tables.";
}

const auto& segments = ((Module*)module)->tables[0]->segments;
if (segments.size() <= segmentId) {
Fatal() << "invalid function table segment id.";
}
Expand All @@ -3318,7 +3394,11 @@ BinaryenIndex BinaryenGetFunctionTableSegmentLength(BinaryenModuleRef module,
const char* BinaryenGetFunctionTableSegmentData(BinaryenModuleRef module,
BinaryenIndex segmentId,
BinaryenIndex dataId) {
const auto& segments = ((Module*)module)->table.segments;
if (((Module*)module)->tables.empty()) {
Fatal() << "module has no tables.";
}

const auto& segments = ((Module*)module)->tables[0]->segments;
if (segments.size() <= segmentId ||
segments[segmentId].data.size() <= dataId) {
Fatal() << "invalid function table segment or data id.";
Expand Down Expand Up @@ -3788,6 +3868,21 @@ void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func,
((Function*)func)->debugLocations[(Expression*)expr] = loc;
}

//
// =========== Table operations ===========
//

const char* BinaryenTableGetName(BinaryenTableRef table) {
return ((Table*)table)->name.c_str();
}
int BinaryenTableGetInitial(BinaryenTableRef table) {
return ((Table*)table)->initial;
}
int BinaryenTableHasMax(BinaryenTableRef table) {
return ((Table*)table)->hasMax();
}
int BinaryenTableGetMax(BinaryenTableRef table) { return ((Table*)table)->max; }

//
// =========== Global operations ===========
//
Expand Down Expand Up @@ -3835,6 +3930,14 @@ const char* BinaryenFunctionImportGetModule(BinaryenFunctionRef import) {
return "";
}
}
const char* BinaryenTableImportGetModule(BinaryenTableRef import) {
auto* table = (Table*)import;
if (table->imported()) {
return table->module.c_str();
} else {
return "";
}
}
const char* BinaryenGlobalImportGetModule(BinaryenGlobalRef import) {
auto* global = (Global*)import;
if (global->imported()) {
Expand All @@ -3859,6 +3962,14 @@ const char* BinaryenFunctionImportGetBase(BinaryenFunctionRef import) {
return "";
}
}
const char* BinaryenTableImportGetBase(BinaryenTableRef import) {
auto* table = (Table*)import;
if (table->imported()) {
return table->base.c_str();
} else {
return "";
}
}
const char* BinaryenGlobalImportGetBase(BinaryenGlobalRef import) {
auto* global = (Global*)import;
if (global->imported()) {
Expand Down
38 changes: 38 additions & 0 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ BINARYEN_API BinaryenExpressionRef BinaryenCall(BinaryenModuleRef module,
BinaryenType returnType);
BINARYEN_API BinaryenExpressionRef
BinaryenCallIndirect(BinaryenModuleRef module,
const char* table,
BinaryenExpressionRef target,
BinaryenExpressionRef* operands,
BinaryenIndex numOperands,
Expand All @@ -621,6 +622,7 @@ BinaryenReturnCall(BinaryenModuleRef module,
BinaryenType returnType);
BINARYEN_API BinaryenExpressionRef
BinaryenReturnCallIndirect(BinaryenModuleRef module,
const char* table,
BinaryenExpressionRef target,
BinaryenExpressionRef* operands,
BinaryenIndex numOperands,
Expand Down Expand Up @@ -1041,6 +1043,12 @@ BinaryenCallIndirectGetTarget(BinaryenExpressionRef expr);
BINARYEN_API void
BinaryenCallIndirectSetTarget(BinaryenExpressionRef expr,
BinaryenExpressionRef targetExpr);
// Gets the table name of a `call_indirect` expression.
BINARYEN_API const char*
BinaryenCallIndirectGetTable(BinaryenExpressionRef expr);
// Sets the table name of a `call_indirect` expression.
BINARYEN_API void BinaryenCallIndirectSetTable(BinaryenExpressionRef expr,
const char* table);
// Gets the number of operands of a `call_indirect` expression.
BINARYEN_API BinaryenIndex
BinaryenCallIndirectGetNumOperands(BinaryenExpressionRef expr);
Expand Down Expand Up @@ -2039,6 +2047,25 @@ BINARYEN_API BinaryenIndex BinaryenGetFunctionTableSegmentLength(
BINARYEN_API const char* BinaryenGetFunctionTableSegmentData(
BinaryenModuleRef module, BinaryenIndex segmentId, BinaryenIndex dataId);

// Tables

BINARYEN_REF(Table);

BINARYEN_API BinaryenTableRef BinaryenAddTable(BinaryenModuleRef module,
const char* table,
BinaryenIndex initial,
BinaryenIndex maximum,
const char** funcNames,
BinaryenIndex numFuncNames,
BinaryenExpressionRef offset);
BINARYEN_API void BinaryenRemoveTable(BinaryenModuleRef module,
const char* table);
BINARYEN_API BinaryenIndex BinaryenGetNumTables(BinaryenModuleRef module);
BINARYEN_API BinaryenTableRef BinaryenGetTable(BinaryenModuleRef module,
const char* name);
BINARYEN_API BinaryenTableRef BinaryenGetTableByIndex(BinaryenModuleRef module,
BinaryenIndex index);

// Memory. One per module

// Each segment has data in segments, a start offset in segmentOffsets, and a
Expand Down Expand Up @@ -2329,6 +2356,15 @@ BINARYEN_API void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func,
BinaryenIndex lineNumber,
BinaryenIndex columnNumber);

//
// ========== Table Operations ==========
//

BINARYEN_API const char* BinaryenTableGetName(BinaryenTableRef table);
BINARYEN_API int BinaryenTableGetInitial(BinaryenTableRef table);
BINARYEN_API int BinaryenTableHasMax(BinaryenTableRef table);
BINARYEN_API int BinaryenTableGetMax(BinaryenTableRef table);

//
// ========== Global Operations ==========
//
Expand Down Expand Up @@ -2364,12 +2400,14 @@ BINARYEN_API BinaryenType BinaryenEventGetResults(BinaryenEventRef event);
// Gets the external module name of the specified import.
BINARYEN_API const char*
BinaryenFunctionImportGetModule(BinaryenFunctionRef import);
BINARYEN_API const char* BinaryenTableImportGetModule(BinaryenTableRef import);
BINARYEN_API const char*
BinaryenGlobalImportGetModule(BinaryenGlobalRef import);
BINARYEN_API const char* BinaryenEventImportGetModule(BinaryenEventRef import);
// Gets the external base name of the specified import.
BINARYEN_API const char*
BinaryenFunctionImportGetBase(BinaryenFunctionRef import);
BINARYEN_API const char* BinaryenTableImportGetBase(BinaryenTableRef import);
BINARYEN_API const char* BinaryenGlobalImportGetBase(BinaryenGlobalRef import);
BINARYEN_API const char* BinaryenEventImportGetBase(BinaryenEventRef import);

Expand Down
Loading