diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 8 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 35 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 6 |
4 files changed, 59 insertions, 1 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index df99fabb9..d449d4bdb 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3978,7 +3978,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { } if (opcode == BinaryConsts::RefAsFunc || opcode == BinaryConsts::RefAsData || - opcode == BinaryConsts::RefAsI31) { + opcode == BinaryConsts::RefAsI31 || + opcode == BinaryConsts::ExternInternalize || + opcode == BinaryConsts::ExternExternalize) { visitRefAs((curr = allocator.alloc<RefAs>())->cast<RefAs>(), opcode); break; } @@ -7347,6 +7349,12 @@ void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) { case BinaryConsts::RefAsI31: curr->op = RefAsI31; break; + case BinaryConsts::ExternInternalize: + curr->op = ExternInternalize; + break; + case BinaryConsts::ExternExternalize: + curr->op = ExternExternalize; + break; default: WASM_UNREACHABLE("invalid code for ref.as_*"); } @@ -7356,6 +7364,7 @@ void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) { } curr->finalize(); } + void WasmBinaryBuilder::throwError(std::string text) { throw ParseException(text, 0, pos); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 13bd09927..fddb7e41c 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2170,6 +2170,14 @@ void BinaryInstWriter::visitRefAs(RefAs* curr) { case RefAsI31: o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsI31); break; + case ExternInternalize: + o << int8_t(BinaryConsts::GCPrefix) + << U32LEB(BinaryConsts::ExternInternalize); + break; + case ExternExternalize: + o << int8_t(BinaryConsts::GCPrefix) + << U32LEB(BinaryConsts::ExternExternalize); + break; default: WASM_UNREACHABLE("invalid ref.as_*"); } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 532529d2a..75cbcf53a 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -424,6 +424,7 @@ public: void visitMemoryGrow(MemoryGrow* curr); void visitRefNull(RefNull* curr); void visitRefIs(RefIs* curr); + void visitRefAs(RefAs* curr); void visitRefFunc(RefFunc* curr); void visitRefEq(RefEq* curr); void visitTableGet(TableGet* curr); @@ -2125,6 +2126,40 @@ void FunctionValidator::visitRefIs(RefIs* curr) { "ref.is_*'s argument should be a reference type"); } +void FunctionValidator::visitRefAs(RefAs* curr) { + switch (curr->op) { + default: + // TODO: validate all the other ref.as_* + break; + case ExternInternalize: { + shouldBeTrue(getModule()->features.hasGC(), + curr, + "extern.internalize requries GC to be enabled"); + if (curr->type == Type::unreachable) { + return; + } + shouldBeSubType(curr->value->type, + Type(HeapType::ext, Nullable), + curr->value, + "extern.internalize value should be an externref"); + break; + } + case ExternExternalize: { + shouldBeTrue(getModule()->features.hasGC(), + curr, + "extern.externalize requries GC to be enabled"); + if (curr->type == Type::unreachable) { + return; + } + shouldBeSubType(curr->value->type, + Type(HeapType::any, Nullable), + curr->value, + "extern.externalize value should be an anyref"); + break; + } + } +} + void FunctionValidator::visitRefFunc(RefFunc* curr) { // If we are not in a function, this is a global location like a table. We // allow RefFunc there as we represent tables that way regardless of what diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 8226e9079..56db8d7a9 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1122,6 +1122,12 @@ void RefAs::finalize() { case RefAsI31: type = Type(HeapType::i31, NonNullable); break; + case ExternInternalize: + type = Type(HeapType::any, value->type.getNullability()); + break; + case ExternExternalize: + type = Type(HeapType::ext, value->type.getNullability()); + break; default: WASM_UNREACHABLE("invalid ref.as_*"); } |