Source code

Revision control

Copy as Markdown

Other Tools

// |jit-test| skip-if: !wasmGcEnabled()
// We can read the object fields from JS via a builtin
{
let ins = wasmEvalText(`(module
(type $p (struct (field f64) (field (mut i32))))
(func (export "mkp") (result eqref)
(struct.new $p (f64.const 1.5) (i32.const 33))))`).exports;
let p = ins.mkp();
assertEq(wasmGcReadField(p, 0), 1.5);
assertEq(wasmGcReadField(p, 1), 33);
assertErrorMessage(() => wasmGcReadField(p, 2), WebAssembly.RuntimeError, /index out of bounds/);
}
// Fields can't be modified from JS.
{
let ins = wasmEvalText(`(module
(type $p (struct (field f64)))
(func (export "mkp") (result eqref)
(struct.new $p (f64.const 1.5))))`).exports;
let p = ins.mkp();
assertErrorMessage(() => p[0] = 5.7, TypeError, /can't modify/);
}
// MVA v1 restriction: structs have no prototype
{
let ins = wasmEvalText(`(module
(type $q (struct (field (mut f64))))
(type $p (struct (field (mut (ref null $q)))))
(type $r (struct (field (mut eqref))))
(func (export "mkp") (result eqref)
(struct.new $p (ref.null $q)))
(func (export "mkr") (result eqref)
(struct.new $r (ref.null eq))))`).exports;
assertEq(Object.getPrototypeOf(ins.mkp()), null);
assertEq(Object.getPrototypeOf(ins.mkr()), null);
}
// MVA v1 restriction: all fields are immutable
{
let ins = wasmEvalText(`(module
(type $q (struct (field (mut f64))))
(type $p (struct (field (mut (ref null $q))) (field (mut eqref))))
(func (export "mkq") (result eqref)
(struct.new $q (f64.const 1.5)))
(func (export "mkp") (result eqref)
(struct.new $p (ref.null $q) (ref.null eq))))`).exports;
let q = ins.mkq();
assertEq(typeof q, "object");
assertEq(wasmGcReadField(q, 0), 1.5);
let p = ins.mkp();
assertEq(typeof p, "object");
assertEq(wasmGcReadField(p, 0), null);
assertErrorMessage(() => { p[0] = q }, TypeError, /can't modify/);
assertErrorMessage(() => { p[1] = q }, TypeError, /can't modify/);
}
// MVA v1 restriction: structs that expose i64 fields make those fields
// immutable from JS, and the structs are not constructible from JS.
{
let ins = wasmEvalText(`(module
(type $p (struct (field (mut i64))))
(func (export "mkp") (result eqref)
(struct.new $p (i64.const 0x1234567887654321))))`).exports;
let p = ins.mkp();
assertEq(typeof p, "object");
assertEq(wasmGcReadField(p, 0), 0x1234567887654321n)
assertErrorMessage(() => { p[0] = 0 }, TypeError, /can't modify/);
}
// A consequence of the current mapping of i64 as two i32 fields is that we run
// a risk of struct.narrow not recognizing the difference. So check this.
{
let ins = wasmEvalText(
`(module
(type $p (struct (field i64)))
(type $q (struct (field i32) (field i32)))
(func $f (param eqref) (result i32)
local.get 0
ref.test (ref $q)
)
(func $g (param eqref) (result i32)
local.get 0
ref.test (ref $p)
)
(func (export "t1") (result i32)
(call $f (struct.new $p (i64.const 0))))
(func (export "t2") (result i32)
(call $g (struct.new $q (i32.const 0) (i32.const 0)))))`).exports;
assertEq(ins.t1(), 0);
assertEq(ins.t2(), 0);
}