c9063b7e86
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}
150 lines
5.6 KiB
JavaScript
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');
|