diff --git a/test/inspector/debugger/wasm-gc-anyref.js b/test/inspector/debugger/wasm-gc-anyref.js index db06d325a0..5ef0dc7a46 100644 --- a/test/inspector/debugger/wasm-gc-anyref.js +++ b/test/inspector/debugger/wasm-gc-anyref.js @@ -66,6 +66,7 @@ async function printPauseLocationsAndContinue(msg) { async function instantiateWasm() { var builder = new WasmModuleBuilder(); + builder.startRecGroup(); let struct_type = builder.addStruct([makeField(kWasmI32, false)]); let array_type = builder.addArray(kWasmI32); let imported_ref_table = @@ -128,7 +129,7 @@ async function instantiateWasm() { .addLocals(kWasmAnyRef, 1, ['anyref_local_null']) .addBody(body) .exportFunc(); - + builder.endRecGroup(); var module_bytes = builder.toArray(); breakpointLocation = main.body_offset + body.length - 1; diff --git a/test/mjsunit/regress/wasm/regress-12874.js b/test/mjsunit/regress/wasm/regress-12874.js index 58a9146ebb..b670322348 100644 --- a/test/mjsunit/regress/wasm/regress-12874.js +++ b/test/mjsunit/regress/wasm/regress-12874.js @@ -9,10 +9,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); var builder = new WasmModuleBuilder(); -var sig_index = builder.addType({params: [kWasmStructRef], results: [kWasmI32]}); - +builder.startRecGroup(); +var sig_index = builder.addType({params: [kWasmStructRef], + results: [kWasmI32]}); var sub1 = builder.addStruct([makeField(kWasmI32, true)]); var sub2 = builder.addStruct([makeField(kWasmI32, false)]); +builder.endRecGroup(); builder.addFunction('producer', makeSig([], [kWasmStructRef])) .addBody([ diff --git a/test/mjsunit/regress/wasm/regress-12945.js b/test/mjsunit/regress/wasm/regress-12945.js index a681465db3..3dc72fa13f 100644 --- a/test/mjsunit/regress/wasm/regress-12945.js +++ b/test/mjsunit/regress/wasm/regress-12945.js @@ -8,9 +8,11 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); let builder = new WasmModuleBuilder(); let i32_field = makeField(kWasmI32, true); +builder.startRecGroup(); let supertype = builder.addStruct([i32_field]); let sub1 = builder.addStruct([i32_field, i32_field], supertype); let sub2 = builder.addStruct([i32_field, makeField(kWasmF64, true)], supertype); +builder.endRecGroup(); let sig = makeSig([wasmRefNullType(supertype)], [kWasmI32]); let callee = builder.addFunction("callee", sig).addBody([ diff --git a/test/mjsunit/wasm/call_indirect.js b/test/mjsunit/wasm/call_indirect.js index b3621687b4..6f482a4ab1 100644 --- a/test/mjsunit/wasm/call_indirect.js +++ b/test/mjsunit/wasm/call_indirect.js @@ -48,8 +48,6 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); let exporting_instance = (function() { const builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); - let struct_mistyped = builder.addStruct([]); let struct = builder.addStruct([makeField(kWasmI32, true)]); @@ -72,8 +70,6 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); const builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); - // Have these in the reverse order than before. let struct = builder.addStruct([makeField(kWasmI32, true)]); let struct_mistyped = builder.addStruct([]); diff --git a/test/mjsunit/wasm/gc-casts-from-any.js b/test/mjsunit/wasm/gc-casts-from-any.js index 845d335b0c..4dd8e9a937 100644 --- a/test/mjsunit/wasm/gc-casts-from-any.js +++ b/test/mjsunit/wasm/gc-casts-from-any.js @@ -8,9 +8,11 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); (function TestRefTest() { var builder = new WasmModuleBuilder(); + builder.startRecGroup(); let structSuper = builder.addStruct([makeField(kWasmI32, true)]); let structSub = builder.addStruct([makeField(kWasmI32, true)], structSuper); let array = builder.addArray(kWasmI32); + builder.endRecGroup(); let fct = builder.addFunction('createStructSuper', diff --git a/test/mjsunit/wasm/gc-casts-subtypes.js b/test/mjsunit/wasm/gc-casts-subtypes.js index 7208c94bf0..9225a70a2f 100644 --- a/test/mjsunit/wasm/gc-casts-subtypes.js +++ b/test/mjsunit/wasm/gc-casts-subtypes.js @@ -11,9 +11,15 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); (function RefCastFromNull() { print(arguments.callee.name); let builder = new WasmModuleBuilder(); + builder.startRecGroup(); let structSuper = builder.addStruct([makeField(kWasmI32, true)]); + builder.endRecGroup(); + builder.startRecGroup(); let structSub = builder.addStruct([makeField(kWasmI32, true)], structSuper); + builder.endRecGroup(); + builder.startRecGroup(); let array = builder.addArray(kWasmI32); + builder.endRecGroup(); // Note: Casting between unrelated types is allowed as long as the types // belong to the same type hierarchy (func / any / extern). In these cases the diff --git a/test/mjsunit/wasm/gc-js-interop-helpers.js b/test/mjsunit/wasm/gc-js-interop-helpers.js index 2047862d16..3c39fc13bc 100644 --- a/test/mjsunit/wasm/gc-js-interop-helpers.js +++ b/test/mjsunit/wasm/gc-js-interop-helpers.js @@ -8,7 +8,6 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); function CreateWasmObjects() { let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let struct_type = builder.addStruct([makeField(kWasmI32, true)]); let array_type = builder.addArray(kWasmI32, true); builder.addFunction('MakeStruct', makeSig([], [kWasmExternRef])) diff --git a/test/mjsunit/wasm/gc-js-interop-import.mjs b/test/mjsunit/wasm/gc-js-interop-import.mjs index 41ee0e12f7..b6266ad4e8 100644 --- a/test/mjsunit/wasm/gc-js-interop-import.mjs +++ b/test/mjsunit/wasm/gc-js-interop-import.mjs @@ -8,7 +8,6 @@ import {struct, array} from 'gc-js-interop-export.mjs'; // Read struct and array with new wasm module. let builder = new WasmModuleBuilder(); -builder.setSingletonRecGroups(); let struct_type = builder.addStruct([makeField(kWasmI32, true)]); let array_type = builder.addArray(kWasmI32, true); builder.addFunction('readStruct', makeSig([kWasmExternRef], [kWasmI32])) diff --git a/test/mjsunit/wasm/reference-globals-import.js b/test/mjsunit/wasm/reference-globals-import.js index 456bc92af0..4aa1697fff 100644 --- a/test/mjsunit/wasm/reference-globals-import.js +++ b/test/mjsunit/wasm/reference-globals-import.js @@ -13,7 +13,6 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); let exporting_instance = (function() { let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let type_super = builder.addStruct([makeField(kWasmI32, false)]); let type_sub = builder.addStruct([makeField(kWasmI32, false)], type_super); @@ -64,7 +63,6 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); for (let[expected_valid, type, global] of tests) { print(`test ${type} imports ${global}`); let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let type_super = builder.addStruct([makeField(kWasmI32, false)]); let type_sub = builder.addStruct([makeField(kWasmI32, false)], type_super); @@ -105,7 +103,6 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); let exporting_instance = (function() { let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let type_super = builder.addStruct([makeField(kWasmI32, false)]); let type_sub = builder.addStruct([makeField(kWasmI32, false)], type_super); @@ -156,7 +153,6 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); for (let[expected_valid, type, imported_value] of tests) { print(`test ${type} imports ${imported_value}`); let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let type_super = builder.addStruct([makeField(kWasmI32, false)]); let type_sub = builder.addStruct([makeField(kWasmI32, false)], type_super); @@ -214,7 +210,6 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); let exporting_instance = (function() { let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let type_struct = builder.addStruct([makeField(kWasmI32, false)]); let type_array = builder.addArray(kWasmI32); diff --git a/test/mjsunit/wasm/reference-globals.js b/test/mjsunit/wasm/reference-globals.js index 821c2b1b27..88bd2bf3b3 100644 --- a/test/mjsunit/wasm/reference-globals.js +++ b/test/mjsunit/wasm/reference-globals.js @@ -12,8 +12,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); var exporting_instance = (function() { var builder = new WasmModuleBuilder(); + builder.startRecGroup(); var sig_index = builder.addType(kSig_i_ii); + builder.endRecGroup(); + builder.startRecGroup(); var wrong_sig_index = builder.addType(kSig_i_i); + builder.endRecGroup(); var addition_index = builder.addFunction("addition", sig_index) .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) @@ -110,7 +114,9 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); var builder = new WasmModuleBuilder(); + builder.startRecGroup(); var struct_index = builder.addStruct([{type: kWasmI32, mutability: true}]); + builder.endRecGroup(); var composite_struct_index = builder.addStruct( [{type: kWasmI32, mutability: true}, {type: wasmRefNullType(struct_index), mutability: true}, diff --git a/test/mjsunit/wasm/reference-tables.js b/test/mjsunit/wasm/reference-tables.js index c54fef5218..ed556ae5fa 100644 --- a/test/mjsunit/wasm/reference-tables.js +++ b/test/mjsunit/wasm/reference-tables.js @@ -425,8 +425,6 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); // Equivalent struct type. let builder = new WasmModuleBuilder(); - // Force type canonicalization for struct_type - builder.setSingletonRecGroups(); let struct_type = builder.addStruct([makeField(kWasmI32, false)]); let struct_type_invalid = builder.addStruct([makeField(kWasmI64, false)]); let struct_type_sub = builder.addStruct( @@ -473,7 +471,6 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let exporting_instance = (() => { let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let struct_type_base = builder.addStruct([makeField(kWasmI32, false)]); let struct_type = builder.addStruct([makeField(kWasmI32, false)], struct_type_base); @@ -482,7 +479,6 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); })(); let builder = new WasmModuleBuilder(); - builder.setSingletonRecGroups(); let struct_type_base = builder.addStruct([makeField(kWasmI32, false)]); let struct_type = builder.addStruct([makeField(kWasmI32, false)], struct_type_base); diff --git a/test/mjsunit/wasm/runtime-type-canonicalization.js b/test/mjsunit/wasm/runtime-type-canonicalization.js index 72bcae09af..832e5c017f 100644 --- a/test/mjsunit/wasm/runtime-type-canonicalization.js +++ b/test/mjsunit/wasm/runtime-type-canonicalization.js @@ -7,7 +7,6 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); let builder = new WasmModuleBuilder(); -builder.setSingletonRecGroups(); let struct_index = builder.addStruct([makeField(kWasmI32, true)]); let identical_struct_index = builder.addStruct([makeField(kWasmI32, true)]); diff --git a/test/mjsunit/wasm/type-based-optimizations.js b/test/mjsunit/wasm/type-based-optimizations.js index 5ac4debefb..f6bd1ac783 100644 --- a/test/mjsunit/wasm/type-based-optimizations.js +++ b/test/mjsunit/wasm/type-based-optimizations.js @@ -10,6 +10,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); // (by inspecting the resulting graph). (function WasmTypedOptimizationsTest() { let builder = new WasmModuleBuilder(); + builder.startRecGroup(); let top = builder.addStruct([makeField(kWasmI32, true)]); let middle = builder.addStruct([makeField(kWasmI32, true), makeField(kWasmI64, false)], @@ -22,6 +23,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); makeField(kWasmI64, false), makeField(kWasmI64, false)], middle); + builder.endRecGroup(); builder.addFunction("main", makeSig( [wasmRefType(bottom1), wasmRefType(bottom2)], [kWasmI32])) diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js index cf0299f9f3..f9ae8db8b8 100644 --- a/test/mjsunit/wasm/wasm-module-builder.js +++ b/test/mjsunit/wasm/wasm-module-builder.js @@ -1272,15 +1272,11 @@ class WasmModuleBuilder { this.element_segments = []; this.data_segments = []; this.explicit = []; + this.rec_groups = []; this.num_imported_funcs = 0; this.num_imported_globals = 0; this.num_imported_tables = 0; this.num_imported_tags = 0; - // If a wasm-gc type is detected, all types are put by default into a single - // recursive group. This field overrides this behavior and puts each type in - // a separate rec. group instead. - // TODO(7748): Support more flexible rec. groups. - this.singleton_rec_groups = false; return this; } @@ -1339,8 +1335,6 @@ class WasmModuleBuilder { this.explicit.push(this.createCustomSection(name, bytes)); } - // TODO(7748): Support recursive groups. - addType(type, supertype_idx = kNoSuperType) { var pl = type.params.length; // should have params var rl = type.results.length; // should have results @@ -1607,8 +1601,19 @@ class WasmModuleBuilder { return this; } - setSingletonRecGroups() { - this.singleton_rec_groups = true; + startRecGroup() { + this.rec_groups.push({start: this.types.length, size: 0}); + } + + endRecGroup() { + if (this.rec_groups.length == 0) { + throw new Error("Did not start a recursive group before ending one") + } + let last_element = this.rec_groups[this.rec_groups.length - 1] + if (last_element.size != 0) { + throw new Error("Did not start a recursive group before ending one") + } + last_element.size = this.types.length - last_element.start; } setName(name) { @@ -1627,17 +1632,23 @@ class WasmModuleBuilder { if (wasm.types.length > 0) { if (debug) print('emitting types @ ' + binary.length); binary.emit_section(kTypeSectionCode, section => { - // If any type is a wasm-gc type, wrap everything in a recursive group. - // TODO(7748): Support more flexible rec. groups. - if (!this.singleton_rec_groups && - wasm.types.findIndex(type => type instanceof WasmStruct || - type instanceof WasmArray) >= 0) { - section.emit_u32v(1); - section.emit_u8(kWasmRecursiveTypeGroupForm); + let length_with_groups = wasm.types.length; + for (let group of wasm.rec_groups) { + length_with_groups -= group.size - 1; } - section.emit_u32v(wasm.types.length); + section.emit_u32v(length_with_groups); - for (let type of wasm.types) { + let rec_group_index = 0; + + for (let i = 0; i < wasm.types.length; i++) { + if (rec_group_index < wasm.rec_groups.length && + wasm.rec_groups[rec_group_index].start == i) { + section.emit_u8(kWasmRecursiveTypeGroupForm); + section.emit_u32v(wasm.rec_groups[rec_group_index].size); + rec_group_index++; + } + + let type = wasm.types[i]; if (type.supertype != kNoSuperType) { section.emit_u8(kWasmSubtypeForm); section.emit_u8(1); // supertype count