summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2022-06-18 09:37:09 -0700
committerGitHub <noreply@github.com>2022-06-18 09:37:09 -0700
commitbab21052c3e12df7ad2fd3711d0fe6e69e05f449 (patch)
tree0ff5e87412853db2253ade9373d95b118e68f892
parent4652398b62ce0546f015cdc2c7b3010938c7c5a9 (diff)
downloadbinaryen-bab21052c3e12df7ad2fd3711d0fe6e69e05f449.tar.gz
binaryen-bab21052c3e12df7ad2fd3711d0fe6e69e05f449.tar.bz2
binaryen-bab21052c3e12df7ad2fd3711d0fe6e69e05f449.zip
Do not emit recursion groups without GC enabled (#4738)
We emit nominal types as a single large recursion group, but this produces invalid modules when --nominal or --hybrid was used without GC enabled. Fix the bug by always emitting types as though they were structural (i.e. without recursion groups) when GC is not enabled. Fixes #4723.
-rw-r--r--src/wasm/wasm-binary.cpp9
-rw-r--r--test/lit/nominal-no-gc.wast20
2 files changed, 27 insertions, 2 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 6cbf880e3..c161a623b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -223,7 +223,12 @@ void WasmBinaryWriter::writeTypes() {
// the type section. With nominal typing there is always one group and with
// equirecursive typing there is one group per type.
size_t numGroups = 0;
- switch (getTypeSystem()) {
+ // MVP types are structural and do not use recursion groups.
+ TypeSystem typeSystem = getTypeSystem();
+ if (!wasm->features.hasGC()) {
+ typeSystem = TypeSystem::Equirecursive;
+ }
+ switch (typeSystem) {
case TypeSystem::Equirecursive:
numGroups = indexedTypes.types.size();
break;
@@ -242,7 +247,7 @@ void WasmBinaryWriter::writeTypes() {
BYN_TRACE("== writeTypes\n");
auto start = startSection(BinaryConsts::Section::Type);
o << U32LEB(numGroups);
- if (getTypeSystem() == TypeSystem::Nominal) {
+ if (typeSystem == TypeSystem::Nominal) {
// The nominal recursion group contains every type.
o << S32LEB(BinaryConsts::EncodedType::Rec)
<< U32LEB(indexedTypes.types.size());
diff --git a/test/lit/nominal-no-gc.wast b/test/lit/nominal-no-gc.wast
new file mode 100644
index 000000000..7247caa5a
--- /dev/null
+++ b/test/lit/nominal-no-gc.wast
@@ -0,0 +1,20 @@
+;; Write the module with --nominal but without GC
+;; RUN: wasm-opt %s --nominal --disable-gc -g -o %t.wasm
+
+;; We should not get any recursion groups even though we used --nominal. We use
+;; --hybrid -all here to make sure that any rec groups from the binary will
+;; actually show up in the output and cause the test to fail.
+;; RUN: wasm-opt %t.wasm --hybrid -all -S -o - | filecheck %s
+
+;; Also check that we don't get a failure with the default configuration.
+;; RUN: wasm-opt %t.wasm
+
+;; CHECK-NOT: rec
+
+(module
+ (type $foo (func))
+ (type $bar (func))
+
+ (func $f1 (type $foo))
+ (func $f2 (type $bar))
+)