summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc23
-rw-r--r--src/ir/properties.h3
-rw-r--r--src/literal.h6
-rw-r--r--src/parser/contexts.h11
-rw-r--r--src/parser/parsers.h11
-rw-r--r--src/parser/wast-parser.cpp7
-rw-r--r--src/passes/Print.cpp6
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm-builder.h3
-rw-r--r--src/wasm-interpreter.h3
-rw-r--r--src/wasm-ir-builder.h2
-rw-r--r--src/wasm/literal.cpp3
-rw-r--r--src/wasm/wasm-binary.cpp18
-rw-r--r--src/wasm/wasm-ir-builder.cpp4
-rw-r--r--src/wasm/wasm-stack.cpp4
-rw-r--r--src/wasm/wasm.cpp3
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);
}
}