1// META: global=window,dedicatedworker,jsshell
2// META: script=/wasm/jsapi/wasm-module-builder.js
3
4function assert_ArrayBuffer(buffer, expected) {
5  assert_equals(Object.getPrototypeOf(buffer), ArrayBuffer.prototype, "Prototype");
6  assert_true(Object.isExtensible(buffer), "isExtensible");
7  assert_array_equals(new Uint8Array(buffer), expected);
8}
9
10function assert_sections(sections, expected) {
11  assert_true(Array.isArray(sections), "Should be array");
12  assert_equals(Object.getPrototypeOf(sections), Array.prototype, "Prototype");
13  assert_true(Object.isExtensible(sections), "isExtensible");
14
15  assert_equals(sections.length, expected.length);
16  for (let i = 0; i < expected.length; ++i) {
17    assert_ArrayBuffer(sections[i], expected[i]);
18  }
19}
20
21let emptyModuleBinary;
22setup(() => {
23  emptyModuleBinary = new WasmModuleBuilder().toBuffer();
24});
25
26test(() => {
27  assert_throws_js(TypeError, () => WebAssembly.Module.customSections());
28  const module = new WebAssembly.Module(emptyModuleBinary);
29  assert_throws_js(TypeError, () => WebAssembly.Module.customSections(module));
30}, "Missing arguments");
31
32test(() => {
33  const invalidArguments = [
34    undefined,
35    null,
36    true,
37    "",
38    Symbol(),
39    1,
40    {},
41    WebAssembly.Module,
42    WebAssembly.Module.prototype,
43  ];
44  for (const argument of invalidArguments) {
45    assert_throws_js(TypeError, () => WebAssembly.Module.customSections(argument, ""),
46                     `customSections(${format_value(argument)})`);
47  }
48}, "Non-Module arguments");
49
50test(() => {
51  const module = new WebAssembly.Module(emptyModuleBinary);
52  const fn = WebAssembly.Module.customSections;
53  const thisValues = [
54    undefined,
55    null,
56    true,
57    "",
58    Symbol(),
59    1,
60    {},
61    WebAssembly.Module,
62    WebAssembly.Module.prototype,
63  ];
64  for (const thisValue of thisValues) {
65    assert_sections(fn.call(thisValue, module, ""), []);
66  }
67}, "Branding");
68
69test(() => {
70  const module = new WebAssembly.Module(emptyModuleBinary);
71  assert_sections(WebAssembly.Module.customSections(module, ""), []);
72}, "Empty module");
73
74test(() => {
75  const module = new WebAssembly.Module(emptyModuleBinary);
76  assert_not_equals(WebAssembly.Module.customSections(module, ""),
77                    WebAssembly.Module.customSections(module, ""));
78}, "Empty module: array caching");
79
80test(() => {
81  const bytes1 = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
82  const bytes2 = [74, 83, 65, 80, 73];
83
84  const builder = new WasmModuleBuilder();
85  builder.addCustomSection("name", bytes1);
86  builder.addCustomSection("name", bytes2);
87  builder.addCustomSection("foo", bytes1);
88  const buffer = builder.toBuffer()
89  const module = new WebAssembly.Module(buffer);
90
91  assert_sections(WebAssembly.Module.customSections(module, "name"), [
92    bytes1,
93    bytes2,
94  ])
95
96  assert_sections(WebAssembly.Module.customSections(module, "foo"), [
97    bytes1,
98  ])
99
100  assert_sections(WebAssembly.Module.customSections(module, ""), [])
101  assert_sections(WebAssembly.Module.customSections(module, "\0"), [])
102  assert_sections(WebAssembly.Module.customSections(module, "name\0"), [])
103  assert_sections(WebAssembly.Module.customSections(module, "foo\0"), [])
104}, "Custom sections");
105
106test(() => {
107  const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
108  const name = "yee\uD801\uDC37eey"
109
110  const builder = new WasmModuleBuilder();
111  builder.addCustomSection(name, bytes);
112  const buffer = builder.toBuffer();
113  const module = new WebAssembly.Module(buffer);
114
115  assert_sections(WebAssembly.Module.customSections(module, name), [
116    bytes,
117  ]);
118  assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFDeey"), []);
119  assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFD\uFFFDeey"), []);
120}, "Custom sections with surrogate pairs");
121
122test(() => {
123  const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
124
125  const builder = new WasmModuleBuilder();
126  builder.addCustomSection("na\uFFFDme", bytes);
127  const buffer = builder.toBuffer();
128  const module = new WebAssembly.Module(buffer);
129
130  assert_sections(WebAssembly.Module.customSections(module, "name"), []);
131  assert_sections(WebAssembly.Module.customSections(module, "na\uFFFDme"), [
132    bytes,
133  ]);
134  assert_sections(WebAssembly.Module.customSections(module, "na\uDC01me"), []);
135}, "Custom sections with U+FFFD");
136
137test(() => {
138  const module = new WebAssembly.Module(emptyModuleBinary);
139  assert_sections(WebAssembly.Module.customSections(module, "", {}), []);
140}, "Stray argument");
141