• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// META: global=window,dedicatedworker,jsshell
2// META: script=/wasm/jsapi/wasm-module-builder.js
3// META: script=assertions.js
4
5let functions = {};
6setup(() => {
7  const builder = new WasmModuleBuilder();
8
9  builder
10    .addFunction("fn", kSig_v_d)
11    .addBody([])
12    .exportFunc();
13  builder
14    .addFunction("fn2", kSig_v_v)
15    .addBody([])
16    .exportFunc();
17
18  const buffer = builder.toBuffer()
19  const module = new WebAssembly.Module(buffer);
20  const instance = new WebAssembly.Instance(module, {});
21  functions = instance.exports;
22});
23
24test(() => {
25  const argument = { "element": "anyfunc", "initial": 5 };
26  const table = new WebAssembly.Table(argument);
27  assert_throws_js(TypeError, () => table.get());
28}, "Missing arguments: get");
29
30test(t => {
31  const thisValues = [
32    undefined,
33    null,
34    true,
35    "",
36    Symbol(),
37    1,
38    {},
39    WebAssembly.Table,
40    WebAssembly.Table.prototype,
41  ];
42
43  const argument = {
44    valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
45    toString: t.unreached_func("Should not touch the argument (toString)"),
46  };
47
48  const fn = WebAssembly.Table.prototype.get;
49
50  for (const thisValue of thisValues) {
51    assert_throws_js(TypeError, () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
52  }
53}, "Branding: get");
54
55test(() => {
56  const argument = { "element": "anyfunc", "initial": 5 };
57  const table = new WebAssembly.Table(argument);
58  assert_throws_js(TypeError, () => table.set());
59}, "Missing arguments: set");
60
61test(t => {
62  const thisValues = [
63    undefined,
64    null,
65    true,
66    "",
67    Symbol(),
68    1,
69    {},
70    WebAssembly.Table,
71    WebAssembly.Table.prototype,
72  ];
73
74  const argument = {
75    valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
76    toString: t.unreached_func("Should not touch the argument (toString)"),
77  };
78
79  const fn = WebAssembly.Table.prototype.set;
80
81  for (const thisValue of thisValues) {
82    assert_throws_js(TypeError, () => fn.call(thisValue, argument, null), `this=${format_value(thisValue)}`);
83  }
84}, "Branding: set");
85
86test(() => {
87  const argument = { "element": "anyfunc", "initial": 5 };
88  const table = new WebAssembly.Table(argument);
89  assert_equal_to_array(table, [null, null, null, null, null]);
90
91  const {fn, fn2} = functions;
92
93  assert_equals(table.set(0, fn), undefined, "set() returns undefined.");
94  table.set(2, fn2);
95  table.set(4, fn);
96
97  assert_equal_to_array(table, [fn, null, fn2, null, fn]);
98
99  table.set(0, null);
100  assert_equal_to_array(table, [null, null, fn2, null, fn]);
101}, "Basic");
102
103test(() => {
104  const argument = { "element": "anyfunc", "initial": 5 };
105  const table = new WebAssembly.Table(argument);
106  assert_equal_to_array(table, [null, null, null, null, null]);
107
108  const {fn, fn2} = functions;
109
110  table.set(0, fn);
111  table.set(2, fn2);
112  table.set(4, fn);
113
114  assert_equal_to_array(table, [fn, null, fn2, null, fn]);
115
116  table.grow(4);
117
118  assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null]);
119}, "Growing");
120
121test(() => {
122  const argument = { "element": "anyfunc", "initial": 5 };
123  const table = new WebAssembly.Table(argument);
124  assert_equal_to_array(table, [null, null, null, null, null]);
125
126  const {fn} = functions;
127
128  // -1 is the wrong type hence the type check on entry gets this
129  // before the range check does.
130  assert_throws_js(TypeError, () => table.set(-1, fn));
131  assert_throws_js(RangeError, () => table.set(5, fn));
132  assert_equal_to_array(table, [null, null, null, null, null]);
133}, "Setting out-of-bounds");
134
135test(() => {
136  const argument = { "element": "anyfunc", "initial": 1 };
137  const table = new WebAssembly.Table(argument);
138  assert_equal_to_array(table, [null]);
139
140  const invalidArguments = [
141    undefined,
142    true,
143    false,
144    "test",
145    Symbol(),
146    7,
147    NaN,
148    {},
149  ];
150  for (const argument of invalidArguments) {
151    assert_throws_js(TypeError, () => table.set(0, argument),
152                     `set(${format_value(argument)})`);
153  }
154  assert_equal_to_array(table, [null]);
155}, "Setting non-function");
156
157test(() => {
158  const argument = { "element": "anyfunc", "initial": 1 };
159  const table = new WebAssembly.Table(argument);
160  assert_equal_to_array(table, [null]);
161
162  const fn = function() {};
163  assert_throws_js(TypeError, () => table.set(0, fn));
164  assert_equal_to_array(table, [null]);
165}, "Setting non-wasm function");
166
167test(() => {
168  const argument = { "element": "anyfunc", "initial": 1 };
169  const table = new WebAssembly.Table(argument);
170  assert_equal_to_array(table, [null]);
171
172  const fn = () => {};
173  assert_throws_js(TypeError, () => table.set(0, fn));
174  assert_equal_to_array(table, [null]);
175}, "Setting non-wasm arrow function");
176
177const outOfRangeValues = [
178  undefined,
179  NaN,
180  Infinity,
181  -Infinity,
182  -1,
183  0x100000000,
184  0x1000000000,
185  "0x100000000",
186  { valueOf() { return 0x100000000; } },
187];
188
189for (const value of outOfRangeValues) {
190  test(() => {
191    const argument = { "element": "anyfunc", "initial": 1 };
192    const table = new WebAssembly.Table(argument);
193    assert_throws_js(TypeError, () => table.get(value));
194  }, `Getting out-of-range argument: ${format_value(value)}`);
195
196  test(() => {
197    const argument = { "element": "anyfunc", "initial": 1 };
198    const table = new WebAssembly.Table(argument);
199    assert_throws_js(TypeError, () => table.set(value, null));
200  }, `Setting out-of-range argument: ${format_value(value)}`);
201}
202
203test(() => {
204  const argument = { "element": "anyfunc", "initial": 1 };
205  const table = new WebAssembly.Table(argument);
206  let called = 0;
207  const value = {
208    valueOf() {
209      called++;
210      return 0;
211    },
212  };
213  assert_throws_js(TypeError, () => table.set(value, {}));
214  assert_equals(called, 1);
215}, "Order of argument conversion");
216
217test(() => {
218  const {fn} = functions;
219  const argument = { "element": "anyfunc", "initial": 1 };
220  const table = new WebAssembly.Table(argument);
221
222  assert_equals(table.get(0, {}), null);
223  assert_equals(table.set(0, fn, {}), undefined);
224}, "Stray argument");
225
226test(() => {
227  const builder = new WasmModuleBuilder();
228  builder
229    .addFunction("fn", kSig_v_v)
230    .addBody([])
231    .exportFunc();
232  const bin = builder.toBuffer();
233  const fn = new WebAssembly.Instance(new WebAssembly.Module(bin)).exports.fn;
234
235  const argument = { "element": "anyfunc", "initial": 1 };
236  const table = new WebAssembly.Table(argument, fn);
237
238  assert_equals(table.get(0), fn);
239  table.set(0);
240  assert_equals(table.get(0), null);
241
242  table.set(0, fn);
243  assert_equals(table.get(0), fn);
244
245  assert_throws_js(TypeError, () => table.set(0, {}));
246  assert_throws_js(TypeError, () => table.set(0, 37));
247}, "Arguments for anyfunc table set");
248
249test(() => {
250  const testObject = {};
251  const argument = { "element": "externref", "initial": 1 };
252  const table = new WebAssembly.Table(argument, testObject);
253
254  assert_equals(table.get(0), testObject);
255  table.set(0);
256  assert_equals(table.get(0), undefined);
257
258  table.set(0, testObject);
259  assert_equals(table.get(0), testObject);
260
261  table.set(0, 37);
262  assert_equals(table.get(0), 37);
263}, "Arguments for externref table set");
264