summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/wast-parser.cpp12
-rw-r--r--src/tools/wasm-shell.cpp3
-rw-r--r--src/wasm-interpreter.h13
-rw-r--r--src/wasm/literal.cpp3
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");