summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/gen-s-parser.py1
-rw-r--r--src/gen-s-parser.inc3
-rw-r--r--src/passes/Print.cpp3
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm-interpreter.h3
-rw-r--r--src/wasm.h1
-rw-r--r--src/wasm/wasm-binary.cpp6
-rw-r--r--src/wasm/wasm-stack.cpp3
-rw-r--r--src/wasm/wasm.cpp4
-rw-r--r--test/heap-types.wast1
-rw-r--r--test/heap-types.wast.from-wast5
-rw-r--r--test/heap-types.wast.fromBinary5
-rw-r--r--test/heap-types.wast.fromBinary.noDebugInfo5
13 files changed, 41 insertions, 0 deletions
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index 420f38c64..20d8d54a2 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -571,6 +571,7 @@ instructions = [
("ref.is_func", "makeRefIs(s, RefIsFunc)"),
("ref.is_data", "makeRefIs(s, RefIsData)"),
("ref.is_i31", "makeRefIs(s, RefIsI31)"),
+ ("ref.as_non_null", "makeRefAs(s, RefAsNonNull)"),
("ref.as_func", "makeRefAs(s, RefAsFunc)"),
("ref.as_data", "makeRefAs(s, RefAsData)"),
("ref.as_i31", "makeRefAs(s, RefAsI31)"),
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index a22a01c02..3930a0318 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -2849,6 +2849,9 @@ switch (op[0]) {
case 'i':
if (strcmp(op, "ref.as_i31") == 0) { return makeRefAs(s, RefAsI31); }
goto parse_error;
+ case 'n':
+ if (strcmp(op, "ref.as_non_null") == 0) { return makeRefAs(s, RefAsNonNull); }
+ goto parse_error;
default: goto parse_error;
}
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index c380eb0f9..9e1afffd4 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1871,6 +1871,9 @@ struct PrintExpressionContents
}
void visitRefAs(RefAs* curr) {
switch (curr->op) {
+ case RefAsNonNull:
+ printMedium(o, "ref.as_non_null");
+ break;
case RefAsFunc:
printMedium(o, "ref.as_func");
break;
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index e976a57bf..3536afaf8 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -996,6 +996,7 @@ enum ASTNodes {
RefNull = 0xd0,
RefIsNull = 0xd1,
RefFunc = 0xd2,
+ RefAsNonNull = 0xd3,
// exception handling opcodes
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index fb7a3fcea..26c86efe6 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1681,6 +1681,9 @@ public:
trap("null ref");
}
switch (curr->op) {
+ case RefAsNonNull:
+ // We've already checked for a null.
+ break;
case RefAsFunc:
if (value.type.isFunction()) {
trap("not a func");
diff --git a/src/wasm.h b/src/wasm.h
index 2102972b3..d681f3f4b 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -550,6 +550,7 @@ enum RefIsOp {
};
enum RefAsOp {
+ RefAsNonNull,
RefAsFunc,
RefAsData,
RefAsI31,
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 64a40f2ca..4a90dd698 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -2876,6 +2876,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
case BinaryConsts::RefEq:
visitRefEq((curr = allocator.alloc<RefEq>())->cast<RefEq>());
break;
+ case BinaryConsts::RefAsNonNull:
+ visitRefAs((curr = allocator.alloc<RefAs>())->cast<RefAs>(), code);
+ break;
case BinaryConsts::Try:
visitTryOrTryInBlock(curr);
break;
@@ -5997,6 +6000,9 @@ bool WasmBinaryBuilder::maybeVisitArrayLen(Expression*& out, uint32_t code) {
void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) {
BYN_TRACE("zz node: RefAs\n");
switch (code) {
+ case BinaryConsts::RefAsNonNull:
+ curr->op = RefAsNonNull;
+ break;
case BinaryConsts::RefAsFunc:
curr->op = RefAsFunc;
break;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 0ccca0e23..9ac3013b5 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2090,6 +2090,9 @@ void BinaryInstWriter::visitArrayLen(ArrayLen* curr) {
void BinaryInstWriter::visitRefAs(RefAs* curr) {
switch (curr->op) {
+ case RefAsNonNull:
+ o << int8_t(BinaryConsts::RefAsNonNull);
+ break;
case RefAsFunc:
o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefAsFunc);
break;
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index a62435412..a94bda066 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -1036,6 +1036,10 @@ void RefAs::finalize() {
return;
}
switch (op) {
+ case RefAsNonNull:
+ // FIXME: when we support non-nullable types, switch to NonNullable
+ type = Type(value->type.getHeapType(), Nullable);
+ break;
case RefAsFunc:
type = Type::funcref;
break;
diff --git a/test/heap-types.wast b/test/heap-types.wast
index 94138276a..e06d1dff6 100644
--- a/test/heap-types.wast
+++ b/test/heap-types.wast
@@ -188,6 +188,7 @@
(if (ref.is_i31 (local.get $x)) (unreachable))
)
(func $ref.as_X (param $x anyref)
+ (drop (ref.as_non_null (local.get $x)))
(drop (ref.as_func (local.get $x)))
(drop (ref.as_data (local.get $x)))
(drop (ref.as_i31 (local.get $x)))
diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast
index a737a50ab..f3e8d5ce6 100644
--- a/test/heap-types.wast.from-wast
+++ b/test/heap-types.wast.from-wast
@@ -221,6 +221,11 @@
)
(func $ref.as_X (param $x anyref)
(drop
+ (ref.as_non_null
+ (local.get $x)
+ )
+ )
+ (drop
(ref.as_func
(local.get $x)
)
diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary
index b1256ac4f..80c91d2fe 100644
--- a/test/heap-types.wast.fromBinary
+++ b/test/heap-types.wast.fromBinary
@@ -220,6 +220,11 @@
)
(func $ref.as_X (param $x anyref)
(drop
+ (ref.as_non_null
+ (local.get $x)
+ )
+ )
+ (drop
(ref.as_func
(local.get $x)
)
diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo
index 5febb58a3..2852b8bea 100644
--- a/test/heap-types.wast.fromBinary.noDebugInfo
+++ b/test/heap-types.wast.fromBinary.noDebugInfo
@@ -220,6 +220,11 @@
)
(func $6 (param $0 anyref)
(drop
+ (ref.as_non_null
+ (local.get $0)
+ )
+ )
+ (drop
(ref.as_func
(local.get $0)
)