1import Builder from '../Builder.js';
2import * as assert from '../assert.js';
3
4// Interesting Unicode corner cases.
5
6const names = [
7 "", // Empty string.
8 "\u0000", // NUL
9 "␀", // SYMBOL FOR NUL
10 "\ufeff", // BYTE ORDER MARK
11 "\ufffc", // OBJECT REPLACEMENT CHARACTER
12 "�", // REPLACEMENT CHARACTER in case anything gets substituted this would be a duplicate, which WebAssembly disallows.
13 "\ufffe", // NONCHARACTER-FFFE
14 "\uffff", // NONCHARACTER-FFFF
15 "\u200e", // LEFT-TO-RIGHT MARK
16 "\u200f", // RIGHT-TO-LEFT MARK
17 "\u202a", // LEFT-TO-RIGHT EMBEDDING
18 "\u202b", // RIGHT-TO-LEFT EMBEDDING
19 "\u202d", // LEFT-TO-RIGHT OVERRIDE
20 "\u202e", // RIGHT-TO-LEFT OVERRIDE
21 "\u202c", // POP DIRECTIONAL FORMATTING
22 "🇨🇦", // REGIONAL INDICATOR SYMBOL LETTER C + REGIONAL INDICATOR SYMBOL LETTER A
23 "🈹", // PLAYING CARD BLACK JOKER
24 "👨❤️💋👨", // Combine a bunch of emoji
25
26 // Duplicate entries are invalid, so normalization would cause issues. We want to catch those issues.
27 "한글",
28 "한글", // Normalized version of the above.
29 "Å", // LATIN CAPITAL LETTER A WITH RING ABOVE
30 "Å", // ANGSTROM SIGN
31 "Å", // LATIN CAPITAL LETTER A + COMBINING RING ABOVE
32 "À", // LATIN CAPITAL LETTER A + COMBINING GRAVE ACCENT
33 "À", // LATIN CAPITAL LETTER A WITH GRAVE
34 "ą̂́", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + COMBINING OGONEK
35 "ą̂́", // LATIN SMALL LETTER A WITH OGONEK + COMBINING CIRCUMFLEX ACCENT + COMBINING ACUTE ACCENT
36 "Q̣̀", // LATIN CAPITAL LETTER Q + COMBINING GRAVE ACCENT + COMBINING DOT BELOW
37 "Q̣̀", // LATIN CAPITAL LETTER + COMBINING DOT BELOW + COMBINING GRAVE ACCENT
38
39 // Combine way too many things:
40
41
42
43 "Ĵ̸̨̛͙̙̱̯̺̖͔͎̣͓̬͉͓͙͔͈̥̖͎ͯ́̂͆̓̂̑ͥͧͤ͋̔ͥà̷̛̤̻̦͓͓̖̪̟͓͂ͫ̅ͦͦ̈̄̉̅̾̊̽͑ͬ̚͟͠v̡͙͕̟͎̰͆̿ͩ͗ͩ̀ͧ͂͆̾́͑ͦͭ̽ͦ̀͘a̧̻͖͓̗̻̩͌ͮ͗̈́͊̊̑̉̚̕S̡͖̱͈͚͉̩̺͎ͪͧ́͒̔̿̈ͫͥ̇ͦ̏͐̃ͭ́ͭ͢͝ç̧͎̮̤̙̗̻̯͖̮̙̰̞ͫ̽ͤ̓̊̇͆̀ͫ͂̒͐ͬ̇͂̉͒ͫ̚͘͞ͅṙ̷͓̹͈̮̪͔͓̫̓͛̅̑̉̏͂ͣ́̏͋́̓̚ͅȉͪͩ̍̽ͣ̊ͮ̚͞͏̴̵̯̹̠͖͈̠͎̦̀p͙̝̗̥̻̯̰͚̫̏̏ͯ͐ͧ͋̊̃̈̈́͢t̷͍͎̻̩̠̬̙̦̰͓̩̗̝̱̣̓̐ͫ̀̋̓͝",
44
45
46
47
48];
49
50// WebAssembly import objects have a two-level namespace with module and field. Both must be UTF-8.
51let importObject = {};
52for (let idxModule = 0; idxModule < names.length; ++idxModule) {
53 assert.falsy(importObject.hasOwnProperty(names[idxModule]));
54 importObject[names[idxModule]] = {};
55 for (let idxField = 0; idxField < names.length; ++idxField) {
56 assert.falsy(importObject[names[idxModule]].hasOwnProperty(names[idxField]));
57 importObject[names[idxModule]][names[idxField]] = () => 10000 * idxModule + idxField;
58 }
59}
60
61let b = (new Builder())
62 .Type().End();
63
64b = b.Import();
65for (let idxModule = 0; idxModule < names.length; ++idxModule)
66 for (let idxField = 0; idxField < names.length; ++idxField)
67 b = b.Function(names[idxModule], names[idxField], { params: [], ret: "i32" });
68b = b.End();
69
70b = b.Function().End();
71
72b = b.Export();
73for (let idx = 0; idx < names.length; ++idx)
74 b = b.Function(names[idx]);
75b = b.End();
76
77b = b.Code();
78for (let idx = 0; idx < names.length; ++idx)
79 b = b.Function(names[idx], { params: [], ret: "i32" }).I32Const(idx).Return().End();
80b = b.End();
81
82const module = new WebAssembly.Module(b.WebAssembly().get());
83
84for (let idxModule = 0; idxModule < names.length; ++idxModule)
85 for (let idxField = 0; idxField < names.length; ++idxField) {
86 assert.eq(WebAssembly.Module.imports(module)[idxModule * names.length + idxField].module, names[idxModule]);
87 assert.eq(WebAssembly.Module.imports(module)[idxModule * names.length + idxField].name, names[idxField]);
88 }
89
90for (let idx = 0; idx < names.length; ++idx)
91 assert.eq(WebAssembly.Module.exports(module)[idx].name, names[idx]);
92
93const instance = new WebAssembly.Instance(module, importObject);
94
95for (let idx = 0; idx < names.length; ++idx)
96 assert.eq(instance.exports[names[idx]](), idx);