diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/wasm/gc/value_subtyping.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | js/src/jit-test/tests/wasm/gc/value_subtyping.js | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/gc/value_subtyping.js b/js/src/jit-test/tests/wasm/gc/value_subtyping.js new file mode 100644 index 0000000000..bc0a3df678 --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/value_subtyping.js @@ -0,0 +1,305 @@ +// |jit-test| skip-if: !wasmGcEnabled() + +function simpleTypeSection(types) { + return types.map((x, i) => `(type \$${i} ${x})`).join('\n'); +} + +function assertSubtype(superType, subType, types) { + types = types || []; + wasmEvalText(`(module + ${types} + (func + unreachable + (block (param ${subType}) + (block (param ${superType}) + drop + ) + ) + ) + )`); +} + +function assertNotSubtype(superType, subType, types) { + assertErrorMessage(() => { + assertSubtype(superType, subType, types); + }, WebAssembly.CompileError, /type mismatch/); +} + +// Primitive trivial subtyping +assertSubtype('i32', 'i32'); +assertSubtype('i64', 'i64'); +assertSubtype('f32', 'f32'); +assertSubtype('f64', 'f64'); +assertSubtype('eqref', 'eqref'); +assertSubtype('funcref', 'funcref'); + +// No subtyping relation between funcref, anyref, externref. These are our top +// types. +assertNotSubtype('funcref', 'anyref'); +assertNotSubtype('anyref', 'funcref'); +assertNotSubtype('funcref', 'externref'); +assertNotSubtype('externref', 'funcref'); +assertNotSubtype('externref', 'anyref'); +assertNotSubtype('anyref', 'externref'); + +// eqref is a subtype of anyref +assertSubtype('anyref', 'eqref'); + +// structref is a subtype of eqref and anyref +assertSubtype('anyref', 'structref'); +assertSubtype('eqref', 'structref'); + +// arrayref is a subtype of eqref and anyref +assertSubtype('anyref', 'arrayref'); +assertSubtype('eqref', 'arrayref'); + +// Structs are subtypes of anyref, eqref, and structref +assertSubtype( + 'anyref', + '(ref 0)', + simpleTypeSection(['(struct)'])); +assertSubtype( + 'eqref', + '(ref 0)', + simpleTypeSection(['(struct)'])); +assertSubtype( + 'structref', + '(ref 0)', + simpleTypeSection(['(struct)'])); + +// Struct identity +assertSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection(['(struct)', '(struct)'])); +assertSubtype( + '(ref 1)', + '(ref 0)', + simpleTypeSection(['(struct)', '(struct)'])); + +// Self referential struct +assertSubtype( + '(ref 1)', + '(ref 0)', + simpleTypeSection(['(struct (ref 0))', '(struct (ref 1))'])); + +// Mutually referential structs +assertSubtype( + '(ref 2)', + '(ref 0)', + `(rec + (type (struct (ref 1))) + (type (struct (ref 0))) + ) + (rec + (type (struct (ref 3))) + (type (struct (ref 2))) + )`); + +// Struct subtypes can have extra fields +assertSubtype( + '(ref 0)', + '(ref 1)', + `(type (struct)) + (type (sub 0 (struct (field i32))))`); +assertSubtype( + '(ref 0)', + '(ref 1)', + `(type (struct)) + (type (sub 0 (struct (field i32) (field i32))))`); + +// Struct supertypes cannot have extra fields +assertNotSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(struct (field i32))', + '(struct)'])); + +// Struct field mutability must match +assertSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(struct (field (mut i32)))', + '(struct (field (mut i32)))'])); +assertSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(struct (field i32))', + '(struct (field i32))'])); +assertNotSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(struct (field (mut i32)))', + '(struct (field i32))'])); +assertNotSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(struct (field i32))', + '(struct (field (mut i32)))'])); + +// Struct fields are invariant when mutable +assertSubtype( + '(ref 2)', + '(ref 3)', + simpleTypeSection([ + '(struct)', + '(struct)', + '(struct (field (mut (ref 0))))', + '(struct (field (mut (ref 1))))'])); +assertNotSubtype( + '(ref 2)', + '(ref 3)', + simpleTypeSection([ + '(struct)', + '(struct (field i32))', + '(struct (field (mut (ref 0))))', + '(struct (field (mut (ref 1))))'])); + +// Struct fields are covariant when immutable +assertSubtype( + '(ref 2)', + '(ref 3)', + `(type (struct)) + (type (sub 0 (struct (field i32)))) + (type (struct (field (ref 0)))) + (type (sub 2 (struct (field (ref 1)))))`); + +// Arrays are subtypes of anyref, eqref, and arrayref +assertSubtype( + 'anyref', + '(ref 0)', + simpleTypeSection(['(array i32)'])); +assertSubtype( + 'eqref', + '(ref 0)', + simpleTypeSection(['(array i32)'])); +assertSubtype( + 'arrayref', + '(ref 0)', + simpleTypeSection(['(array i32)'])); + +// Array identity +assertSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection(['(array i32)', '(array i32)'])); +assertSubtype( + '(ref 1)', + '(ref 0)', + simpleTypeSection(['(array i32)', '(array i32)'])); + +// Self referential array +assertSubtype( + '(ref 1)', + '(ref 0)', + simpleTypeSection(['(array (ref 0))', '(array (ref 1))'])); + +// Mutually referential arrays +assertSubtype( + '(ref 2)', + '(ref 0)', + `(rec + (type (array (ref 1))) + (type (array (ref 0))) + ) + (rec + (type (array (ref 3))) + (type (array (ref 2))) + )`); + +// Array mutability must match +assertSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(array (mut i32))', + '(array (mut i32))'])); +assertSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(array i32)', + '(array i32)'])); +assertNotSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(array (mut i32))', + '(array i32)'])); +assertNotSubtype( + '(ref 0)', + '(ref 1)', + simpleTypeSection([ + '(array i32)', + '(array (mut i32))'])); + +// Array elements are invariant when mutable +assertSubtype( + '(ref 2)', + '(ref 3)', + simpleTypeSection([ + '(struct)', + '(struct)', + '(array (mut (ref 0)))', + '(array (mut (ref 1)))'])); +assertNotSubtype( + '(ref 2)', + '(ref 3)', + simpleTypeSection([ + '(struct)', + '(struct (field i32))', + '(array (mut (ref 0)))', + '(array (mut (ref 1)))'])); + +// Array elements are covariant when immutable +assertSubtype( + '(ref 2)', + '(ref 3)', + `(type (struct)) + (type (sub 0 (struct (field i32)))) + (type (array (ref 0))) + (type (sub 2 (array (ref 1))))`); + +// nullref is a subtype of everything in anyref hierarchy +assertSubtype('anyref', 'nullref'); +assertSubtype('eqref', 'nullref'); +assertSubtype('structref', 'nullref'); +assertSubtype('arrayref', 'nullref'); +assertSubtype('(ref null 0)', 'nullref', simpleTypeSection(['(struct)'])); +assertSubtype('(ref null 0)', 'nullref', simpleTypeSection(['(array i32)'])); + +// nullref is not a subtype of any other hierarchy +assertNotSubtype('funcref', 'nullref'); +assertNotSubtype('(ref null 0)', 'nullref', simpleTypeSection(['(func)'])); +assertNotSubtype('externref', 'nullref'); + +// nullfuncref is a subtype of everything in funcref hierarchy +assertSubtype('funcref', 'nullfuncref'); +assertSubtype('(ref null 0)', 'nullfuncref', simpleTypeSection(['(func)'])); + +// nullfuncref is not a subtype of any other hierarchy +assertNotSubtype('anyref', 'nullfuncref'); +assertNotSubtype('eqref', 'nullfuncref'); +assertNotSubtype('structref', 'nullfuncref'); +assertNotSubtype('arrayref', 'nullfuncref'); +assertNotSubtype('externref', 'nullfuncref'); +assertNotSubtype('(ref null 0)', 'nullfuncref', simpleTypeSection(['(struct)'])); +assertNotSubtype('(ref null 0)', 'nullfuncref', simpleTypeSection(['(array i32)'])); + +// nullexternref is a subtype of everything in externref hierarchy +assertSubtype('externref', 'nullexternref'); + +// nullexternref is not a subtype of any other hierarchy +assertNotSubtype('anyref', 'nullexternref'); +assertNotSubtype('eqref', 'nullexternref'); +assertNotSubtype('structref', 'nullexternref'); +assertNotSubtype('arrayref', 'nullexternref'); +assertNotSubtype('funcref', 'nullexternref'); +assertNotSubtype('(ref null 0)', 'nullexternref', simpleTypeSection(['(struct)'])); +assertNotSubtype('(ref null 0)', 'nullexternref', simpleTypeSection(['(array i32)'])); +assertNotSubtype('(ref null 0)', 'nullexternref', simpleTypeSection(['(func)'])); |