blob: e86c209ecd4f22610c7f9096952b5dc85256425f [file] [log] [blame]
import Builder from '../Builder.js';
import * as assert from '../assert.js';
// Interesting Unicode corner cases.
const names = [
"", // Empty string.
"\u0000", // NUL
"␀", // SYMBOL FOR NUL
"\ufeff", // BYTE ORDER MARK
"\ufffc", // OBJECT REPLACEMENT CHARACTER
"�", // REPLACEMENT CHARACTER in case anything gets substituted this would be a duplicate, which WebAssembly disallows.
"\ufffe", // NONCHARACTER-FFFE
"\uffff", // NONCHARACTER-FFFF
"\u200e", // LEFT-TO-RIGHT MARK
"\u200f", // RIGHT-TO-LEFT MARK
"\u202a", // LEFT-TO-RIGHT EMBEDDING
"\u202b", // RIGHT-TO-LEFT EMBEDDING
"\u202d", // LEFT-TO-RIGHT OVERRIDE
"\u202e", // RIGHT-TO-LEFT OVERRIDE
"\u202c", // POP DIRECTIONAL FORMATTING
"🇨🇦", // REGIONAL INDICATOR SYMBOL LETTER C + REGIONAL INDICATOR SYMBOL LETTER A
"🈹", // PLAYING CARD BLACK JOKER
"👨‍❤️‍💋‍👨", // Combine a bunch of emoji
// Duplicate entries are invalid, so normalization would cause issues. We want to catch those issues.
"한글",
"한글", // Normalized version of the above.
"Å", // LATIN CAPITAL LETTER A WITH RING ABOVE
"Å", // ANGSTROM SIGN
"Å", // LATIN CAPITAL LETTER A + COMBINING RING ABOVE
"À", // LATIN CAPITAL LETTER A + COMBINING GRAVE ACCENT
"À", // LATIN CAPITAL LETTER A WITH GRAVE
"ą̂́", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + COMBINING OGONEK
"ą̂́", // LATIN SMALL LETTER A WITH OGONEK + COMBINING CIRCUMFLEX ACCENT + COMBINING ACUTE ACCENT
"Q̣̀", // LATIN CAPITAL LETTER Q + COMBINING GRAVE ACCENT + COMBINING DOT BELOW
"Q̣̀", // LATIN CAPITAL LETTER + COMBINING DOT BELOW + COMBINING GRAVE ACCENT
// Combine way too many things:
"Ĵ̸̨̛͙̙̱̯̺̖͔͎̣͓̬͉͓͙͔͈̥̖͎ͯ́̂͆̓̂̑ͥͧͤ͋̔ͥà̷̛̤̻̦͓͓̖̪̟͓͂ͫ̅ͦͦ̈̄̉̅̾̊̽͑ͬ̚͟͠v̡͙͕̟͎̰͆̿ͩ͗ͩ̀ͧ͂͆̾́͑ͦͭ̽ͦ̀͘a̧̻͖͓̗̻̩͌ͮ͗̈́͊̊̑̉̚̕S̡͖̱͈͚͉̩̺͎ͪͧ́͒̔̿̈ͫͥ̇ͦ̏͐̃ͭ́ͭ͢͝ç̧͎̮̤̙̗̻̯͖̮̙̰̞ͫ̽ͤ̓̊̇͆̀ͫ͂̒͐ͬ̇͂̉͒ͫ̚͘͞ͅṙ̷͓̹͈̮̪͔͓̫̓͛̅̑̉̏͂ͣ́̏͋́̓̚ͅȉͪͩ̍̽ͣ̊ͮ̚͞͏̴̵̯̹̠͖͈̠͎̦̀p͙̝̗̥̻̯̰͚̫̏̏ͯ͐ͧ͋̊̃̈̈́͢t̷͍͎̻̩̠̬̙̦̰͓̩̗̝̱̣̓̐ͫ̀̋̓͝",
];
// WebAssembly import objects have a two-level namespace with module and field. Both must be UTF-8.
let importObject = {};
for (let idxModule = 0; idxModule < names.length; ++idxModule) {
assert.falsy(importObject.hasOwnProperty(names[idxModule]));
importObject[names[idxModule]] = {};
for (let idxField = 0; idxField < names.length; ++idxField) {
assert.falsy(importObject[names[idxModule]].hasOwnProperty(names[idxField]));
importObject[names[idxModule]][names[idxField]] = () => 10000 * idxModule + idxField;
}
}
let b = (new Builder())
.Type().End();
b = b.Import();
for (let idxModule = 0; idxModule < names.length; ++idxModule)
for (let idxField = 0; idxField < names.length; ++idxField)
b = b.Function(names[idxModule], names[idxField], { params: [], ret: "i32" });
b = b.End();
b = b.Function().End();
b = b.Export();
for (let idx = 0; idx < names.length; ++idx)
b = b.Function(names[idx]);
b = b.End();
b = b.Code();
for (let idx = 0; idx < names.length; ++idx)
b = b.Function(names[idx], { params: [], ret: "i32" }).I32Const(idx).Return().End();
b = b.End();
const module = new WebAssembly.Module(b.WebAssembly().get());
for (let idxModule = 0; idxModule < names.length; ++idxModule)
for (let idxField = 0; idxField < names.length; ++idxField) {
assert.eq(WebAssembly.Module.imports(module)[idxModule * names.length + idxField].module, names[idxModule]);
assert.eq(WebAssembly.Module.imports(module)[idxModule * names.length + idxField].name, names[idxField]);
}
for (let idx = 0; idx < names.length; ++idx)
assert.eq(WebAssembly.Module.exports(module)[idx].name, names[idx]);
const instance = new WebAssembly.Instance(module, importObject);
for (let idx = 0; idx < names.length; ++idx)
assert.eq(instance.exports[names[idx]](), idx);