diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 5 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 4 |
5 files changed, 49 insertions, 2 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7e72b056f..9aa18f270 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2793,6 +2793,8 @@ void WasmBinaryBuilder::processNames() { get->table = getTableName(index); } else if (auto* set = ref->dynCast<TableSet>()) { set->table = getTableName(index); + } else if (auto* size = ref->dynCast<TableSize>()) { + size->table = getTableName(index); } else { WASM_UNREACHABLE("Invalid type in table references"); } @@ -3613,8 +3615,10 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitMemoryFill(curr, opcode)) { break; } - throwError("invalid code after nontrapping float-to-int prefix: " + - std::to_string(opcode)); + if (maybeVisitTableSize(curr, opcode)) { + break; + } + throwError("invalid code after misc prefix: " + std::to_string(opcode)); break; } case BinaryConsts::SIMDPrefix: { @@ -4918,6 +4922,22 @@ bool WasmBinaryBuilder::maybeVisitMemoryFill(Expression*& out, uint32_t code) { return true; } +bool WasmBinaryBuilder::maybeVisitTableSize(Expression*& out, uint32_t code) { + if (code != BinaryConsts::TableSize) { + return false; + } + Index tableIdx = getU32LEB(); + if (tableIdx >= tables.size()) { + throwError("bad table index"); + } + auto* curr = allocator.alloc<TableSize>(); + curr->finalize(); + // Defer setting the table name for later, when we know it. + tableRefs[tableIdx].push_back(curr); + out = curr; + return true; +} + bool WasmBinaryBuilder::maybeVisitBinary(Expression*& out, uint8_t code) { Binary* curr; #define INT_TYPED_CODE(code) \ diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 854228e9f..6c41264a6 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2462,6 +2462,15 @@ Expression* SExpressionWasmBuilder::makeTableSet(Element& s) { return Builder(wasm).makeTableSet(tableName, index, value); } +Expression* SExpressionWasmBuilder::makeTableSize(Element& s) { + auto tableName = s[1]->str(); + auto* table = wasm.getTableOrNull(tableName); + if (!table) { + throw ParseException("invalid table name in table.size", s.line, s.col); + } + return Builder(wasm).makeTableSize(tableName); +} + // try can be either in the form of try-catch or try-delegate. // try-catch is written in the folded wast format as // (try diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 8f6581956..f81a0b7a0 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1857,6 +1857,11 @@ void BinaryInstWriter::visitTableSet(TableSet* curr) { o << U32LEB(parent.getTableIndex(curr->table)); } +void BinaryInstWriter::visitTableSize(TableSize* curr) { + o << int8_t(BinaryConsts::MiscPrefix) << U32LEB(BinaryConsts::TableSize); + o << U32LEB(parent.getTableIndex(curr->table)); +} + void BinaryInstWriter::visitTry(Try* curr) { breakStack.push_back(curr->name); o << int8_t(BinaryConsts::Try); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 0e362df9c..0271884a4 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -366,6 +366,7 @@ public: void visitRefEq(RefEq* curr); void visitTableGet(TableGet* curr); void visitTableSet(TableSet* curr); + void visitTableSize(TableSize* curr); void noteDelegate(Name name, Expression* curr); void noteRethrow(Name name, Expression* curr); void visitTry(Try* curr); @@ -2063,6 +2064,14 @@ void FunctionValidator::visitTableSet(TableSet* curr) { } } +void FunctionValidator::visitTableSize(TableSize* curr) { + shouldBeTrue(getModule()->features.hasReferenceTypes(), + curr, + "table.size requires reference types to be enabled"); + auto* table = getModule()->getTableOrNull(curr->table); + shouldBeTrue(!!table, curr, "table.size table must exist"); +} + void FunctionValidator::noteDelegate(Name name, Expression* curr) { if (name != DELEGATE_CALLER_TARGET) { shouldBeTrue(delegateTargetNames.count(name) != 0, diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 4975f4597..c42a1089d 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -857,6 +857,10 @@ void TableSet::finalize() { } } +void TableSize::finalize() { + // Nothing to do - the type must have been set already during construction. +} + void Try::finalize() { // If none of the component bodies' type is a supertype of the others, assume // the current type is already correct. TODO: Calculate a proper LUB. |