1// META: global=window,dedicatedworker,jsshell
2// META: script=/wasm/jsapi/assertions.js
3
4function test_operations(object, object_name, operations) {
5  for (const [name, length] of operations) {
6    test(() => {
7      const propdesc = Object.getOwnPropertyDescriptor(object, name);
8      assert_equals(typeof propdesc, "object");
9      assert_true(propdesc.writable, "writable");
10      assert_true(propdesc.enumerable, "enumerable");
11      assert_true(propdesc.configurable, "configurable");
12      assert_equals(propdesc.value, object[name]);
13    }, `${object_name}.${name}`);
14
15    test(() => {
16      assert_function_name(object[name], name, `${object_name}.${name}`);
17    }, `${object_name}.${name}: name`);
18
19    test(() => {
20      assert_function_length(object[name], length, `${object_name}.${name}`);
21    }, `${object_name}.${name}: length`);
22  }
23}
24
25function test_attributes(object, object_name, attributes) {
26  for (const [name, mutable] of attributes) {
27    test(() => {
28      const propdesc = Object.getOwnPropertyDescriptor(object, name);
29      assert_equals(typeof propdesc, "object");
30      assert_true(propdesc.enumerable, "enumerable");
31      assert_true(propdesc.configurable, "configurable");
32    }, `${object_name}.${name}`);
33
34    test(() => {
35      const propdesc = Object.getOwnPropertyDescriptor(object, name);
36      assert_equals(typeof propdesc, "object");
37      assert_equals(typeof propdesc.get, "function");
38      assert_function_name(propdesc.get, "get " + name, `getter for "${name}"`);
39      assert_function_length(propdesc.get, 0, `getter for "${name}"`);
40    }, `${object_name}.${name}: getter`);
41
42    test(() => {
43      const propdesc = Object.getOwnPropertyDescriptor(object, name);
44      assert_equals(typeof propdesc, "object");
45      if (mutable) {
46        assert_equals(typeof propdesc.set, "function");
47        assert_function_name(propdesc.set, "set " + name, `setter for "${name}"`);
48        assert_function_length(propdesc.set, 1, `setter for "${name}"`);
49      } else {
50        assert_equals(typeof propdesc.set, "undefined");
51      }
52    }, `${object_name}.${name}: setter`);
53  }
54}
55
56test(() => {
57  const propdesc = Object.getOwnPropertyDescriptor(this, "WebAssembly");
58  assert_equals(typeof propdesc, "object");
59  assert_true(propdesc.writable, "writable");
60  assert_false(propdesc.enumerable, "enumerable");
61  assert_true(propdesc.configurable, "configurable");
62  assert_equals(propdesc.value, this.WebAssembly);
63}, "WebAssembly: property descriptor");
64
65test(() => {
66  assert_throws_js(TypeError, () => WebAssembly());
67}, "WebAssembly: calling");
68
69test(() => {
70  assert_throws_js(TypeError, () => new WebAssembly());
71}, "WebAssembly: constructing");
72
73const interfaces = [
74  "Module",
75  "Instance",
76  "Memory",
77  "Table",
78  "Global",
79  "CompileError",
80  "LinkError",
81  "RuntimeError",
82];
83
84for (const name of interfaces) {
85  test(() => {
86    const propdesc = Object.getOwnPropertyDescriptor(WebAssembly, name);
87    assert_equals(typeof propdesc, "object");
88    assert_true(propdesc.writable, "writable");
89    assert_false(propdesc.enumerable, "enumerable");
90    assert_true(propdesc.configurable, "configurable");
91    assert_equals(propdesc.value, WebAssembly[name]);
92  }, `WebAssembly.${name}: property descriptor`);
93
94  test(() => {
95    const interface_object = WebAssembly[name];
96    const propdesc = Object.getOwnPropertyDescriptor(interface_object, "prototype");
97    assert_equals(typeof propdesc, "object");
98    assert_false(propdesc.writable, "writable");
99    assert_false(propdesc.enumerable, "enumerable");
100    assert_false(propdesc.configurable, "configurable");
101  }, `WebAssembly.${name}: prototype`);
102
103  test(() => {
104    const interface_object = WebAssembly[name];
105    const interface_prototype_object = interface_object.prototype;
106    const propdesc = Object.getOwnPropertyDescriptor(interface_prototype_object, "constructor");
107    assert_equals(typeof propdesc, "object");
108    assert_true(propdesc.writable, "writable");
109    assert_false(propdesc.enumerable, "enumerable");
110    assert_true(propdesc.configurable, "configurable");
111    assert_equals(propdesc.value, interface_object);
112  }, `WebAssembly.${name}: prototype.constructor`);
113}
114
115test_operations(WebAssembly, "WebAssembly", [
116  ["validate", 1],
117  ["compile", 1],
118  ["instantiate", 1],
119]);
120
121
122test_operations(WebAssembly.Module, "WebAssembly.Module", [
123  ["exports", 1],
124  ["imports", 1],
125  ["customSections", 2],
126]);
127
128
129test_attributes(WebAssembly.Instance.prototype, "WebAssembly.Instance", [
130  ["exports", false],
131]);
132
133
134test_operations(WebAssembly.Memory.prototype, "WebAssembly.Memory", [
135  ["grow", 1],
136]);
137
138test_attributes(WebAssembly.Memory.prototype, "WebAssembly.Memory", [
139  ["buffer", false],
140]);
141
142
143test_operations(WebAssembly.Table.prototype, "WebAssembly.Table", [
144  ["grow", 1],
145  ["get", 1],
146  ["set", 1],
147]);
148
149test_attributes(WebAssembly.Table.prototype, "WebAssembly.Table", [
150  ["length", false],
151]);
152
153
154test_operations(WebAssembly.Global.prototype, "WebAssembly.Global", [
155  ["valueOf", 0],
156]);
157
158test_attributes(WebAssembly.Global.prototype, "WebAssembly.Global", [
159  ["value", true],
160]);
161