diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 23 | ||||
-rw-r--r-- | src/ir/properties.h | 3 | ||||
-rw-r--r-- | src/literal.h | 6 | ||||
-rw-r--r-- | src/parser/contexts.h | 11 | ||||
-rw-r--r-- | src/parser/parsers.h | 11 | ||||
-rw-r--r-- | src/parser/wast-parser.cpp | 7 | ||||
-rw-r--r-- | src/passes/Print.cpp | 6 | ||||
-rw-r--r-- | src/wasm-binary.h | 1 | ||||
-rw-r--r-- | src/wasm-builder.h | 3 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 3 | ||||
-rw-r--r-- | src/wasm-ir-builder.h | 2 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 3 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 18 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 3 |
16 files changed, 76 insertions, 32 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 8a3dcba0b..bbed0f8be 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -1831,7 +1831,7 @@ switch (buf[0]) { } case 'n': if (op == "i31.new"sv) { - CHECK_ERR(makeRefI31(ctx, pos, annotations)); + CHECK_ERR(makeRefI31(ctx, pos, annotations, Unshared)); return Ok{}; } goto parse_error; @@ -4505,12 +4505,23 @@ switch (buf[0]) { goto parse_error; case 'i': { switch (buf[5]) { - case '3': - if (op == "ref.i31"sv) { - CHECK_ERR(makeRefI31(ctx, pos, annotations)); - return Ok{}; + case '3': { + switch (buf[7]) { + case '\0': + if (op == "ref.i31"sv) { + CHECK_ERR(makeRefI31(ctx, pos, annotations, Unshared)); + return Ok{}; + } + goto parse_error; + case '_': + if (op == "ref.i31_shared"sv) { + CHECK_ERR(makeRefI31(ctx, pos, annotations, Shared)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 's': if (op == "ref.is_null"sv) { CHECK_ERR(makeRefIsNull(ctx, pos, annotations)); diff --git a/src/ir/properties.h b/src/ir/properties.h index ccb2392b0..09486ee34 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -119,7 +119,8 @@ inline Literal getLiteral(const Expression* curr) { return Literal(r->func, r->type.getHeapType()); } else if (auto* i = curr->dynCast<RefI31>()) { if (auto* c = i->value->dynCast<Const>()) { - return Literal::makeI31(c->value.geti32()); + return Literal::makeI31(c->value.geti32(), + i->type.getHeapType().getShared()); } } else if (auto* s = curr->dynCast<StringConst>()) { return Literal(s->string.toString()); diff --git a/src/literal.h b/src/literal.h index 1268448fb..45f76f247 100644 --- a/src/literal.h +++ b/src/literal.h @@ -243,8 +243,8 @@ public: static Literal makeFunc(Name func, HeapType type) { return Literal(func, type); } - static Literal makeI31(int32_t value) { - auto lit = Literal(Type(HeapType::i31, NonNullable)); + static Literal makeI31(int32_t value, Shareability share) { + auto lit = Literal(Type(HeapTypes::i31.getBasic(share), NonNullable)); lit.i32 = value | 0x80000000; return lit; } @@ -281,7 +281,7 @@ public: return i32; } int32_t geti31(bool signed_ = true) const { - assert(type.getHeapType() == HeapType::i31); + assert(type.getHeapType().getBasic(Unshared) == HeapType::i31); // Cast to unsigned for the left shift to avoid undefined behavior. return signed_ ? int32_t((uint32_t(i32) << 1)) >> 1 : (i32 & 0x7fffffff); } diff --git a/src/parser/contexts.h b/src/parser/contexts.h index f58275d71..96a70663d 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -695,7 +695,10 @@ struct NullInstrParserCtx { Result<> makeCallRef(Index, const std::vector<Annotation>&, HeapTypeT, bool) { return Ok{}; } - Result<> makeRefI31(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> + makeRefI31(Index, const std::vector<Annotation>&, Shareability share) { + return Ok{}; + } Result<> makeI31Get(Index, const std::vector<Annotation>&, bool) { return Ok{}; } @@ -2363,8 +2366,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeCallRef(type, isReturn)); } - Result<> makeRefI31(Index pos, const std::vector<Annotation>& annotations) { - return withLoc(pos, irBuilder.makeRefI31()); + Result<> makeRefI31(Index pos, + const std::vector<Annotation>& annotations, + Shareability share) { + return withLoc(pos, irBuilder.makeRefI31(share)); } Result<> makeI31Get(Index pos, diff --git a/src/parser/parsers.h b/src/parser/parsers.h index db450e3c6..2c3916fa3 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -221,7 +221,8 @@ template<typename Ctx> Result<> makeCallRef(Ctx&, Index, const std::vector<Annotation>&, bool isReturn); template<typename Ctx> -Result<> makeRefI31(Ctx&, Index, const std::vector<Annotation>&); +Result<> +makeRefI31(Ctx&, Index, const std::vector<Annotation>&, Shareability share); template<typename Ctx> Result<> makeI31Get(Ctx&, Index, const std::vector<Annotation>&, bool signed_); template<typename Ctx> @@ -2127,9 +2128,11 @@ Result<> makeCallRef(Ctx& ctx, } template<typename Ctx> -Result<> -makeRefI31(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { - return ctx.makeRefI31(pos, annotations); +Result<> makeRefI31(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + Shareability share) { + return ctx.makeRefI31(pos, annotations, share); } template<typename Ctx> diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 137ef0df1..a3a6c14ce 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -207,6 +207,13 @@ Result<ExpectedResult> result(Lexer& in) { return RefResult{HeapType::func}; } + if (in.takeSExprStart("ref.i31_shared")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.i31_shared"); + } + return RefResult{HeapTypes::i31.getBasic(Shared)}; + } + return in.err("unrecognized result"); } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 2e9800775..ede49ab38 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2076,7 +2076,11 @@ struct PrintExpressionContents o << std::max(curr->tuple->type.size(), size_t(2)) << " "; o << curr->index; } - void visitRefI31(RefI31* curr) { printMedium(o, "ref.i31"); } + void visitRefI31(RefI31* curr) { + bool shared = + curr->type != Type::unreachable && curr->type.getHeapType().isShared(); + printMedium(o, shared ? "ref.i31_shared" : "ref.i31"); + } void visitI31Get(I31Get* curr) { printMedium(o, curr->signed_ ? "i31.get_s" : "i31.get_u"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 0b9615c7e..3e45b4969 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1125,6 +1125,7 @@ enum ASTNodes { RefI31 = 0x1c, I31GetS = 0x1d, I31GetU = 0x1e, + RefI31Shared = 0x1f, // stringref opcodes diff --git a/src/wasm-builder.h b/src/wasm-builder.h index a20ba46a6..1e768b11c 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -873,9 +873,10 @@ public: ret->finalize(); return ret; } - RefI31* makeRefI31(Expression* value) { + RefI31* makeRefI31(Expression* value, Shareability share = Unshared) { auto* ret = wasm.allocator.alloc<RefI31>(); ret->value = value; + ret->type = Type(HeapTypes::i31.getBasic(share), NonNullable); ret->finalize(); return ret; } diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 93739d1c9..9bdf0e72c 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1426,7 +1426,8 @@ public: } const auto& value = flow.getSingleValue(); NOTE_EVAL1(value); - return Literal::makeI31(value.geti32()); + return Literal::makeI31(value.geti32(), + curr->type.getHeapType().getShared()); } Flow visitI31Get(I31Get* curr) { NOTE_ENTER("I31Get"); diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 16c3b7570..eff8c85ad 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -181,7 +181,7 @@ public: [[nodiscard]] Result<> makeTupleMake(uint32_t arity); [[nodiscard]] Result<> makeTupleExtract(uint32_t arity, uint32_t index); [[nodiscard]] Result<> makeTupleDrop(uint32_t arity); - [[nodiscard]] Result<> makeRefI31(); + [[nodiscard]] Result<> makeRefI31(Shareability share); [[nodiscard]] Result<> makeI31Get(bool signed_); [[nodiscard]] Result<> makeCallRef(HeapType type, bool isReturn); [[nodiscard]] Result<> makeRefTest(Type type); diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index f13ea504f..20b6b7234 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -57,7 +57,8 @@ Literal::Literal(Type type) : type(type) { return; } - if (type.isRef() && type.getHeapType() == HeapType::i31) { + if (type.isRef() && type.getHeapType().isBasic() && + type.getHeapType().getBasic(Unshared) == HeapType::i31) { assert(type.isNonNullable()); i32 = 0; return; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 78470324c..74d74f473 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7244,13 +7244,19 @@ void WasmBinaryReader::visitCallRef(CallRef* curr) { } bool WasmBinaryReader::maybeVisitRefI31(Expression*& out, uint32_t code) { - if (code != BinaryConsts::RefI31) { - return false; + Shareability share; + switch (code) { + case BinaryConsts::RefI31: + share = Unshared; + break; + case BinaryConsts::RefI31Shared: + share = Shared; + break; + default: + return false; } - auto* curr = allocator.alloc<RefI31>(); - curr->value = popNonVoidExpression(); - curr->finalize(); - out = curr; + auto* value = popNonVoidExpression(); + out = Builder(wasm).makeRefI31(value, share); return true; } diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 63f5df4c0..3db6238c4 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1605,10 +1605,10 @@ Result<> IRBuilder::makeTupleDrop(uint32_t arity) { return Ok{}; } -Result<> IRBuilder::makeRefI31() { +Result<> IRBuilder::makeRefI31(Shareability share) { RefI31 curr; CHECK_ERR(visitRefI31(&curr)); - push(builder.makeRefI31(curr.value)); + push(builder.makeRefI31(curr.value, share)); return Ok{}; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 40a50706a..cd0a9928e 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2114,7 +2114,9 @@ void BinaryInstWriter::visitTupleExtract(TupleExtract* curr) { } void BinaryInstWriter::visitRefI31(RefI31* curr) { - o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefI31); + o << int8_t(BinaryConsts::GCPrefix) + << U32LEB(curr->type.getHeapType().isShared() ? BinaryConsts::RefI31Shared + : BinaryConsts::RefI31); } void BinaryInstWriter::visitI31Get(I31Get* curr) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 8a2b4755c..c4f02128e 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -964,7 +964,8 @@ void RefI31::finalize() { if (value->type == Type::unreachable) { type = Type::unreachable; } else { - type = Type(HeapType::i31, NonNullable); + assert(type.isRef() && type.getHeapType().isBasic() && + type.getHeapType().getBasic(Unshared) == HeapType::i31); } } |