Skip to content

Commit e5e3bf3

Browse files
authored
Merge pull request #668 from WebAssembly/tables_n_memories
Tables and memories
2 parents e268d93 + 7851e3a commit e5e3bf3

File tree

112 files changed

+6389
-5485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+6389
-5485
lines changed

bin/wasm.js

Lines changed: 5843 additions & 5112 deletions
Large diffs are not rendered by default.

check.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def minify_check(wast, verify_final_result=True):
362362
print '\n[ checking wasm-shell spec testcases... ]\n'
363363

364364
if len(requested) == 0:
365-
BLACKLIST = []
365+
BLACKLIST = ['memory.wast'] # FIXME we support old and new memory formats, for now, until 0xc, and so can't pass this old-style test
366366
spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join('test', 'spec'))) if t not in BLACKLIST]
367367
else:
368368
spec_tests = requested[:]

src/asm2wasm.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,17 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
660660
// TODO: when not using aliasing function pointers, we could merge them by noticing that
661661
// index 0 in each table is the null func, and each other index should only have one
662662
// non-null func. However, that breaks down when function pointer casts are emulated.
663-
functionTableStarts[name] = wasm.table.names.size(); // this table starts here
663+
if (wasm.table.segments.size() == 0) {
664+
wasm.table.segments.emplace_back(wasm.allocator.alloc<Const>()->set(Literal(uint32_t(0))));
665+
}
666+
auto& segment = wasm.table.segments[0];
667+
functionTableStarts[name] = segment.data.size(); // this table starts here
664668
Ref contents = value[1];
665669
for (unsigned k = 0; k < contents->size(); k++) {
666670
IString curr = contents[k][1]->getIString();
667-
wasm.table.names.push_back(curr);
671+
segment.data.push_back(curr);
668672
}
673+
wasm.table.initial = wasm.table.max = segment.data.size();
669674
} else {
670675
abort_on("invalid var element", pair);
671676
}

src/binaryen-c.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -729,14 +729,17 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* fun
729729
}
730730

731731
auto* wasm = (Module*)module;
732+
Table::Segment segment(wasm->allocator.alloc<Const>()->set(Literal(int32_t(0))));
732733
for (BinaryenIndex i = 0; i < numFuncs; i++) {
733-
wasm->table.names.push_back(((Function*)funcs[i])->name);
734+
segment.data.push_back(((Function*)funcs[i])->name);
734735
}
736+
wasm->table.segments.push_back(segment);
737+
wasm->table.initial = wasm->table.max = numFuncs;
735738
}
736739

737740
// Memory. One per module
738741

739-
void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char* exportName, const char **segments, BinaryenIndex* segmentOffsets, BinaryenIndex* segmentSizes, BinaryenIndex numSegments) {
742+
void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char* exportName, const char **segments, BinaryenExpressionRef* segmentOffsets, BinaryenIndex* segmentSizes, BinaryenIndex numSegments) {
740743
if (tracing) {
741744
std::cout << " {\n";
742745
for (BinaryenIndex i = 0; i < numSegments; i++) {
@@ -754,10 +757,10 @@ void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, Binaryen
754757
}
755758
if (numSegments == 0) std::cout << "0"; // ensure the array is not empty, otherwise a compiler error on VS
756759
std::cout << " };\n";
757-
std::cout << " BinaryenIndex segmentOffsets[] = { ";
760+
std::cout << " BinaryenExpressionRef segmentOffsets[] = { ";
758761
for (BinaryenIndex i = 0; i < numSegments; i++) {
759762
if (i > 0) std::cout << ", ";
760-
std::cout << segmentOffsets[i];
763+
std::cout << "expressions[" << expressions[segmentOffsets[i]] << "]";
761764
}
762765
if (numSegments == 0) std::cout << "0"; // ensure the array is not empty, otherwise a compiler error on VS
763766
std::cout << " };\n";
@@ -779,7 +782,7 @@ void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, Binaryen
779782
wasm->memory.max = maximum;
780783
if (exportName) wasm->memory.exportName = exportName;
781784
for (BinaryenIndex i = 0; i < numSegments; i++) {
782-
wasm->memory.segments.emplace_back(segmentOffsets[i], segments[i], segmentSizes[i]);
785+
wasm->memory.segments.emplace_back((Expression*)segmentOffsets[i], segments[i], segmentSizes[i]);
783786
}
784787
}
785788

src/binaryen-c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* fun
346346

347347
// Each segment has data in segments, a start offset in segmentOffsets, and a size in segmentSizes.
348348
// exportName can be NULL
349-
void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char* exportName, const char **segments, BinaryenIndex* segmentOffsets, BinaryenIndex* segmentSizes, BinaryenIndex numSegments);
349+
void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char* exportName, const char **segments, BinaryenExpressionRef* segmentOffsets, BinaryenIndex* segmentSizes, BinaryenIndex numSegments);
350350

351351
// Start function. One per module
352352

src/passes/DuplicateFunctionElimination.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ struct DuplicateFunctionElimination : public Pass {
123123
replacerRunner.add<FunctionReplacer>(&replacements);
124124
replacerRunner.run();
125125
// replace in table
126-
for (auto& name : module->table.names) {
127-
auto iter = replacements.find(name);
128-
if (iter != replacements.end()) {
129-
name = iter->second;
126+
for (auto& segment : module->table.segments) {
127+
for (auto& name : segment.data) {
128+
auto iter = replacements.find(name);
129+
if (iter != replacements.end()) {
130+
name = iter->second;
131+
}
130132
}
131133
}
132134
// replace in start

src/passes/Print.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -575,12 +575,19 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
575575
decIndent();
576576
}
577577
void visitTable(Table *curr) {
578-
printOpening(o, "table");
579-
for (auto name : curr->names) {
580-
o << ' ';
581-
printName(name);
578+
printOpening(o, "table") << ' ' << curr->initial;
579+
if (curr->max && curr->max != Table::kMaxSize) o << ' ' << curr->max;
580+
o << " anyfunc)\n";
581+
doIndent(o, indent);
582+
for (auto& segment : curr->segments) {
583+
printOpening(o, "elem ", true);
584+
visit(segment.offset);
585+
for (auto name : segment.data) {
586+
o << ' ';
587+
printName(name);
588+
}
589+
o << ')';
582590
}
583-
o << ')';
584591
}
585592
void visitModule(Module *curr) {
586593
currModule = curr;
@@ -589,9 +596,12 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
589596
doIndent(o, indent);
590597
printOpening(o, "memory") << ' ' << curr->memory.initial;
591598
if (curr->memory.max && curr->memory.max != Memory::kMaxSize) o << ' ' << curr->memory.max;
599+
o << ")\n";
592600
for (auto segment : curr->memory.segments) {
593-
o << maybeNewLine;
594-
o << (minify ? "" : " ") << "(segment " << segment.offset << " \"";
601+
doIndent(o, indent);
602+
printOpening(o, "data ", true);
603+
visit(segment.offset);
604+
o << " \"";
595605
for (size_t i = 0; i < segment.data.size(); i++) {
596606
unsigned char c = segment.data[i];
597607
switch (c) {
@@ -612,10 +622,8 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
612622
}
613623
}
614624
}
615-
o << "\")";
625+
o << "\")\n";
616626
}
617-
o << ((curr->memory.segments.size() > 0 && !minify) ? "\n " : "") << ')';
618-
o << maybeNewLine;
619627
if (curr->memory.exportName.is()) {
620628
doIndent(o, indent);
621629
printOpening(o, "export ");
@@ -647,7 +655,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
647655
visitGlobal(child.get());
648656
o << maybeNewLine;
649657
}
650-
if (curr->table.names.size() > 0) {
658+
if (curr->table.segments.size() > 0 || curr->table.initial > 0 || curr->table.max != Table::kMaxSize) {
651659
doIndent(o, indent);
652660
visitTable(&curr->table);
653661
o << maybeNewLine;

src/passes/RemoveUnusedFunctions.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ struct RemoveUnusedFunctions : public Pass {
3939
root.push_back(module->getFunction(curr->value));
4040
}
4141
// For now, all functions that can be called indirectly are marked as roots.
42-
for (auto& curr : module->table.names) {
43-
root.push_back(module->getFunction(curr));
42+
for (auto& segment : module->table.segments) {
43+
for (auto& curr : segment.data) {
44+
root.push_back(module->getFunction(curr));
45+
}
4446
}
4547
// Compute function reachability starting from the root set.
4648
DirectCallGraphAnalyzer analyzer(module, root);

src/passes/ReorderFunctions.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ struct ReorderFunctions : public WalkerPass<PostWalker<ReorderFunctions, Visitor
3838
for (auto& curr : module->exports) {
3939
counts[curr->value]++;
4040
}
41-
for (auto& curr : module->table.names) {
42-
counts[curr]++;
41+
for (auto& segment : module->table.segments) {
42+
for (auto& curr : segment.data) {
43+
counts[curr]++;
44+
}
4345
}
4446
std::sort(module->functions.begin(), module->functions.end(), [this](
4547
const std::unique_ptr<Function>& a,

src/shared-constants.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ extern Name GROW_WASM_MEMORY,
2424
PARAM,
2525
RESULT,
2626
MEMORY,
27+
DATA,
2728
SEGMENT,
2829
EXPORT,
2930
IMPORT,
3031
TABLE,
32+
ELEM,
3133
LOCAL,
3234
TYPE,
3335
CALL,
@@ -43,6 +45,7 @@ extern Name GROW_WASM_MEMORY,
4345
NEG_NAN,
4446
CASE,
4547
BR,
48+
ANYFUNC,
4649
FAKE_RETURN,
4750
ASSERT_RETURN,
4851
ASSERT_TRAP,

0 commit comments

Comments
 (0)