summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp37
-rw-r--r--src/wasm/wasm-s-parser.cpp22
-rw-r--r--src/wasm/wasm-stack.cpp26
-rw-r--r--src/wasm/wasm.cpp9
-rw-r--r--src/wasm/wat-parser.cpp7
5 files changed, 59 insertions, 42 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index b1f4b8907..767e0c2ab 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -4032,8 +4032,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
}
if (opcode == BinaryConsts::RefAsFunc ||
opcode == BinaryConsts::RefAsData ||
- opcode == BinaryConsts::RefAsI31 ||
- opcode == BinaryConsts::ExternInternalize ||
+ opcode == BinaryConsts::RefAsI31) {
+ visitRefAsCast((curr = allocator.alloc<RefCast>())->cast<RefCast>(),
+ opcode);
+ break;
+ }
+ if (opcode == BinaryConsts::ExternInternalize ||
opcode == BinaryConsts::ExternExternalize) {
visitRefAs((curr = allocator.alloc<RefAs>())->cast<RefAs>(), opcode);
break;
@@ -6910,6 +6914,26 @@ bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) {
return false;
}
+void WasmBinaryBuilder::visitRefAsCast(RefCast* curr, uint32_t code) {
+ // TODO: These instructions are deprecated. Remove them.
+ switch (code) {
+ case BinaryConsts::RefAsFunc:
+ curr->type = Type(HeapType::func, NonNullable);
+ break;
+ case BinaryConsts::RefAsData:
+ curr->type = Type(HeapType::data, NonNullable);
+ break;
+ case BinaryConsts::RefAsI31:
+ curr->type = Type(HeapType::i31, NonNullable);
+ break;
+ default:
+ WASM_UNREACHABLE("unexpected ref.as*");
+ }
+ curr->ref = popNonVoidExpression();
+ curr->safety = RefCast::Safe;
+ curr->finalize();
+}
+
bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) {
if (code == BinaryConsts::RefCastStatic || code == BinaryConsts::RefCast ||
code == BinaryConsts::RefCastNull || code == BinaryConsts::RefCastNop) {
@@ -7439,15 +7463,6 @@ void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) {
case BinaryConsts::RefAsNonNull:
curr->op = RefAsNonNull;
break;
- case BinaryConsts::RefAsFunc:
- curr->op = RefAsFunc;
- break;
- case BinaryConsts::RefAsData:
- curr->op = RefAsData;
- break;
- case BinaryConsts::RefAsI31:
- curr->op = RefAsI31;
- break;
case BinaryConsts::ExternInternalize:
curr->op = ExternInternalize;
break;
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 4f725d48b..03dba223b 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2790,27 +2790,27 @@ Expression* SExpressionWasmBuilder::makeRefTest(Element& s,
return Builder(wasm).makeRefTest(ref, *castType);
}
-Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {
+Expression* SExpressionWasmBuilder::makeRefCast(Element& s,
+ std::optional<Type> castType) {
int i = 1;
- Nullability nullability;
bool legacy = false;
- if (s[0]->str().str == "ref.cast_static") {
- legacy = true;
- } else {
- nullability = NonNullable;
- if (s[i]->str().str == "null") {
+ if (!castType) {
+ Nullability nullability = NonNullable;
+ if (s[0]->str().str == "ref.cast_static") {
+ legacy = true;
+ } else if (s[i]->str().str == "null") {
nullability = Nullable;
++i;
}
+ auto type = parseHeapType(*s[i++]);
+ castType = Type(type, nullability);
}
- auto heapType = parseHeapType(*s[i++]);
auto* ref = parseExpression(*s[i++]);
if (legacy) {
// Legacy polymorphic behavior.
- nullability = ref->type.getNullability();
+ castType = Type(castType->getHeapType(), ref->type.getNullability());
}
- auto type = Type(heapType, nullability);
- return Builder(wasm).makeRefCast(ref, type, RefCast::Safe);
+ return Builder(wasm).makeRefCast(ref, *castType, RefCast::Safe);
}
Expression* SExpressionWasmBuilder::makeRefCastNop(Element& s) {
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 82c7c511f..c4e1a863c 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2041,6 +2041,23 @@ void BinaryInstWriter::visitRefCast(RefCast* curr) {
o << U32LEB(BinaryConsts::RefCastNop);
parent.writeIndexedHeapType(curr->type.getHeapType());
} else {
+ // TODO: These instructions are deprecated. Remove them.
+ if (auto type = curr->type.getHeapType();
+ type.isBasic() && curr->type.isNonNullable()) {
+ switch (type.getBasic()) {
+ case HeapType::func:
+ o << U32LEB(BinaryConsts::RefAsFunc);
+ return;
+ case HeapType::data:
+ o << U32LEB(BinaryConsts::RefAsData);
+ return;
+ case HeapType::i31:
+ o << U32LEB(BinaryConsts::RefAsI31);
+ return;
+ default:
+ break;
+ }
+ }
if (curr->type.isNullable()) {
o << U32LEB(BinaryConsts::RefCastNull);
} else {
@@ -2244,15 +2261,6 @@ void BinaryInstWriter::visitRefAs(RefAs* curr) {
case RefAsNonNull:
o << int8_t(BinaryConsts::RefAsNonNull);
break;
- case RefAsFunc:
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsFunc);
- break;
- case RefAsData:
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsData);
- break;
- case RefAsI31:
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsI31);
- break;
case ExternInternalize:
o << int8_t(BinaryConsts::GCPrefix)
<< U32LEB(BinaryConsts::ExternInternalize);
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index c121ba89a..4a72f6ea6 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -1115,15 +1115,6 @@ void RefAs::finalize() {
case RefAsNonNull:
type = Type(value->type.getHeapType(), NonNullable);
break;
- case RefAsFunc:
- type = Type(HeapType::func, NonNullable);
- break;
- case RefAsData:
- type = Type(HeapType::data, NonNullable);
- break;
- case RefAsI31:
- type = Type(HeapType::i31, NonNullable);
- break;
case ExternInternalize:
type = Type(HeapType::any, value->type.getNullability());
break;
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp
index 08eec41c6..c2d06ae90 100644
--- a/src/wasm/wat-parser.cpp
+++ b/src/wasm/wat-parser.cpp
@@ -2346,7 +2346,9 @@ Result<typename Ctx::InstrT> makeI31Get(Ctx&, Index, bool signed_);
template<typename Ctx>
Result<typename Ctx::InstrT>
makeRefTest(Ctx&, Index, std::optional<Type> castType = std::nullopt);
-template<typename Ctx> Result<typename Ctx::InstrT> makeRefCast(Ctx&, Index);
+template<typename Ctx>
+Result<typename Ctx::InstrT>
+makeRefCast(Ctx&, Index, std::optional<Type> castType = std::nullopt);
template<typename Ctx> Result<typename Ctx::InstrT> makeRefCastNop(Ctx&, Index);
template<typename Ctx>
Result<typename Ctx::InstrT> makeBrOnNull(Ctx&, Index, bool onFail = false);
@@ -3444,7 +3446,8 @@ makeRefTest(Ctx& ctx, Index pos, std::optional<Type> castType) {
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeRefCast(Ctx& ctx, Index pos) {
+Result<typename Ctx::InstrT>
+makeRefCast(Ctx& ctx, Index pos, std::optional<Type> castType) {
return ctx.in.err("unimplemented instruction");
}