summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-06-18 18:20:49 -0700
committerGitHub <noreply@github.com>2024-06-19 01:20:49 +0000
commit2df678e4670517eaac40d1d2d9541d3b706b324b (patch)
tree3a47da6a20834dad1e43a8953ea428eb12fcb13c /src/parser
parent829e228d4b2ccb314ea1e653fd16154ae3fd31b3 (diff)
downloadbinaryen-2df678e4670517eaac40d1d2d9541d3b706b324b.tar.gz
binaryen-2df678e4670517eaac40d1d2d9541d3b706b324b.tar.bz2
binaryen-2df678e4670517eaac40d1d2d9541d3b706b324b.zip
[threads] Shared basic heap types (#6667)
Implement binary and text parsing and printing of shared basic heap types and incorporate them into the type hierarchy. To avoid the massive amount of code duplication that would be necessary if we were to add separate enum variants for each of the shared basic heap types, use bit 0 to indicate whether the type is shared and replace `getBasic()` with `getBasic(Unshared)`, which clears that bit. Update all the use sites to record whether the original type was shared and produce shared or unshared output without code duplication.
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/contexts.h93
-rw-r--r--src/parser/parsers.h91
2 files changed, 114 insertions, 70 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 6dabfca3d..f58275d71 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -105,24 +105,21 @@ struct NullTypeParserCtx {
using ElemListT = Ok;
using DataStringT = Ok;
- HeapTypeT makeFuncType() { return Ok{}; }
- HeapTypeT makeAnyType() { return Ok{}; }
- HeapTypeT makeExternType() { return Ok{}; }
- HeapTypeT makeEqType() { return Ok{}; }
- HeapTypeT makeI31Type() { return Ok{}; }
- HeapTypeT makeStructType() { return Ok{}; }
- HeapTypeT makeArrayType() { return Ok{}; }
- HeapTypeT makeExnType() { return Ok{}; }
- HeapTypeT makeStringType() { return Ok{}; }
- HeapTypeT makeStringViewWTF8Type() { return Ok{}; }
- HeapTypeT makeStringViewWTF16Type() { return Ok{}; }
- HeapTypeT makeStringViewIterType() { return Ok{}; }
- HeapTypeT makeContType() { return Ok{}; }
- HeapTypeT makeNoneType() { return Ok{}; }
- HeapTypeT makeNoextType() { return Ok{}; }
- HeapTypeT makeNofuncType() { return Ok{}; }
- HeapTypeT makeNoexnType() { return Ok{}; }
- HeapTypeT makeNocontType() { return Ok{}; }
+ HeapTypeT makeFuncType(Shareability) { return Ok{}; }
+ HeapTypeT makeAnyType(Shareability) { return Ok{}; }
+ HeapTypeT makeExternType(Shareability) { return Ok{}; }
+ HeapTypeT makeEqType(Shareability) { return Ok{}; }
+ HeapTypeT makeI31Type(Shareability) { return Ok{}; }
+ HeapTypeT makeStructType(Shareability) { return Ok{}; }
+ HeapTypeT makeArrayType(Shareability) { return Ok{}; }
+ HeapTypeT makeExnType(Shareability) { return Ok{}; }
+ HeapTypeT makeStringType(Shareability) { return Ok{}; }
+ HeapTypeT makeContType(Shareability) { return Ok{}; }
+ HeapTypeT makeNoneType(Shareability) { return Ok{}; }
+ HeapTypeT makeNoextType(Shareability) { return Ok{}; }
+ HeapTypeT makeNofuncType(Shareability) { return Ok{}; }
+ HeapTypeT makeNoexnType(Shareability) { return Ok{}; }
+ HeapTypeT makeNocontType(Shareability) { return Ok{}; }
TypeT makeI32() { return Ok{}; }
TypeT makeI64() { return Ok{}; }
@@ -208,21 +205,51 @@ template<typename Ctx> struct TypeParserCtx {
Ctx& self() { return *static_cast<Ctx*>(this); }
- HeapTypeT makeFuncType() { return HeapType::func; }
- HeapTypeT makeAnyType() { return HeapType::any; }
- HeapTypeT makeExternType() { return HeapType::ext; }
- HeapTypeT makeEqType() { return HeapType::eq; }
- HeapTypeT makeI31Type() { return HeapType::i31; }
- HeapTypeT makeStructType() { return HeapType::struct_; }
- HeapTypeT makeArrayType() { return HeapType::array; }
- HeapTypeT makeExnType() { return HeapType::exn; }
- HeapTypeT makeStringType() { return HeapType::string; }
- HeapTypeT makeContType() { return HeapType::cont; }
- HeapTypeT makeNoneType() { return HeapType::none; }
- HeapTypeT makeNoextType() { return HeapType::noext; }
- HeapTypeT makeNofuncType() { return HeapType::nofunc; }
- HeapTypeT makeNoexnType() { return HeapType::noexn; }
- HeapTypeT makeNocontType() { return HeapType::nocont; }
+ HeapTypeT makeFuncType(Shareability share) {
+ return HeapTypes::func.getBasic(share);
+ }
+ HeapTypeT makeAnyType(Shareability share) {
+ return HeapTypes::any.getBasic(share);
+ }
+ HeapTypeT makeExternType(Shareability share) {
+ return HeapTypes::ext.getBasic(share);
+ }
+ HeapTypeT makeEqType(Shareability share) {
+ return HeapTypes::eq.getBasic(share);
+ }
+ HeapTypeT makeI31Type(Shareability share) {
+ return HeapTypes::i31.getBasic(share);
+ }
+ HeapTypeT makeStructType(Shareability share) {
+ return HeapTypes::struct_.getBasic(share);
+ }
+ HeapTypeT makeArrayType(Shareability share) {
+ return HeapTypes::array.getBasic(share);
+ }
+ HeapTypeT makeExnType(Shareability share) {
+ return HeapTypes::exn.getBasic(share);
+ }
+ HeapTypeT makeStringType(Shareability share) {
+ return HeapTypes::string.getBasic(share);
+ }
+ HeapTypeT makeContType(Shareability share) {
+ return HeapTypes::cont.getBasic(share);
+ }
+ HeapTypeT makeNoneType(Shareability share) {
+ return HeapTypes::none.getBasic(share);
+ }
+ HeapTypeT makeNoextType(Shareability share) {
+ return HeapTypes::noext.getBasic(share);
+ }
+ HeapTypeT makeNofuncType(Shareability share) {
+ return HeapTypes::nofunc.getBasic(share);
+ }
+ HeapTypeT makeNoexnType(Shareability share) {
+ return HeapTypes::noexn.getBasic(share);
+ }
+ HeapTypeT makeNocontType(Shareability share) {
+ return HeapTypes::nocont.getBasic(share);
+ }
TypeT makeI32() { return Type::i32; }
TypeT makeI64() { return Type::i64; }
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 1c329aecb..db450e3c6 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -27,6 +27,8 @@ namespace wasm::WATParser {
using namespace std::string_view_literals;
// Types
+template<typename Ctx>
+Result<typename Ctx::HeapTypeT> absheaptype(Ctx&, Shareability);
template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::RefTypeT> maybeRefType(Ctx&);
template<typename Ctx> Result<typename Ctx::RefTypeT> reftype(Ctx&);
@@ -358,58 +360,73 @@ template<typename Ctx> Result<> module(Ctx&);
// Types
// =====
-// heaptype ::= x:typeidx => types[x]
-// | 'func' => func
-// | 'extern' => extern
-template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx& ctx) {
+// absheaptype ::= 'func' | 'extern' | ...
+template<typename Ctx>
+Result<typename Ctx::HeapTypeT> absheaptype(Ctx& ctx, Shareability share) {
if (ctx.in.takeKeyword("func"sv)) {
- return ctx.makeFuncType();
+ return ctx.makeFuncType(share);
}
if (ctx.in.takeKeyword("any"sv)) {
- return ctx.makeAnyType();
+ return ctx.makeAnyType(share);
}
if (ctx.in.takeKeyword("extern"sv)) {
- return ctx.makeExternType();
+ return ctx.makeExternType(share);
}
if (ctx.in.takeKeyword("eq"sv)) {
- return ctx.makeEqType();
+ return ctx.makeEqType(share);
}
if (ctx.in.takeKeyword("i31"sv)) {
- return ctx.makeI31Type();
+ return ctx.makeI31Type(share);
}
if (ctx.in.takeKeyword("struct"sv)) {
- return ctx.makeStructType();
+ return ctx.makeStructType(share);
}
if (ctx.in.takeKeyword("array"sv)) {
- return ctx.makeArrayType();
+ return ctx.makeArrayType(share);
}
if (ctx.in.takeKeyword("exn"sv)) {
- return ctx.makeExnType();
+ return ctx.makeExnType(share);
}
if (ctx.in.takeKeyword("string"sv)) {
- return ctx.makeStringType();
+ return ctx.makeStringType(share);
}
if (ctx.in.takeKeyword("cont"sv)) {
- return ctx.makeContType();
+ return ctx.makeContType(share);
}
if (ctx.in.takeKeyword("none"sv)) {
- return ctx.makeNoneType();
+ return ctx.makeNoneType(share);
}
if (ctx.in.takeKeyword("noextern"sv)) {
- return ctx.makeNoextType();
+ return ctx.makeNoextType(share);
}
if (ctx.in.takeKeyword("nofunc"sv)) {
- return ctx.makeNofuncType();
+ return ctx.makeNofuncType(share);
}
if (ctx.in.takeKeyword("noexn"sv)) {
- return ctx.makeNoexnType();
+ return ctx.makeNoexnType(share);
}
if (ctx.in.takeKeyword("nocont"sv)) {
- return ctx.makeNocontType();
+ return ctx.makeNocontType(share);
}
- auto type = typeidx(ctx);
- CHECK_ERR(type);
- return *type;
+ return ctx.in.err("expected abstract heap type");
+}
+
+// heaptype ::= x:typeidx => types[x]
+// | t:absheaptype => unshared t
+// | '(' 'shared' t:absheaptype ')' => shared t
+template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx& ctx) {
+ if (auto t = maybeTypeidx(ctx)) {
+ CHECK_ERR(t);
+ return *t;
+ }
+
+ auto share = ctx.in.takeSExprStart("shared"sv) ? Shared : Unshared;
+ auto t = absheaptype(ctx, share);
+ CHECK_ERR(t);
+ if (share == Shared && !ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of shared abstract heap type");
+ }
+ return *t;
}
// reftype ::= 'funcref' => funcref
@@ -422,49 +439,49 @@ template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx& ctx) {
// | '(' ref null? t:heaptype ')' => ref null? t
template<typename Ctx> MaybeResult<typename Ctx::TypeT> maybeReftype(Ctx& ctx) {
if (ctx.in.takeKeyword("funcref"sv)) {
- return ctx.makeRefType(ctx.makeFuncType(), Nullable);
+ return ctx.makeRefType(ctx.makeFuncType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("externref"sv)) {
- return ctx.makeRefType(ctx.makeExternType(), Nullable);
+ return ctx.makeRefType(ctx.makeExternType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("anyref"sv)) {
- return ctx.makeRefType(ctx.makeAnyType(), Nullable);
+ return ctx.makeRefType(ctx.makeAnyType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("eqref"sv)) {
- return ctx.makeRefType(ctx.makeEqType(), Nullable);
+ return ctx.makeRefType(ctx.makeEqType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("i31ref"sv)) {
- return ctx.makeRefType(ctx.makeI31Type(), Nullable);
+ return ctx.makeRefType(ctx.makeI31Type(Unshared), Nullable);
}
if (ctx.in.takeKeyword("structref"sv)) {
- return ctx.makeRefType(ctx.makeStructType(), Nullable);
+ return ctx.makeRefType(ctx.makeStructType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("arrayref"sv)) {
- return ctx.makeRefType(ctx.makeArrayType(), Nullable);
+ return ctx.makeRefType(ctx.makeArrayType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("exnref"sv)) {
- return ctx.makeRefType(ctx.makeExnType(), Nullable);
+ return ctx.makeRefType(ctx.makeExnType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("stringref"sv)) {
- return ctx.makeRefType(ctx.makeStringType(), Nullable);
+ return ctx.makeRefType(ctx.makeStringType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("contref"sv)) {
- return ctx.makeRefType(ctx.makeContType(), Nullable);
+ return ctx.makeRefType(ctx.makeContType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("nullref"sv)) {
- return ctx.makeRefType(ctx.makeNoneType(), Nullable);
+ return ctx.makeRefType(ctx.makeNoneType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("nullexternref"sv)) {
- return ctx.makeRefType(ctx.makeNoextType(), Nullable);
+ return ctx.makeRefType(ctx.makeNoextType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("nullfuncref"sv)) {
- return ctx.makeRefType(ctx.makeNofuncType(), Nullable);
+ return ctx.makeRefType(ctx.makeNofuncType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("nullexnref"sv)) {
- return ctx.makeRefType(ctx.makeNoexnType(), Nullable);
+ return ctx.makeRefType(ctx.makeNoexnType(Unshared), Nullable);
}
if (ctx.in.takeKeyword("nullcontref"sv)) {
- return ctx.makeRefType(ctx.makeNocontType(), Nullable);
+ return ctx.makeRefType(ctx.makeNocontType(Unshared), Nullable);
}
if (!ctx.in.takeSExprStart("ref"sv)) {