• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// META: global=window,dedicatedworker,jsshell
2// META: script=/wasm/jsapi/wasm-module-builder.js
3
4let emptyModuleBinary;
5setup(() => {
6  emptyModuleBinary = new WasmModuleBuilder().toBuffer();
7});
8
9function assert_ModuleExportDescriptor(export_, expected) {
10  assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype");
11  assert_true(Object.isExtensible(export_), "isExtensible");
12
13  const name = Object.getOwnPropertyDescriptor(export_, "name");
14  assert_true(name.writable, "name: writable");
15  assert_true(name.enumerable, "name: enumerable");
16  assert_true(name.configurable, "name: configurable");
17  assert_equals(name.value, expected.name);
18
19  const kind = Object.getOwnPropertyDescriptor(export_, "kind");
20  assert_true(kind.writable, "kind: writable");
21  assert_true(kind.enumerable, "kind: enumerable");
22  assert_true(kind.configurable, "kind: configurable");
23  assert_equals(kind.value, expected.kind);
24}
25
26function assert_exports(exports, expected) {
27  assert_true(Array.isArray(exports), "Should be array");
28  assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
29  assert_true(Object.isExtensible(exports), "isExtensible");
30
31  assert_equals(exports.length, expected.length);
32  for (let i = 0; i < expected.length; ++i) {
33    assert_ModuleExportDescriptor(exports[i], expected[i]);
34  }
35}
36
37test(() => {
38  assert_throws_js(TypeError, () => WebAssembly.Module.exports());
39}, "Missing arguments");
40
41test(() => {
42  const invalidArguments = [
43    undefined,
44    null,
45    true,
46    "",
47    Symbol(),
48    1,
49    {},
50    WebAssembly.Module,
51    WebAssembly.Module.prototype,
52  ];
53  for (const argument of invalidArguments) {
54    assert_throws_js(TypeError, () => WebAssembly.Module.exports(argument),
55                     `exports(${format_value(argument)})`);
56  }
57}, "Non-Module arguments");
58
59test(() => {
60  const module = new WebAssembly.Module(emptyModuleBinary);
61  const fn = WebAssembly.Module.exports;
62  const thisValues = [
63    undefined,
64    null,
65    true,
66    "",
67    Symbol(),
68    1,
69    {},
70    WebAssembly.Module,
71    WebAssembly.Module.prototype,
72  ];
73  for (const thisValue of thisValues) {
74    assert_array_equals(fn.call(thisValue, module), []);
75  }
76}, "Branding");
77
78test(() => {
79  const module = new WebAssembly.Module(emptyModuleBinary);
80  const exports = WebAssembly.Module.exports(module);
81  assert_true(Array.isArray(exports));
82}, "Return type");
83
84test(() => {
85  const module = new WebAssembly.Module(emptyModuleBinary);
86  const exports = WebAssembly.Module.exports(module);
87  assert_exports(exports, []);
88}, "Empty module");
89
90test(() => {
91  const module = new WebAssembly.Module(emptyModuleBinary);
92  assert_not_equals(WebAssembly.Module.exports(module), WebAssembly.Module.exports(module));
93}, "Empty module: array caching");
94
95test(() => {
96  const builder = new WasmModuleBuilder();
97
98  builder
99    .addFunction("fn", kSig_v_v)
100    .addBody([])
101    .exportFunc();
102  builder
103    .addFunction("fn2", kSig_v_v)
104    .addBody([])
105    .exportFunc();
106
107  builder.setTableBounds(1);
108  builder.addExportOfKind("table", kExternalTable, 0);
109
110  builder.addGlobal(kWasmI32, true)
111    .exportAs("global")
112    .init = 7;
113  builder.addGlobal(kWasmF64, true)
114    .exportAs("global2")
115    .init = 1.2;
116
117  builder.addMemory(0, 256, true);
118
119  const buffer = builder.toBuffer()
120  const module = new WebAssembly.Module(buffer);
121  const exports = WebAssembly.Module.exports(module);
122  const expected = [
123    { "kind": "function", "name": "fn" },
124    { "kind": "function", "name": "fn2" },
125    { "kind": "table", "name": "table" },
126    { "kind": "global", "name": "global" },
127    { "kind": "global", "name": "global2" },
128    { "kind": "memory", "name": "memory" },
129  ];
130  assert_exports(exports, expected);
131}, "exports");
132
133test(() => {
134  const builder = new WasmModuleBuilder();
135
136  builder
137    .addFunction("", kSig_v_v)
138    .addBody([])
139    .exportFunc();
140
141  const buffer = builder.toBuffer()
142  const module = new WebAssembly.Module(buffer);
143  const exports = WebAssembly.Module.exports(module);
144  const expected = [
145    { "kind": "function", "name": "" },
146  ];
147  assert_exports(exports, expected);
148}, "exports with empty name: function");
149
150test(() => {
151  const builder = new WasmModuleBuilder();
152
153  builder.setTableBounds(1);
154  builder.addExportOfKind("", kExternalTable, 0);
155
156  const buffer = builder.toBuffer()
157  const module = new WebAssembly.Module(buffer);
158  const exports = WebAssembly.Module.exports(module);
159  const expected = [
160    { "kind": "table", "name": "" },
161  ];
162  assert_exports(exports, expected);
163}, "exports with empty name: table");
164
165test(() => {
166  const builder = new WasmModuleBuilder();
167
168  builder.addGlobal(kWasmI32, true)
169    .exportAs("")
170    .init = 7;
171
172  const buffer = builder.toBuffer()
173  const module = new WebAssembly.Module(buffer);
174  const exports = WebAssembly.Module.exports(module);
175  const expected = [
176    { "kind": "global", "name": "" },
177  ];
178  assert_exports(exports, expected);
179}, "exports with empty name: global");
180
181test(() => {
182  const module = new WebAssembly.Module(emptyModuleBinary);
183  const exports = WebAssembly.Module.exports(module, {});
184  assert_exports(exports, []);
185}, "Stray argument");
186