summaryrefslogtreecommitdiff
path: root/src/wasm2js.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-06-11 14:13:52 -0700
committerGitHub <noreply@github.com>2024-06-11 14:13:52 -0700
commit2dcf67049ef4d2cbcb2a65d367be97ae675f9d8a (patch)
tree6b2193693bfa44034baff985e8ccf38d3fa4af0a /src/wasm2js.h
parentcdd94a01ad02e944eaa9ba5e20a1129bef9ac305 (diff)
downloadbinaryen-2dcf67049ef4d2cbcb2a65d367be97ae675f9d8a.tar.gz
binaryen-2dcf67049ef4d2cbcb2a65d367be97ae675f9d8a.tar.bz2
binaryen-2dcf67049ef4d2cbcb2a65d367be97ae675f9d8a.zip
wasm2js: Add Table operations (#6650)
TableGet, Set, Size, Grow, Fill, Copy. Also move "null" into shared-constants, to make the code more consistent overall.
Diffstat (limited to 'src/wasm2js.h')
-rw-r--r--src/wasm2js.h73
1 files changed, 57 insertions, 16 deletions
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 2084c0453..dd4e61a51 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -672,12 +672,11 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) {
if (!table->imported()) {
TableUtils::FlatTable flat(*wasm, *table);
if (flat.valid) {
- Name null("null");
for (auto& name : flat.names) {
if (name.is()) {
name = fromName(name, NameScope::Top);
} else {
- name = null;
+ name = NULL_;
}
ValueBuilder::appendToArray(theArray, ValueBuilder::makeName(name));
}
@@ -2221,11 +2220,11 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
visit(curr->value, EXPRESSION_RESULT),
visit(curr->size, EXPRESSION_RESULT));
}
- Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName("null"); }
+ Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName(NULL_); }
Ref visitRefIsNull(RefIsNull* curr) {
return ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT),
EQ,
- ValueBuilder::makeName("null"));
+ ValueBuilder::makeName(NULL_));
}
Ref visitRefFunc(RefFunc* curr) {
return ValueBuilder::makeName(fromName(curr->func, NameScope::Top));
@@ -2236,28 +2235,40 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
visit(curr->right, EXPRESSION_RESULT));
}
Ref visitTableGet(TableGet* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
+ return ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE),
+ visit(curr->index, EXPRESSION_RESULT));
}
Ref visitTableSet(TableSet* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
+ auto sub = ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE),
+ visit(curr->index, EXPRESSION_RESULT));
+ auto value = visit(curr->value, EXPRESSION_RESULT);
+ return ValueBuilder::makeBinary(sub, SET, value);
}
Ref visitTableSize(TableSize* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
+ return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE),
+ ValueBuilder::makeName(LENGTH));
}
Ref visitTableGrow(TableGrow* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
+ ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_GROW);
+ // Also ensure fill, as grow calls fill internally.
+ ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL);
+ return ValueBuilder::makeCall(ABI::wasm2js::TABLE_GROW,
+ visit(curr->value, EXPRESSION_RESULT),
+ visit(curr->delta, EXPRESSION_RESULT));
}
Ref visitTableFill(TableFill* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
+ ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL);
+ return ValueBuilder::makeCall(ABI::wasm2js::TABLE_FILL,
+ visit(curr->dest, EXPRESSION_RESULT),
+ visit(curr->value, EXPRESSION_RESULT),
+ visit(curr->size, EXPRESSION_RESULT));
}
Ref visitTableCopy(TableCopy* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
+ ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_COPY);
+ return ValueBuilder::makeCall(ABI::wasm2js::TABLE_COPY,
+ visit(curr->dest, EXPRESSION_RESULT),
+ visit(curr->source, EXPRESSION_RESULT),
+ visit(curr->size, EXPRESSION_RESULT));
}
Ref visitTry(Try* curr) {
unimplemented(curr);
@@ -3026,6 +3037,36 @@ void Wasm2JSGlue::emitSpecialSupport() {
bufferView.copyWithin(dest, source, source + size);
}
)";
+ } else if (import->base == ABI::wasm2js::TABLE_GROW) {
+ out << R"(
+ function wasm2js_table_grow(value, delta) {
+ // TODO: traps on invalid things
+ var oldSize = FUNCTION_TABLE.length;
+ FUNCTION_TABLE.length = oldSize + delta;
+ if (newSize > oldSize) {
+ __wasm_table_fill(oldSize, value, delta)
+ }
+ return oldSize;
+ }
+ )";
+ } else if (import->base == ABI::wasm2js::TABLE_FILL) {
+ out << R"(
+ function __wasm_table_fill(dest, value, size) {
+ // TODO: traps on invalid things
+ for (var i = 0; i < size; i++) {
+ FUNCTION_TABLE[dest + i] = value;
+ }
+ }
+ )";
+ } else if (import->base == ABI::wasm2js::TABLE_COPY) {
+ out << R"(
+ function __wasm_table_copy(dest, source, size) {
+ // TODO: traps on invalid things
+ for (var i = 0; i < size; i++) {
+ FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i];
+ }
+ }
+ )";
} else if (import->base == ABI::wasm2js::DATA_DROP) {
out << R"(
function wasm2js_data_drop(segment) {