diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/parser/wast-parser.cpp | 12 | ||||
-rw-r--r-- | src/tools/wasm-shell.cpp | 3 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 13 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 3 |
4 files changed, 21 insertions, 10 deletions
diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index a3a6c14ce..00269a577 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -25,7 +25,17 @@ using namespace std::string_view_literals; namespace { Result<Literal> const_(Lexer& in) { - // TODO: handle `ref.extern n` as well. + if (in.takeSExprStart("ref.extern"sv)) { + auto n = in.takeI32(); + if (!n) { + return in.err("expected host reference payload"); + } + if (!in.takeRParen()) { + return in.err("expected end of ref.extern"); + } + // Represent host references as externalized i31s. + return Literal::makeI31(*n, Unshared).externalize(); + } return parseConst(in); } diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index 651857965..eda4facc9 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp @@ -318,7 +318,8 @@ struct Shell { return Err{err.str()}; } } else if (auto* ref = std::get_if<RefResult>(&expected)) { - if (!val.type.isRef() || val.type.getHeapType() != ref->type) { + if (!val.type.isRef() || + !HeapType::isSubType(val.type.getHeapType(), ref->type)) { err << "expected " << ref->type << " reference, got " << val << atIndex(); return Err{err.str()}; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 1bf135c40..cbd2b31d6 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -3172,20 +3172,17 @@ public: } auto info = getTableInstanceInfo(curr->table); - Index tableSize = info.interface()->tableSize(info.name); + uint64_t tableSize = info.interface()->tableSize(info.name); auto* table = info.instance->wasm.getTable(info.name); Flow ret = Literal::makeFromInt64(tableSize, table->indexType); Flow fail = Literal::makeFromInt64(-1, table->indexType); - Index delta = deltaFlow.getSingleValue().geti32(); + uint64_t delta = deltaFlow.getSingleValue().getUnsigned(); - if (tableSize >= uint32_t(-1) - delta) { + uint64_t newSize; + if (std::ckd_add(&newSize, tableSize, delta)) { return fail; } - if (uint64_t(tableSize) + uint64_t(delta) > uint64_t(table->max)) { - return fail; - } - Index newSize = tableSize + delta; - if (newSize > WebLimitations::MaxTableSize) { + if (newSize > table->max || newSize > WebLimitations::MaxTableSize) { return fail; } if (!info.interface()->growTable( diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 650318be3..d60e2f8a9 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -463,6 +463,9 @@ bool Literal::operator==(const Literal& other) const { if (type.getHeapType().isMaybeShared(HeapType::i31)) { return i32 == other.i32; } + if (type.getHeapType().isMaybeShared(HeapType::ext)) { + return internalize() == other.internalize(); + } WASM_UNREACHABLE("unexpected type"); } WASM_UNREACHABLE("unexpected type"); |