diff options
-rwxr-xr-x | scripts/gen-s-parser.py | 1 | ||||
-rw-r--r-- | src/gen-s-parser.inc | 3 | ||||
-rw-r--r-- | src/passes/Print.cpp | 3 | ||||
-rw-r--r-- | src/wasm-binary.h | 1 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 3 | ||||
-rw-r--r-- | src/wasm.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 3 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 4 | ||||
-rw-r--r-- | test/heap-types.wast | 1 | ||||
-rw-r--r-- | test/heap-types.wast.from-wast | 5 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary | 5 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary.noDebugInfo | 5 |
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) ) |