COMMIT_MESSAGE

 1WebAssembly: test imports and exports with 16-bit characters
 2

JSTests/ChangeLog

 12017-06-07 JF Bastien <jfbastien@apple.com>
 2
 3 WebAssembly: test imports and exports with 16-bit characters
 4 https://bugs.webkit.org/show_bug.cgi?id=165977
 5 <rdar://problem/29760130>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 The output for import failure was improved, so many tests need to
 10 be updated here. Only one has new tests as noted below.
 11
 12 * wasm/function-tests/memory-import-and-grow.js:
 13 * wasm/js-api/Instance.imports.exports.unicode.js: Added. Main new test.
 14 (idxModule):
 15 * wasm/js-api/global-error.js:
 16 (new.Number):
 17 (assert.throws):
 18 * wasm/js-api/table.js:
 19 (assert.throws):
 20 (new.WebAssembly.Table):
 21 * wasm/js-api/test_memory.js:
 22 (test):
 23 * wasm/js-api/wasm-to-wasm-bad-signature.js:
 24 (BadSignatureDropStartParams.):
 25 (BadSignatureDropStartParams):
 26 (BadSignatureDropEndParams.):
 27 (BadSignatureSwapParam.):
 28 (BadSignatureRet.):
 29 * wasm/js-api/web-assembly-instantiate.js:
 30 (assert.asyncTest.async.test):
 31 (assert.asyncTest):
 32 * wasm/js-api/wrapper-function.js:
 33 (return.new.WebAssembly.Module):
 34
1352017-06-06 Joseph Pecoraro <pecoraro@apple.com>
236
337 Unreviewed rollout r217807. Caused a test to crash.

JSTests/wasm/function-tests/memory-import-and-grow.js

@@test({ initial: 2, maximum: 2 }, { initial: 2, maximum: 4 }, u, 1, 2);
121121test({ initial: 2, maximum: 4 }, { initial: 2 }, 0, u, 2);
122122
123123// Disallowed: imported initial is lesser than declared.
124 assert.throws(() => test({ initial: 1, maximum: 4 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
125 assert.throws(() => test({ initial: 0, maximum: 4 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
 124assert.throws(() => test({ initial: 1, maximum: 4 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
 125assert.throws(() => test({ initial: 0, maximum: 4 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
126126
127127// Disallowed: imported maximum is greater than declared.
128 assert.throws(() => test({ initial: 2, maximum: 5 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`);
 128assert.throws(() => test({ initial: 2, maximum: 5 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import imp:memory provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`);
129129
130130// Disallowed: no imported maximum, same as above.
131 assert.throws(() => test({ initial: 2 }, { initial: 2, maximum: 4 }, 0, u, 2), WebAssembly.LinkError, `Memory import did not have a 'maximum' but the module requires that it does`);
 131assert.throws(() => test({ initial: 2 }, { initial: 2, maximum: 4 }, 0, u, 2), WebAssembly.LinkError, `Memory import imp:memory did not have a 'maximum' but the module requires that it does`);

JSTests/wasm/js-api/Instance.imports.exports.unicode.js

 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);

JSTests/wasm/js-api/global-error.js

@@for ( let imp of [undefined, null, {}, () => {}, "number", new Number(4)]) {
185185 bin.trim();
186186
187187 const module = new WebAssembly.Module(bin.get());
188  assert.throws(() => new WebAssembly.Instance(module, { imp: { global: imp } }), WebAssembly.LinkError, "imported global must be a number (evaluating 'new WebAssembly.Instance(module, { imp: { global: imp } })')");
 188 assert.throws(() => new WebAssembly.Instance(module, { imp: { global: imp } }), WebAssembly.LinkError, "imported global imp:global must be a number (evaluating 'new WebAssembly.Instance(module, { imp: { global: imp } })')");
189189}
190190
191191{

@@for ( let imp of [undefined, null, {}, () => {}, "number", new Number(4)]) {
208208 .Function().End()
209209 .Global().GetGlobal("i64", 0, "immutable").End();
210210 const module = new WebAssembly.Module(builder.WebAssembly().get());
211  assert.throws(() => new WebAssembly.Instance(module, { imp: { global: undefined } }), WebAssembly.LinkError, "imported global cannot be an i64 (evaluating 'new WebAssembly.Instance(module, { imp: { global: undefined } })')");
 211 assert.throws(() => new WebAssembly.Instance(module, { imp: { global: undefined } }), WebAssembly.LinkError, "imported global imp:global cannot be an i64 (evaluating 'new WebAssembly.Instance(module, { imp: { global: undefined } })')");
212212}

JSTests/wasm/js-api/table.js

@@function assertBadTableImport(tableDescription, message) {
193193 }
194194
195195 const badTables = [
196  [{initial: 100, maximum:100, element:"anyfunc"}, new WebAssembly.Table({initial:100, element: "anyfunc"}), "Table import does not have a 'maximum' but the module requires that it does (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
197  [{initial: 100, maximum:100, element:"anyfunc"}, new WebAssembly.Table({initial:100, maximum:101, element: "anyfunc"}), "Imported Table's 'maximum' is larger than the module's expected 'maximum' (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
198  [{initial: 100, element:"anyfunc"}, new WebAssembly.Table({initial:10, element: "anyfunc"}), "Table import provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
199  [{initial: 10, element:"anyfunc"}, new WebAssembly.Table({initial:9, element: "anyfunc"}), "Table import provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
 196 [{initial: 100, maximum:100, element:"anyfunc"}, new WebAssembly.Table({initial:100, element: "anyfunc"}), "Table import imp:table does not have a 'maximum' but the module requires that it does (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
 197 [{initial: 100, maximum:100, element:"anyfunc"}, new WebAssembly.Table({initial:100, maximum:101, element: "anyfunc"}), "Imported Table imp:table 'maximum' is larger than the module's expected 'maximum' (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
 198 [{initial: 100, element:"anyfunc"}, new WebAssembly.Table({initial:10, element: "anyfunc"}), "Table import imp:table provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
 199 [{initial: 10, element:"anyfunc"}, new WebAssembly.Table({initial:9, element: "anyfunc"}), "Table import imp:table provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"],
200200 ];
201201 for (const [d, t, m] of badTables) {
202202 assertBadTableInstance(d, t, m);

@@function assertBadTableImport(tableDescription, message) {
251251 .Code()
252252 .End();
253253 const module = new WebAssembly.Module(builder.WebAssembly().get());
254  assert.throws(() => new WebAssembly.Instance(module, {imp: {table}}), WebAssembly.LinkError, "Table import is not an instance of WebAssembly.Table (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')");
 254 assert.throws(() => new WebAssembly.Instance(module, {imp: {table}}), WebAssembly.LinkError, "Table import imp:table is not an instance of WebAssembly.Table (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')");
255255 }
256256 assertBadTable(25);
257257 assertBadTable(new Object);

JSTests/wasm/js-api/test_memory.js

@@test(function() {
318318 const module = new WebAssembly.Module(bin);
319319
320320 assert.throws(() => new WebAssembly.Instance(module, 20), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object`);
321  assert.throws(() => new WebAssembly.Instance(module, {}), TypeError, `import must be an object`);
322  assert.throws(() => new WebAssembly.Instance(module, {imp: { } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory`);
323  assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: 20 } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory`);
324  assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: [] } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory`);
325  assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }), WebAssembly.LinkError, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
326  assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20}) } }), WebAssembly.LinkError, `Memory import did not have a 'maximum' but the module requires that it does`);
327  assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20, maximum: 26}) } }), WebAssembly.LinkError, `Memory import provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`);
 321 assert.throws(() => new WebAssembly.Instance(module, {}), TypeError, `import imp:memory must be an object`);
 322 assert.throws(() => new WebAssembly.Instance(module, {imp: { } }), WebAssembly.LinkError, `Memory import imp:memory is not an instance of WebAssembly.Memory`);
 323 assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: 20 } }), WebAssembly.LinkError, `Memory import imp:memory is not an instance of WebAssembly.Memory`);
 324 assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: [] } }), WebAssembly.LinkError, `Memory import imp:memory is not an instance of WebAssembly.Memory`);
 325 assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }), WebAssembly.LinkError, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
 326 assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20}) } }), WebAssembly.LinkError, `Memory import imp:memory did not have a 'maximum' but the module requires that it does`);
 327 assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20, maximum: 26}) } }), WebAssembly.LinkError, `Memory import imp:memory provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`);
328328});
329329
330330test(function() {

@@test(function() {
354354 assert.throws(() => new WebAssembly.Instance(module, instanceObj), WebAssembly.LinkError, expectedError);
355355 }
356356
357  testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
358  testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19}) } }, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
 357 testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
 358 testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19}) } }, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
359359
360360 // This should not throw.
361361 new WebAssembly.Instance(module, {imp: {memory: new WebAssembly.Memory({initial:20})}});

JSTests/wasm/js-api/wasm-to-wasm-bad-signature.js

@@const makeImportee = signature => {
6262 for (let i = 1; i <= signature.params.length; ++i) {
6363 const badParamSignature = { params: signature.params.slice(i, signature.params.length), ret: signature.ret };
6464 const importer = makeImporter(badParamSignature);
65  assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
 65 assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
6666 }
6767 }
6868})();

@@const makeImportee = signature => {
7373 for (let i = 1; i < signature.params.length; ++i) {
7474 const badParamSignature = { params: signature.params.slice(0, i), ret: signature.ret };
7575 const importer = makeImporter(badParamSignature);
76  assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
 76 assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
7777 }
7878 }
7979})();

@@const makeImportee = signature => {
8787 badParams[signatureIndex] = swapTypeNonVoid(badParams[signatureIndex], typeIndex);
8888 const badParamSignature = { params: badParams, ret: signature.ret };
8989 const importer = makeImporter(badParamSignature);
90  assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
 90 assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
9191 }
9292 }
9393 }

@@const makeImportee = signature => {
9999 for (let typeIndex = 1; typeIndex < types.length; ++typeIndex) {
100100 const badParamSignature = { params: signature.params, ret: swapType(signature.ret, typeIndex) };
101101 const importer = makeImporter(badParamSignature);
102  assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
 102 assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
103103 }
104104 }
105105})();

JSTests/wasm/js-api/web-assembly-instantiate.js

@@assert.eq(WebAssembly.instantiate.length, 1);
103103 try {
104104 let {module, instance} = await WebAssembly.instantiate(bin, {imp: {memory: 20}});
105105 } catch(e) {
106  assert.eq(e.message, "Memory import is not an instance of WebAssembly.Memory");
 106 assert.eq(e.message, "Memory import imp:memory is not an instance of WebAssembly.Memory");
107107 }
108108 }
109109

@@assert.eq(WebAssembly.instantiate.length, 1);
131131 const module = new WebAssembly.Module(bin);
132132 let instance = await WebAssembly.instantiate(bin, {imp: {memory: 20}});
133133 } catch(e) {
134  assert.eq(e.message, "Memory import is not an instance of WebAssembly.Memory");
 134 assert.eq(e.message, "Memory import imp:memory is not an instance of WebAssembly.Memory");
135135 }
136136 }
137137

JSTests/wasm/js-api/wrapper-function.js

@@function exportImport(type) {
4545 .Code().End();
4646 let module = new WebAssembly.Module(builder.WebAssembly().get());
4747 // This should not type check.
48  assert.throws(() => new WebAssembly.Instance(module, {imp: {f: instance.exports.func}}), WebAssembly.LinkError, "imported function's signature doesn't match the provided WebAssembly function's signature");
 48 assert.throws(() => new WebAssembly.Instance(module, {imp: {f: instance.exports.func}}), WebAssembly.LinkError, "imported function imp:f signature doesn't match the provided WebAssembly function's signature");
4949 }
5050
5151}

Source/JavaScriptCore/ChangeLog

 12017-06-07 JF Bastien <jfbastien@apple.com>
 2
 3 WebAssembly: test imports and exports with 16-bit characters
 4 https://bugs.webkit.org/show_bug.cgi?id=165977
 5 <rdar://problem/29760130>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Add the missing UTF-8 conversions. Improve import failure error
 10 messages, otherwise it's hard to figure out which import is wrong.
 11
 12 * wasm/js/JSWebAssemblyInstance.cpp:
 13 (JSC::JSWebAssemblyInstance::create):
 14 * wasm/js/WebAssemblyModuleRecord.cpp:
 15 (JSC::WebAssemblyModuleRecord::finishCreation):
 16 (JSC::WebAssemblyModuleRecord::link):
 17
1182017-06-06 Keith Miller <keith_miller@apple.com>
219
320 OMG tier up checks should be a patchpoint

Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
137137 return nullptr;
138138 };
139139
 140 auto importFailMessage = [&] (const Wasm::Import& import, const char* before, const char* after) {
 141 return before + String(" ") + String::fromUTF8(import.module) + ":" + String::fromUTF8(import.field) + " " + after;
 142 };
 143
140144 // If the list of module.imports is not empty and Type(importObject) is not Object, a TypeError is thrown.
141145 if (moduleInformation.imports.size() && !importObject)
142146 return exception(createTypeError(exec, ASCIILiteral("can't make WebAssembly.Instance because there is no imports Object and the WebAssembly.Module requires imports")));

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
161165 // For each import i in module.imports:
162166 for (auto& import : moduleInformation.imports) {
163167 // 1. Let o be the resultant value of performing Get(importObject, i.module_name).
164  JSValue importModuleValue = importObject->get(exec, Identifier::fromString(&vm, import.module));
 168 JSValue importModuleValue = importObject->get(exec, Identifier::fromString(&vm, String::fromUTF8(import.module)));
165169 RETURN_IF_EXCEPTION(throwScope, nullptr);
166170 // 2. If Type(o) is not Object, throw a TypeError.
167171 if (!importModuleValue.isObject())
168  return exception(createTypeError(exec, ASCIILiteral("import must be an object"), defaultSourceAppender, runtimeTypeForValue(importModuleValue)));
 172 return exception(createTypeError(exec, importFailMessage(import, "import", "must be an object"), defaultSourceAppender, runtimeTypeForValue(importModuleValue)));
169173
170174 // 3. Let v be the value of performing Get(o, i.item_name)
171175 JSObject* object = jsCast<JSObject*>(importModuleValue);
172  JSValue value = object->get(exec, Identifier::fromString(&vm, import.field));
 176 JSValue value = object->get(exec, Identifier::fromString(&vm, String::fromUTF8(import.field)));
173177 RETURN_IF_EXCEPTION(throwScope, nullptr);
174178
175179 switch (import.kind) {

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
177181 // 4. If i is a function import:
178182 // i. If IsCallable(v) is false, throw a WebAssembly.LinkError.
179183 if (!value.isFunction())
180  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("import function must be callable")));
 184 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "import function", "must be callable")));
181185
182186 JSObject* function = jsCast<JSObject*>(value);
183187 // ii. If v is an Exported Function Exotic Object:

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
195199 }
196200 Wasm::SignatureIndex expectedSignatureIndex = moduleInformation.importFunctionSignatureIndices[import.kindIndex];
197201 if (importedSignatureIndex != expectedSignatureIndex)
198  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("imported function's signature doesn't match the provided WebAssembly function's signature")));
 202 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "imported function", "signature doesn't match the provided WebAssembly function's signature")));
199203 }
200204 // iii. Otherwise:
201205 // a. Let closure be a new host function of the given signature which calls v by coercing WebAssembly arguments to JavaScript arguments via ToJSValue and returns the result, if any, by coercing via ToWebAssemblyValue.

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
215219 JSWebAssemblyTable* table = jsDynamicCast<JSWebAssemblyTable*>(vm, value);
216220 // i. If v is not a WebAssembly.Table object, throw a WebAssembly.LinkError.
217221 if (!table)
218  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Table import is not an instance of WebAssembly.Table")));
 222 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Table import", "is not an instance of WebAssembly.Table")));
219223
220224 uint32_t expectedInitial = moduleInformation.tableInformation.initial();
221225 uint32_t actualInitial = table->size();
222226 if (actualInitial < expectedInitial)
223  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Table import provided an 'initial' that is too small")));
 227 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Table import", "provided an 'initial' that is too small")));
224228
225229 if (std::optional<uint32_t> expectedMaximum = moduleInformation.tableInformation.maximum()) {
226230 std::optional<uint32_t> actualMaximum = table->maximum();
227231 if (!actualMaximum)
228  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Table import does not have a 'maximum' but the module requires that it does")));
 232 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Table import", "does not have a 'maximum' but the module requires that it does")));
229233 if (*actualMaximum > *expectedMaximum)
230  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Imported Table's 'maximum' is larger than the module's expected 'maximum'")));
 234 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Imported Table", "'maximum' is larger than the module's expected 'maximum'")));
231235 }
232236
233237 // ii. Append v to tables.

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
244248 JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, value);
245249 // i. If v is not a WebAssembly.Memory object, throw a WebAssembly.LinkError.
246250 if (!memory)
247  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Memory import is not an instance of WebAssembly.Memory")));
 251 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Memory import", "is not an instance of WebAssembly.Memory")));
248252
249253 Wasm::PageCount declaredInitial = moduleInformation.memory.initial();
250254 Wasm::PageCount importedInitial = memory->memory().initial();
251255 if (importedInitial < declaredInitial)
252  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size")));
 256 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Memory import", "provided an 'initial' that is smaller than the module's declared 'initial' import memory size")));
253257
254258 if (Wasm::PageCount declaredMaximum = moduleInformation.memory.maximum()) {
255259 Wasm::PageCount importedMaximum = memory->memory().maximum();
256260 if (!importedMaximum)
257  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Memory import did not have a 'maximum' but the module requires that it does")));
 261 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Memory import", "did not have a 'maximum' but the module requires that it does")));
258262
259263 if (importedMaximum > declaredMaximum)
260  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Memory import provided a 'maximum' that is larger than the module's declared 'maximum' import memory size")));
 264 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Memory import", "provided a 'maximum' that is larger than the module's declared 'maximum' import memory size")));
261265 }
262266
263267 // ii. Append v to memories.

@@JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JS
273277 ASSERT(moduleInformation.globals[import.kindIndex].mutability == Wasm::Global::Immutable);
274278 // ii. If the global_type of i is i64 or Type(v) is not Number, throw a WebAssembly.LinkError.
275279 if (moduleInformation.globals[import.kindIndex].type == Wasm::I64)
276  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("imported global cannot be an i64")));
 280 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "imported global", "cannot be an i64")));
277281 if (!value.isNumber())
278  return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("imported global must be a number")));
 282 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "imported global", "must be a number")));
279283 // iii. Append ToWebAssemblyValue(v) to imports.
280284 ASSERT(numImportGlobals == import.kindIndex);
281285 switch (moduleInformation.globals[import.kindIndex].type) {

Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

11/*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
 2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
33 *
44 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions

@@void WebAssemblyModuleRecord::finishCreation(ExecState* exec, VM& vm, const Wasm
7373 Base::finishCreation(exec, vm);
7474 ASSERT(inherits(vm, info()));
7575 for (const auto& exp : moduleInformation.exports) {
76  Identifier field = Identifier::fromString(&vm, exp.field);
 76 Identifier field = Identifier::fromString(&vm, String::fromUTF8(exp.field));
7777 addExportEntry(ExportEntry::createLocal(field, field));
7878 }
7979}

@@void WebAssemblyModuleRecord::link(ExecState* exec, JSWebAssemblyModule* module,
9999 SymbolTable* exportSymbolTable = module->exportSymbolTable();
100100 unsigned functionImportCount = codeBlock->functionImportCount();
101101
102  // FIXME wire up the imports. https://bugs.webkit.org/show_bug.cgi?id=165118
103 
104102 // Let exports be a list of (string, JS value) pairs that is mapped from each external value e in instance.exports as follows:
105103 JSModuleEnvironment* moduleEnvironment = JSModuleEnvironment::create(vm, globalObject, nullptr, exportSymbolTable, JSValue(), this);
106104 for (const auto& exp : moduleInformation.exports) {

@@void WebAssemblyModuleRecord::link(ExecState* exec, JSWebAssemblyModule* module,
179177 bool shouldThrowReadOnlyError = false;
180178 bool ignoreReadOnlyErrors = true;
181179 bool putResult = false;
182  symbolTablePutTouchWatchpointSet(moduleEnvironment, exec, Identifier::fromString(&vm, exp.field), exportedValue, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult);
 180 symbolTablePutTouchWatchpointSet(moduleEnvironment, exec, Identifier::fromString(&vm, String::fromUTF8(exp.field)), exportedValue, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult);
183181 RELEASE_ASSERT(putResult);
184182 }
185183