summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/wasm/jsapi/global/value-get-set.any.js
blob: f95b7ca9e3f0d54863db6dfd66ea76c9f392c132 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// META: global=window,dedicatedworker,jsshell

test(() => {
  const thisValues = [
    undefined,
    null,
    true,
    "",
    Symbol(),
    1,
    {},
    WebAssembly.Global,
    WebAssembly.Global.prototype,
  ];

  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
  assert_equals(typeof desc, "object");

  const getter = desc.get;
  assert_equals(typeof getter, "function");

  const setter = desc.set;
  assert_equals(typeof setter, "function");

  for (const thisValue of thisValues) {
    assert_throws_js(TypeError, () => getter.call(thisValue), `getter with this=${format_value(thisValue)}`);
    assert_throws_js(TypeError, () => setter.call(thisValue, 1), `setter with this=${format_value(thisValue)}`);
  }
}, "Branding");

for (const type of ["i32", "i64", "f32", "f64"]) {
  const [initial, value, invalid] = type === "i64" ? [0n, 1n, 2] : [0, 1, 2n];
  const immutableOptions = [
    [{}, "missing"],
    [{ "mutable": undefined }, "undefined"],
    [{ "mutable": null }, "null"],
    [{ "mutable": false }, "false"],
    [{ "mutable": "" }, "empty string"],
    [{ "mutable": 0 }, "zero"],
  ];
  for (const [opts, name] of immutableOptions) {
    test(() => {
      opts.value = type;
      const global = new WebAssembly.Global(opts);
      assert_equals(global.value, initial, "initial value");
      assert_equals(global.valueOf(), initial, "initial valueOf");

      assert_throws_js(TypeError, () => global.value = value);

      assert_equals(global.value, initial, "post-set value");
      assert_equals(global.valueOf(), initial, "post-set valueOf");
    }, `Immutable ${type} (${name})`);

    test(t => {
      opts.value = type;
      const global = new WebAssembly.Global(opts);
      assert_equals(global.value, initial, "initial value");
      assert_equals(global.valueOf(), initial, "initial valueOf");

      const value = {
        valueOf: t.unreached_func("should not call valueOf"),
        toString: t.unreached_func("should not call toString"),
      };
      assert_throws_js(TypeError, () => global.value = value);

      assert_equals(global.value, initial, "post-set value");
      assert_equals(global.valueOf(), initial, "post-set valueOf");
    }, `Immutable ${type} with ToNumber side-effects (${name})`);
  }

  const mutableOptions = [
    [{ "mutable": true }, "true"],
    [{ "mutable": 1 }, "one"],
    [{ "mutable": "x" }, "string"],
    [Object.create({ "mutable": true }), "true on prototype"],
  ];
  for (const [opts, name] of mutableOptions) {
    test(() => {
      opts.value = type;
      const global = new WebAssembly.Global(opts);
      assert_equals(global.value, initial, "initial value");
      assert_equals(global.valueOf(), initial, "initial valueOf");

      global.value = value;

      assert_throws_js(TypeError, () => global.value = invalid);

      assert_equals(global.value, value, "post-set value");
      assert_equals(global.valueOf(), value, "post-set valueOf");
    }, `Mutable ${type} (${name})`);
  }
}

test(() => {
  const argument = { "value": "i64", "mutable": true };
  const global = new WebAssembly.Global(argument);

  assert_equals(global.value, 0n, "initial value using ToJSValue");

  const valid = [
    [123n, 123n],
    [2n ** 63n, - (2n ** 63n)],
    [true, 1n],
    [false, 0n],
    ["456", 456n],
  ];
  for (const [input, output] of valid) {
    global.value = input;
    assert_equals(global.valueOf(), output, "post-set valueOf");
  }

  const invalid = [
    undefined,
    null,
    0,
    1,
    4.2,
    Symbol(),
  ];
  for (const input of invalid) {
    assert_throws_js(TypeError, () => global.value = input);
  }
}, "i64 mutability");

test(() => {
  const argument = { "value": "i32", "mutable": true };
  const global = new WebAssembly.Global(argument);
  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
  assert_equals(typeof desc, "object");

  const setter = desc.set;
  assert_equals(typeof setter, "function");

  assert_throws_js(TypeError, () => setter.call(global));
}, "Calling setter without argument");

test(() => {
  const argument = { "value": "i32", "mutable": true };
  const global = new WebAssembly.Global(argument);
  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
  assert_equals(typeof desc, "object");

  const getter = desc.get;
  assert_equals(typeof getter, "function");

  const setter = desc.set;
  assert_equals(typeof setter, "function");

  assert_equals(getter.call(global, {}), 0);
  assert_equals(setter.call(global, 1, {}), undefined);
  assert_equals(global.value, 1);
}, "Stray argument");