v8/test/mjsunit/wasm/wasm-gc-js-roundtrip.js
Manos Koukoutos c9063b7e86 [wasm-gc] Fix and extend JS roundtrip for gc types
Changes:
- Wrap eqref and i31ref objects in the temporary wasm object wrapper
  (in addition to dataref and anyref). Accept those types in
  IsJSCompatibleSignature().
- Handle null correctly in all cases (i.e., do not wrap/unwrap it).
- Improve some error messages.
- Handle kRttWithDepth in one case where it was omitted.
- Some small structure improvements.
- Add an extensive test.

Bug: v8:7748, v8:11606
Change-Id: Ie519f2c87421664dd02cf29fe94f9a9d7510bae2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2794422
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73725}
2021-03-30 16:09:22 +00:00

150 lines
5.6 KiB
JavaScript

// Copyright 2021 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
load('test/mjsunit/wasm/wasm-module-builder.js');
let instance = (() => {
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)]);
let array = builder.addArray(kWasmF64, true);
let sig = builder.addType(makeSig([kWasmI32], [kWasmI32]));
let func = builder.addFunction('inc', sig)
.addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add])
.exportAs('inc');
builder.addFunction('struct_producer', makeSig([], [kWasmDataRef]))
.addBody([
kGCPrefix, kExprRttCanon, struct, kGCPrefix, kExprStructNewDefault,
struct
])
.exportFunc();
builder.addFunction('array_producer', makeSig([], [kWasmDataRef]))
.addBody([
kExprI32Const, 10, kGCPrefix, kExprRttCanon, array, kGCPrefix,
kExprArrayNewDefault, array
])
.exportFunc();
builder.addFunction('i31_producer', makeSig([], [kWasmI31Ref]))
.addBody([kExprI32Const, 5, kGCPrefix, kExprI31New])
.exportFunc();
builder.addFunction('func_producer', makeSig([], [wasmRefType(sig)]))
.addBody([kExprRefFunc, func.index])
.exportFunc();
let test_types = {
i31: kWasmI31Ref,
struct: kWasmDataRef,
array: kWasmDataRef,
raw_struct: struct,
raw_array: array,
typed_func: sig,
data: kWasmDataRef,
eq: kWasmEqRef,
func: kWasmFuncRef,
any: kWasmAnyRef,
};
for (key in test_types) {
let type = wasmOptRefType(test_types[key]);
builder.addFunction(key + '_id', makeSig([type], [type]))
.addBody([kExprLocalGet, 0])
.exportFunc();
builder.addFunction(key + '_null', makeSig([], [type]))
.addBody([kExprRefNull, test_types[key]])
.exportFunc();
}
return builder.instantiate({});
})();
// Wasm-exposed null is the same as JS null.
assertEquals(instance.exports.struct_null(), null);
// We can roundtrip an i31.
instance.exports.i31_id(instance.exports.i31_producer());
// We can roundtrip any null as i31.
instance.exports.i31_id(instance.exports.i31_null());
instance.exports.i31_id(instance.exports.struct_null());
// We cannot roundtrip a struct as i31.
assertThrows(
() => instance.exports.i31_id(instance.exports.struct_producer()),
TypeError, 'type incompatibility when transforming from/to JS');
// We can roundtrip a struct as dataref.
instance.exports.data_id(instance.exports.struct_producer());
// We can roundtrip an array as dataref.
instance.exports.data_id(instance.exports.array_producer());
// We can roundtrip any null as dataref.
instance.exports.data_id(instance.exports.data_null());
instance.exports.data_id(instance.exports.i31_null());
// We cannot roundtrip an i31 as dataref.
assertThrows(
() => instance.exports.data_id(instance.exports.i31_producer()), TypeError,
'type incompatibility when transforming from/to JS');
// We can roundtrip a struct as eqref.
instance.exports.eq_id(instance.exports.struct_producer());
// We can roundtrip an array as eqref.
instance.exports.eq_id(instance.exports.array_producer());
// We can roundtrip an i31 as eqref.
instance.exports.eq_id(instance.exports.i31_producer());
// We can roundtrip any null as eqref.
instance.exports.eq_id(instance.exports.data_null());
instance.exports.eq_id(instance.exports.i31_null());
instance.exports.eq_id(instance.exports.func_null());
// We cannot roundtrip a func as eqref.
assertThrows(
() => instance.exports.eq_id(instance.exports.func_producer()), TypeError,
'type incompatibility when transforming from/to JS');
// We can roundtrip a struct as anyref.
instance.exports.any_id(instance.exports.struct_producer());
// We can roundtrip an array as anyref.
instance.exports.any_id(instance.exports.array_producer());
// We can roundtrip an i31 as anyref.
instance.exports.any_id(instance.exports.i31_producer());
// We can roundtrip a func as anyref.
instance.exports.any_id(instance.exports.func_producer());
// We can roundtrip any null as anyref.
instance.exports.any_id(instance.exports.data_null());
instance.exports.any_id(instance.exports.i31_null());
instance.exports.any_id(instance.exports.func_null());
// We can roundtrip a JS object as anyref.
instance.exports.any_id(instance);
// We can roundtrip a typed function.
instance.exports.typed_func_id(instance.exports.func_producer());
// We can roundtrip any null as typed funcion.
instance.exports.typed_func_id(instance.exports.i31_null());
instance.exports.typed_func_id(instance.exports.struct_null());
// We cannot roundtrip a struct as typed funcion.
assertThrows(
() => instance.exports.typed_func_id(instance.exports.struct_producer()),
TypeError, 'type incompatibility when transforming from/to JS');
// We can roundtrip a func.
instance.exports.func_id(instance.exports.func_producer());
// We can roundtrip any null as func.
instance.exports.func_id(instance.exports.i31_null());
instance.exports.func_id(instance.exports.struct_null());
// We cannot roundtrip an i31 as func.
assertThrows(
() => instance.exports.func_id(instance.exports.i31_producer()), TypeError,
'type incompatibility when transforming from/to JS');
// We cannot directly roundtrip structs or arrays.
// TODO(7748): Switch these tests once we can.
assertThrows(
() => instance.exports.raw_struct_id(instance.exports.struct_producer()),
TypeError, 'type incompatibility when transforming from/to JS');
assertThrows(
() => instance.exports.raw_array_id(instance.exports.array_producer()),
TypeError, 'type incompatibility when transforming from/to JS');