summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp33
-rw-r--r--src/wasm/wasm-validator.cpp72
2 files changed, 67 insertions, 38 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 7e90dfde4..c1e506c8e 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -746,7 +746,7 @@ void WasmBinaryWriter::writeTableDeclarations() {
table->max,
table->hasMax(),
/*shared=*/false,
- /*is64*/ false);
+ table->is64());
});
finishSection(start);
}
@@ -2462,6 +2462,13 @@ Name WasmBinaryReader::getGlobalName(Index index) {
return wasm.globals[index]->name;
}
+Table* WasmBinaryReader::getTable(Index index) {
+ if (index < wasm.tables.size()) {
+ return wasm.tables[index].get();
+ }
+ throwError("Table index out of range.");
+}
+
Name WasmBinaryReader::getTagName(Index index) {
if (index >= wasm.tags.size()) {
throwError("invalid tag index");
@@ -2555,18 +2562,14 @@ void WasmBinaryReader::readImports() {
table->type = getType();
bool is_shared;
- Type indexType;
getResizableLimits(table->initial,
table->max,
is_shared,
- indexType,
+ table->indexType,
Table::kUnlimitedSize);
if (is_shared) {
throwError("Tables may not be shared");
}
- if (indexType == Type::i64) {
- throwError("Tables may not be 64-bit");
- }
wasm.addTable(std::move(table));
break;
@@ -3355,16 +3358,14 @@ void WasmBinaryReader::readTableDeclarations() {
}
auto table = Builder::makeTable(Name::fromInt(i), elemType);
bool is_shared;
- Type indexType;
- getResizableLimits(
- table->initial, table->max, is_shared, indexType, Table::kUnlimitedSize);
+ getResizableLimits(table->initial,
+ table->max,
+ is_shared,
+ table->indexType,
+ Table::kUnlimitedSize);
if (is_shared) {
throwError("Tables may not be shared");
}
- if (indexType == Type::i64) {
- throwError("Tables may not be 64-bit");
- }
-
wasm.addTable(std::move(table));
}
}
@@ -5511,6 +5512,9 @@ bool WasmBinaryReader::maybeVisitTableSize(Expression*& out, uint32_t code) {
throwError("bad table index");
}
auto* curr = allocator.alloc<TableSize>();
+ if (getTable(tableIdx)->is64()) {
+ curr->type = Type::i64;
+ }
curr->finalize();
// Defer setting the table name for later, when we know it.
tableRefs[tableIdx].push_back(&curr->table);
@@ -5529,6 +5533,9 @@ bool WasmBinaryReader::maybeVisitTableGrow(Expression*& out, uint32_t code) {
auto* curr = allocator.alloc<TableGrow>();
curr->delta = popNonVoidExpression();
curr->value = popNonVoidExpression();
+ if (getTable(tableIdx)->is64()) {
+ curr->type = Type::i64;
+ }
curr->finalize();
// Defer setting the table name for later, when we know it.
tableRefs[tableIdx].push_back(&curr->table);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index aad9a0582..8f3082b41 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -947,15 +947,16 @@ void FunctionValidator::visitCall(Call* curr) {
void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
validateReturnCall(curr);
- shouldBeEqualOrFirstIsUnreachable(curr->target->type,
- Type(Type::i32),
- curr,
- "indirect call target must be an i32");
if (curr->target->type != Type::unreachable) {
auto* table = getModule()->getTableOrNull(curr->table);
- shouldBeTrue(!!table, curr, "call-indirect table must exist");
- if (table) {
+ if (shouldBeTrue(!!table, curr, "call-indirect table must exist")) {
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->target->type,
+ table->indexType,
+ curr,
+ "call-indirect call target must match the table index type");
+ shouldBeTrue(!!table, curr, "call-indirect table must exist");
shouldBeTrue(table->type.isFunction(),
curr,
"call-indirect table must be of function type.");
@@ -2267,13 +2268,19 @@ void FunctionValidator::visitTableGet(TableGet* curr) {
shouldBeTrue(getModule()->features.hasReferenceTypes(),
curr,
"table.get requires reference types [--enable-reference-types]");
- shouldBeEqualOrFirstIsUnreachable(
- curr->index->type, Type(Type::i32), curr, "table.get index must be an i32");
auto* table = getModule()->getTableOrNull(curr->table);
- if (shouldBeTrue(!!table, curr, "table.get table must exist") &&
- curr->type != Type::unreachable) {
- shouldBeEqual(
- curr->type, table->type, curr, "table.get must have same type as table.");
+ if (shouldBeTrue(!!table, curr, "table.get table must exist")) {
+ if (curr->type != Type::unreachable) {
+ shouldBeEqual(curr->type,
+ table->type,
+ curr,
+ "table.get must have same type as table.");
+ }
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->index->type,
+ table->indexType,
+ curr,
+ "table.get index must match the table index type.");
}
}
@@ -2281,15 +2288,19 @@ void FunctionValidator::visitTableSet(TableSet* curr) {
shouldBeTrue(getModule()->features.hasReferenceTypes(),
curr,
"table.set requires reference types [--enable-reference-types]");
- shouldBeEqualOrFirstIsUnreachable(
- curr->index->type, Type(Type::i32), curr, "table.set index must be an i32");
auto* table = getModule()->getTableOrNull(curr->table);
- if (shouldBeTrue(!!table, curr, "table.set table must exist") &&
- curr->type != Type::unreachable) {
- shouldBeSubType(curr->value->type,
- table->type,
- curr,
- "table.set value must have right type");
+ if (shouldBeTrue(!!table, curr, "table.set table must exist")) {
+ if (curr->type != Type::unreachable) {
+ shouldBeSubType(curr->value->type,
+ table->type,
+ curr,
+ "table.set value must have right type");
+ }
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->index->type,
+ table->indexType,
+ curr,
+ "table.set index must match the table index type.");
}
}
@@ -2315,7 +2326,7 @@ void FunctionValidator::visitTableGrow(TableGrow* curr) {
curr,
"table.grow value must have right type");
shouldBeEqual(curr->delta->type,
- Type(Type::i32),
+ table->indexType,
curr,
"table.grow must match table index type");
}
@@ -2331,11 +2342,17 @@ void FunctionValidator::visitTableFill(TableFill* curr) {
table->type,
curr,
"table.fill value must have right type");
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->dest->type,
+ table->indexType,
+ curr,
+ "table.fill dest must match table index type");
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->size->type,
+ table->indexType,
+ curr,
+ "table.fill size must match table index type");
}
- shouldBeEqualOrFirstIsUnreachable(
- curr->dest->type, Type(Type::i32), curr, "table.fill dest must be i32");
- shouldBeEqualOrFirstIsUnreachable(
- curr->size->type, Type(Type::i32), curr, "table.fill size must be i32");
}
void FunctionValidator::visitTableCopy(TableCopy* curr) {
@@ -3841,6 +3858,11 @@ static void validateTables(Module& module, ValidationInfo& info) {
"Only funcref and externref are valid for table type "
"(when gc is disabled)");
}
+ if (table->is64()) {
+ info.shouldBeTrue(module.features.hasMemory64(),
+ "memory",
+ "64-bit tables require memory64 [--enable-memory64]");
+ }
}
for (auto& segment : module.elementSegments) {