summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/gc/ref-global.js
blob: 1e2a87edc63cc37a1cc8a4030d14bc5feae2c36a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// |jit-test| skip-if: !wasmGcEnabled()

// Basic private-to-module functionality.  At the moment all we have is null
// pointers, not very exciting.

{
    let bin = wasmTextToBinary(
        `(module
          (type $point (struct
                        (field $x f64)
                        (field $y f64)))

          (global $g1 (mut (ref null $point)) (ref.null $point))
          (global $g2 (mut (ref null $point)) (ref.null $point))
          (global $g3 (ref null $point) (ref.null $point))

          ;; Restriction: cannot expose Refs outside the module, not even
          ;; as a return value.  See ref-restrict.js.

          (func (export "get") (result eqref)
           (global.get $g1))

          (func (export "copy")
           (global.set $g2 (global.get $g1)))

          (func (export "clear")
           (global.set $g1 (global.get $g3))
           (global.set $g2 (ref.null $point))))`);

    let mod = new WebAssembly.Module(bin);
    let ins = new WebAssembly.Instance(mod).exports;

    assertEq(ins.get(), null);
    ins.copy();                 // Should not crash
    ins.clear();                // Should not crash
}

// Global with struct type

{
    let bin = wasmTextToBinary(
        `(module
          (type $point (struct
                        (field $x f64)
                        (field $y f64)))

          (global $glob (mut (ref null $point)) (ref.null $point))

          (func (export "init")
           (global.set $glob (struct.new $point (f64.const 0.5) (f64.const 2.75))))

          (func (export "change")
           (global.set $glob (struct.new $point (f64.const 3.5) (f64.const 37.25))))

          (func (export "clear")
           (global.set $glob (ref.null $point)))

          (func (export "x") (result f64)
           (struct.get $point 0 (global.get $glob)))

          (func (export "y") (result f64)
           (struct.get $point 1 (global.get $glob))))`);

    let mod = new WebAssembly.Module(bin);
    let ins = new WebAssembly.Instance(mod).exports;

    assertErrorMessage(() => ins.x(), WebAssembly.RuntimeError, /dereferencing null pointer/);

    ins.init();
    assertEq(ins.x(), 0.5);
    assertEq(ins.y(), 2.75);

    ins.change();
    assertEq(ins.x(), 3.5);
    assertEq(ins.y(), 37.25);

    ins.clear();
    assertErrorMessage(() => ins.x(), WebAssembly.RuntimeError, /dereferencing null pointer/);
}

// Global value of type externref for initializer from a WebAssembly.Global,
// just check that it works.
{
    let bin = wasmTextToBinary(
        `(module
          (import "" "g" (global $g externref))
          (global $glob externref (global.get $g))
          (func (export "get") (result externref)
           (global.get $glob)))`);

    let mod = new WebAssembly.Module(bin);
    let obj = {zappa:37};
    let g = new WebAssembly.Global({value: "externref"}, obj);
    let ins = new WebAssembly.Instance(mod, {"":{g}}).exports;
    assertEq(ins.get(), obj);
}