v8/test/mjsunit/wasm/gc-casts-from-any.js
Matthias Liedtke 1688cad47f [wasm-gc] Add new ref.cast null taking any reference
This extends crrev.com/c/3948663 (ref.cast) by adding the new
"ref.cast null" which only behaves different for null for which
it doesn't trap but instead casts the null value to the target
(null)type.

Bug: v8:7748
Change-Id: I3ac85d83cc06c95af8830c1c60ae2f28414e2570
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3960329
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83934}
2022-10-26 15:06:50 +00:00

308 lines
15 KiB
JavaScript

// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-gc --no-wasm-gc-structref-as-dataref
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
(function TestRefTest() {
var builder = new WasmModuleBuilder();
let structSuper = builder.addStruct([makeField(kWasmI32, true)]);
let structSub = builder.addStruct([makeField(kWasmI32, true)], structSuper);
let array = builder.addArray(kWasmI32);
let fct =
builder.addFunction('createStructSuper',
makeSig([kWasmI32], [kWasmExternRef]))
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStructNew, structSuper,
kGCPrefix, kExprExternExternalize,
]).exportFunc();
builder.addFunction('createStructSub', makeSig([kWasmI32], [kWasmExternRef]))
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStructNew, structSub,
kGCPrefix, kExprExternExternalize,
]).exportFunc();
builder.addFunction('createArray', makeSig([kWasmI32], [kWasmExternRef]))
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprArrayNewFixed, array, 1,
kGCPrefix, kExprExternExternalize,
]).exportFunc();
builder.addFunction('createFuncRef', makeSig([], [kWasmFuncRef]))
.addBody([
kExprRefFunc, fct.index,
]).exportFunc();
[
["StructSuper", structSuper],
["StructSub", structSub],
["Array", array],
["I31", kI31RefCode],
["AnyArray", kArrayRefCode],
["Struct", kStructRefCode],
["Eq", kEqRefCode],
// 'ref.test any' is semantically the same as '!ref.is_null' here.
["Any", kAnyRefCode],
].forEach(([typeName, typeCode]) => {
builder.addFunction(`refTest${typeName}`,
makeSig([kWasmExternRef], [kWasmI32, kWasmI32]))
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprExternInternalize,
kGCPrefix, kExprRefTest, typeCode,
kExprLocalGet, 0,
kGCPrefix, kExprExternInternalize,
kGCPrefix, kExprRefTestNull, typeCode,
]).exportFunc();
builder.addFunction(`refCast${typeName}`,
makeSig([kWasmExternRef], [kWasmExternRef]))
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprExternInternalize,
kGCPrefix, kExprRefCast, typeCode,
kGCPrefix, kExprExternExternalize,
]).exportFunc();
builder.addFunction(`refCastNull${typeName}`,
makeSig([kWasmExternRef], [kWasmExternRef]))
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprExternInternalize,
kGCPrefix, kExprRefCastNull, typeCode,
kGCPrefix, kExprExternExternalize,
]).exportFunc();
});
var instance = builder.instantiate();
let wasm = instance.exports;
// result: [ref.test, ref.test null]
assertEquals([0, 1], wasm.refTestStructSuper(null));
assertEquals([0, 0], wasm.refTestStructSuper(undefined));
assertEquals([1, 1], wasm.refTestStructSuper(wasm.createStructSuper()));
assertEquals([1, 1], wasm.refTestStructSuper(wasm.createStructSub()));
assertEquals([0, 0], wasm.refTestStructSuper(wasm.createArray()));
assertEquals([0, 0], wasm.refTestStructSuper(wasm.createFuncRef()));
assertEquals([0, 0], wasm.refTestStructSuper(1));
assertEquals([0, 0], wasm.refTestStructSuper({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestStructSub(null));
assertEquals([0, 0], wasm.refTestStructSub(undefined));
assertEquals([0, 0], wasm.refTestStructSub(wasm.createStructSuper()));
assertEquals([1, 1], wasm.refTestStructSub(wasm.createStructSub()));
assertEquals([0, 0], wasm.refTestStructSub(wasm.createArray()));
assertEquals([0, 0], wasm.refTestStructSub(wasm.createFuncRef()));
assertEquals([0, 0], wasm.refTestStructSub(1));
assertEquals([0, 0], wasm.refTestStructSub({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestArray(null));
assertEquals([0, 0], wasm.refTestArray(undefined));
assertEquals([0, 0], wasm.refTestArray(wasm.createStructSuper()));
assertEquals([0, 0], wasm.refTestArray(wasm.createStructSub()));
assertEquals([1, 1], wasm.refTestArray(wasm.createArray()));
assertEquals([0, 0], wasm.refTestArray(wasm.createFuncRef()));
assertEquals([0, 0], wasm.refTestArray(1));
assertEquals([0, 0], wasm.refTestArray({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestI31(null));
assertEquals([0, 0], wasm.refTestI31(undefined));
assertEquals([0, 0], wasm.refTestI31(wasm.createStructSuper()));
assertEquals([0, 0], wasm.refTestI31(wasm.createStructSub()));
assertEquals([0, 0], wasm.refTestI31(wasm.createArray()));
assertEquals([0, 0], wasm.refTestI31(wasm.createFuncRef()));
assertEquals([1, 1], wasm.refTestI31(1));
assertEquals([0, 0], wasm.refTestI31({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestAnyArray(null));
assertEquals([0, 0], wasm.refTestAnyArray(undefined));
assertEquals([0, 0], wasm.refTestAnyArray(wasm.createStructSuper()));
assertEquals([0, 0], wasm.refTestAnyArray(wasm.createStructSub()));
assertEquals([1, 1], wasm.refTestAnyArray(wasm.createArray()));
assertEquals([0, 0], wasm.refTestAnyArray(wasm.createFuncRef()));
assertEquals([0, 0], wasm.refTestAnyArray(1));
assertEquals([0, 0], wasm.refTestAnyArray({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestStruct(null));
assertEquals([0, 0], wasm.refTestStruct(undefined));
assertEquals([1, 1], wasm.refTestStruct(wasm.createStructSuper()));
assertEquals([1, 1], wasm.refTestStruct(wasm.createStructSub()));
assertEquals([0, 0], wasm.refTestStruct(wasm.createArray()));
assertEquals([0, 0], wasm.refTestStruct(wasm.createFuncRef()));
assertEquals([0, 0], wasm.refTestStruct(1));
assertEquals([0, 0], wasm.refTestStruct({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestEq(null));
assertEquals([0, 0], wasm.refTestEq(undefined));
assertEquals([1, 1], wasm.refTestEq(wasm.createStructSuper()));
assertEquals([1, 1], wasm.refTestEq(wasm.createStructSub()));
assertEquals([1, 1], wasm.refTestEq(wasm.createArray()));
assertEquals([0, 0], wasm.refTestEq(wasm.createFuncRef()));
assertEquals([1, 1], wasm.refTestEq(1)); // ref.i31
assertEquals([0, 0], wasm.refTestEq({'JavaScript': 'Object'}));
assertEquals([0, 1], wasm.refTestAny(null));
assertEquals([1, 1], wasm.refTestAny(undefined));
assertEquals([1, 1], wasm.refTestAny(wasm.createStructSuper()));
assertEquals([1, 1], wasm.refTestAny(wasm.createStructSub()));
assertEquals([1, 1], wasm.refTestAny(wasm.createArray()));
assertEquals([1, 1], wasm.refTestAny(wasm.createFuncRef()));
assertEquals([1, 1], wasm.refTestAny(1)); // ref.i31
assertEquals([1, 1], wasm.refTestAny({'JavaScript': 'Object'}));
// ref.cast
let structSuperObj = wasm.createStructSuper();
let structSubObj = wasm.createStructSub();
let arrayObj = wasm.createArray();
let jsObj = {'JavaScript': 'Object'};
let funcObj = wasm.createFuncRef();
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSuper(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSuper(undefined));
assertSame(structSuperObj, wasm.refCastStructSuper(structSuperObj));
assertSame(structSubObj, wasm.refCastStructSuper(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSuper(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSuper(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSuper(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSuper(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(structSuperObj));
assertSame(structSubObj, wasm.refCastStructSub(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastStructSub(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(structSuperObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(structSubObj));
assertSame(arrayObj, wasm.refCastArray(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastArray(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(structSuperObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(funcObj));
assertEquals(1, wasm.refCastI31(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastI31(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(structSuperObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(structSubObj));
assertSame(arrayObj, wasm.refCastAnyArray(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastAnyArray(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStruct(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastStruct(undefined));
assertSame(structSuperObj, wasm.refCastStruct(structSuperObj));
assertSame(structSubObj, wasm.refCastStruct(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStruct(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStruct(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastStruct(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastStruct(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastEq(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastEq(undefined));
assertSame(structSuperObj, wasm.refCastEq(structSuperObj));
assertSame(structSubObj, wasm.refCastEq(structSubObj));
assertSame(arrayObj, wasm.refCastEq(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastEq(funcObj));
assertEquals(1, wasm.refCastEq(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastEq(jsObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastAny(null));
assertSame(undefined, wasm.refCastAny(undefined));
assertSame(structSuperObj, wasm.refCastAny(structSuperObj));
assertSame(structSubObj, wasm.refCastAny(structSubObj));
assertSame(arrayObj, wasm.refCastAny(arrayObj));
assertSame(funcObj, wasm.refCastAny(funcObj));
assertEquals(1, wasm.refCastAny(1));
assertSame(jsObj, wasm.refCastAny(jsObj));
// ref.cast null
assertSame(null, wasm.refCastNullStructSuper(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSuper(undefined));
assertSame(structSuperObj, wasm.refCastNullStructSuper(structSuperObj));
assertSame(structSubObj, wasm.refCastNullStructSuper(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSuper(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSuper(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSuper(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSuper(jsObj));
assertSame(null, wasm.refCastNullStructSub(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSub(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSub(structSuperObj));
assertSame(structSubObj, wasm.refCastNullStructSub(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSub(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSub(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSub(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStructSub(jsObj));
assertSame(null, wasm.refCastNullArray(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullArray(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullArray(structSuperObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullArray(structSubObj));
assertSame(arrayObj, wasm.refCastNullArray(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullArray(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullArray(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullArray(jsObj));
assertSame(null, wasm.refCastNullI31(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullI31(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullI31(structSuperObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullI31(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullI31(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullI31(funcObj));
assertEquals(1, wasm.refCastNullI31(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullI31(jsObj));
assertSame(null, wasm.refCastNullAnyArray(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullAnyArray(undefined));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullAnyArray(structSuperObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullAnyArray(structSubObj));
assertSame(arrayObj, wasm.refCastNullAnyArray(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullAnyArray(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullAnyArray(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullAnyArray(jsObj));
assertSame(null, wasm.refCastNullStruct(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStruct(undefined));
assertSame(structSuperObj, wasm.refCastNullStruct(structSuperObj));
assertSame(structSubObj, wasm.refCastNullStruct(structSubObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStruct(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStruct(funcObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStruct(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullStruct(jsObj));
assertSame(null, wasm.refCastNullEq(null));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullEq(undefined));
assertSame(structSuperObj, wasm.refCastNullEq(structSuperObj));
assertSame(structSubObj, wasm.refCastNullEq(structSubObj));
assertSame(arrayObj, wasm.refCastNullEq(arrayObj));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullEq(funcObj));
assertEquals(1, wasm.refCastNullEq(1));
assertTraps(kTrapIllegalCast, () => wasm.refCastNullEq(jsObj));
assertSame(null, wasm.refCastNullAny(null));
assertSame(undefined, wasm.refCastNullAny(undefined));
assertSame(structSuperObj, wasm.refCastNullAny(structSuperObj));
assertSame(structSubObj, wasm.refCastNullAny(structSubObj));
assertSame(arrayObj, wasm.refCastNullAny(arrayObj));
assertSame(funcObj, wasm.refCastNullAny(funcObj));
assertEquals(1, wasm.refCastNullAny(1));
assertSame(jsObj, wasm.refCastNullAny(jsObj));
})();