diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 25 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 16 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 31 |
4 files changed, 76 insertions, 0 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index fc14510e9..020953c1b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3052,6 +3052,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { visitRefIs((curr = allocator.alloc<RefIs>())->cast<RefIs>(), opcode); break; } + if (opcode == BinaryConsts::RefAsFunc || + opcode == BinaryConsts::RefAsData || + opcode == BinaryConsts::RefAsI31) { + visitRefAs((curr = allocator.alloc<RefAs>())->cast<RefAs>(), opcode); + break; + } throwError("invalid code after GC prefix: " + std::to_string(opcode)); break; } @@ -5971,6 +5977,25 @@ bool WasmBinaryBuilder::maybeVisitArrayLen(Expression*& out, uint32_t code) { return true; } +void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) { + BYN_TRACE("zz node: RefAs\n"); + switch (code) { + case BinaryConsts::RefAsFunc: + curr->op = RefAsFunc; + break; + case BinaryConsts::RefAsData: + curr->op = RefAsData; + break; + case BinaryConsts::RefAsI31: + curr->op = RefAsI31; + break; + default: + WASM_UNREACHABLE("invalid code for ref.as_*"); + } + curr->value = popNonVoidExpression(); + curr->finalize(); +} + void WasmBinaryBuilder::throwError(std::string text) { throw ParseException(text, 0, pos); } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index b9927cbc7..5dec22eb3 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2236,6 +2236,10 @@ Expression* SExpressionWasmBuilder::makeArrayLen(Element& s) { return Builder(wasm).makeArrayLen(ref); } +Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) { + return Builder(wasm).makeRefAs(op, parseExpression(s[1])); +} + // converts an s-expression string representing binary data into an output // sequence of raw bytes this appends to data, which may already contain // content. diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 5609dbb0e..197581e33 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2072,6 +2072,22 @@ void BinaryInstWriter::visitArrayLen(ArrayLen* curr) { parent.writeHeapType(curr->ref->type.getHeapType()); } +void BinaryInstWriter::visitRefAs(RefAs* curr) { + switch (curr->op) { + case RefAsFunc: + o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefAsFunc); + break; + case RefAsData: + o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefAsData); + break; + case RefAsI31: + o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefAsI31); + break; + default: + WASM_UNREACHABLE("invalid ref.as_*"); + } +} + void BinaryInstWriter::emitScopeEnd(Expression* curr) { assert(!breakStack.empty()); breakStack.pop_back(); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index cd1fb716c..2921f4974 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -245,6 +245,17 @@ const char* getExpressionName(Expression* curr) { return "array.set"; case Expression::Id::ArrayLenId: return "array.len"; + case Expression::Id::RefAsId: + switch (curr->cast<RefAs>()->op) { + case RefAsFunc: + return "ref.as_func"; + case RefAsData: + return "ref.as_data"; + case RefAsI31: + return "ref.as_i31"; + default: + WASM_UNREACHABLE("unimplemented ref.is_*"); + } case Expression::Id::NumExpressionIds: WASM_UNREACHABLE("invalid expr id"); } @@ -1153,6 +1164,26 @@ void ArrayLen::finalize() { } } +void RefAs::finalize() { + if (value->type == Type::unreachable) { + type = Type::unreachable; + return; + } + switch (op) { + case RefAsFunc: + type = Type::funcref; + break; + case RefAsData: + type = Type::dataref; + break; + case RefAsI31: + type = Type::i31ref; + break; + default: + WASM_UNREACHABLE("unimplemented ref.is_*"); + } +} + size_t Function::getNumParams() { return sig.params.size(); } size_t Function::getNumVars() { return vars.size(); } |