Skip to content

Commit

Permalink
generate more optimized code for cases with a single promise or no to…
Browse files Browse the repository at this point in the history
…p-level-await
  • Loading branch information
sokra committed May 24, 2019
1 parent 7b8cbe7 commit 214e645
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 18 deletions.
10 changes: 5 additions & 5 deletions examples/wasm-complex/README.md
Expand Up @@ -132,7 +132,7 @@ export const memory = await getMemoryFromParentInWorker();
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _magic_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./magic.js */ 1);
module.exports = Promise.all([_magic_js__WEBPACK_IMPORTED_MODULE_0__]).then(async function([_magic_js__WEBPACK_IMPORTED_MODULE_0__]) {
module.exports = _magic_js__WEBPACK_IMPORTED_MODULE_0__.then(function(_magic_js__WEBPACK_IMPORTED_MODULE_0__) {


// accessing memory
Expand Down Expand Up @@ -165,7 +165,7 @@ return __webpack_exports__;
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _magic_wat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./magic.wat */ 2);
module.exports = Promise.all([_magic_wat__WEBPACK_IMPORTED_MODULE_0__]).then(async function([_magic_wat__WEBPACK_IMPORTED_MODULE_0__]) {
module.exports = _magic_wat__WEBPACK_IMPORTED_MODULE_0__.then(function(_magic_wat__WEBPACK_IMPORTED_MODULE_0__) {
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "get", function() { return _magic_wat__WEBPACK_IMPORTED_MODULE_0__["get"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getNumber", function() { return _magic_wat__WEBPACK_IMPORTED_MODULE_0__["getNumber"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "set", function() { return _magic_wat__WEBPACK_IMPORTED_MODULE_0__["set"]; });
Expand All @@ -191,7 +191,7 @@ return __webpack_exports__;

/* harmony import */ var WEBPACK_IMPORTED_MODULE_1 = __webpack_require__(/*! ./magic-number.js */ 4);

module.exports = Promise.all([WEBPACK_IMPORTED_MODULE_0]).then(function([WEBPACK_IMPORTED_MODULE_0]) { return __webpack_require__.v(module.i, {
module.exports = WEBPACK_IMPORTED_MODULE_0.then(function(WEBPACK_IMPORTED_MODULE_0) { return __webpack_require__.v(module.i, {
"./memory.js": {
"memory": WEBPACK_IMPORTED_MODULE_0["memory"]
},
Expand Down Expand Up @@ -317,7 +317,7 @@ Hash: 0a1b2c3d4e5f6a7b8c9d
Version: webpack 5.0.0-alpha.14
Asset Size Chunks Chunk Names
57cfbfefe1cf7dd20007.module.wasm 139 bytes {179} [emitted] main
output.js 8.7 KiB {179} [emitted] main
output.js 8.64 KiB {179} [emitted] main
Entrypoint main = output.js 57cfbfefe1cf7dd20007.module.wasm
chunk {179} output.js, 57cfbfefe1cf7dd20007.module.wasm (main) 724 bytes (javascript) 139 bytes (webassembly) 1.12 KiB (runtime) [entry] [rendered]
> ./example.js main
Expand Down Expand Up @@ -360,7 +360,7 @@ Hash: 0a1b2c3d4e5f6a7b8c9d
Version: webpack 5.0.0-alpha.14
Asset Size Chunks Chunk Names
9eda4b1cb2ea4cc07c20.module.wasm 139 bytes {179} [emitted] main
output.js 1.88 KiB {179} [emitted] main
output.js 1.82 KiB {179} [emitted] main
Entrypoint main = output.js 9eda4b1cb2ea4cc07c20.module.wasm
chunk {179} output.js, 9eda4b1cb2ea4cc07c20.module.wasm (main) 724 bytes (javascript) 139 bytes (webassembly) 1.12 KiB (runtime) [entry] [rendered]
> ./example.js main
Expand Down
8 changes: 4 additions & 4 deletions examples/wasm-simple/README.md
Expand Up @@ -119,7 +119,7 @@ export function fibonacciJavascript(i) {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _add_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./add.wasm */ 1);
/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math */ 2);
module.exports = Promise.all([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _math__WEBPACK_IMPORTED_MODULE_1__]).then(async function([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _math__WEBPACK_IMPORTED_MODULE_1__]) {
module.exports = Promise.all([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _math__WEBPACK_IMPORTED_MODULE_1__]).then(function([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _math__WEBPACK_IMPORTED_MODULE_1__]) {



Expand Down Expand Up @@ -180,7 +180,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _add_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./add.wasm */ 1);
/* harmony import */ var _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./factorial.wasm */ 3);
/* harmony import */ var _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fibonacci.wasm */ 4);
module.exports = Promise.all([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__]).then(async function([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__]) {
module.exports = Promise.all([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__]).then(function([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__]) {
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "add", function() { return _add_wasm__WEBPACK_IMPORTED_MODULE_0__["add"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "factorial", function() { return _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__["factorial"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fibonacci", function() { return _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__["fibonacci"]; });
Expand Down Expand Up @@ -299,7 +299,7 @@ Version: webpack 5.0.0-alpha.14
216fd3b2e2c26ba17d6a.wasm 41 bytes {179} [emitted] main
ce408c5c3fbf4bafc915.wasm 62 bytes {179} [emitted] main
edf8dce07bda763a8ce8.wasm 67 bytes {179} [emitted] main
output.js 8.92 KiB {179} [emitted] main
output.js 8.9 KiB {179} [emitted] main
Entrypoint main = output.js 216fd3b2e2c26ba17d6a.wasm ce408c5c3fbf4bafc915.wasm edf8dce07bda763a8ce8.wasm
chunk {179} output.js, 216fd3b2e2c26ba17d6a.wasm, ce408c5c3fbf4bafc915.wasm, edf8dce07bda763a8ce8.wasm (main) 1.3 KiB (javascript) 170 bytes (webassembly) 1.16 KiB (runtime) [entry] [rendered]
> ./example.js main
Expand Down Expand Up @@ -349,7 +349,7 @@ Version: webpack 5.0.0-alpha.14
6d518704ecb4aa16ea4e.wasm 62 bytes {179} [emitted] main
9099c5b3bb53a85154d5.wasm 41 bytes {179} [emitted] main
b7e9245ccbc6eb4c52c9.wasm 67 bytes {179} [emitted] main
output.js 2.01 KiB {179} [emitted] main
output.js 2 KiB {179} [emitted] main
Entrypoint main = output.js 6d518704ecb4aa16ea4e.wasm 9099c5b3bb53a85154d5.wasm b7e9245ccbc6eb4c52c9.wasm
chunk {179} output.js, 6d518704ecb4aa16ea4e.wasm, 9099c5b3bb53a85154d5.wasm, b7e9245ccbc6eb4c52c9.wasm (main) 1.3 KiB (javascript) 170 bytes (webassembly) 1.17 KiB (runtime) [entry] [rendered]
> ./example.js main
Expand Down
17 changes: 13 additions & 4 deletions lib/async-modules/AsyncModuleInitFragment.js
Expand Up @@ -7,36 +7,45 @@

const InitFragment = require("../InitFragment");

const generateCode = (moduleArgument, promises) => {
const generateCode = (moduleArgument, hasAwait, promises) => {
if (promises.length === 0) {
return `${moduleArgument}.exports = (async function() {\n`;
}
const mayAsync = hasAwait ? "async " : "";
if (promises.length === 1) {
return `${moduleArgument}.exports = ${
promises[0]
}.then(${mayAsync}function(${promises[0]}) {\n`;
}
return `${moduleArgument}.exports = Promise.all([${promises.join(
", "
)}]).then(async function([${promises.join(", ")}]) {\n`;
)}]).then(${mayAsync}function([${promises.join(", ")}]) {\n`;
};

class AsyncModuleInitFragment extends InitFragment {
/**
* @param {string} moduleArgument the value of module.moduleArgument
* @param {boolean} hasAwait true, if the module has top-level-awaits
* @param {string[]} promises the promises that should be awaited
*/
constructor(moduleArgument, promises) {
constructor(moduleArgument, hasAwait, promises) {
super(
generateCode(moduleArgument, promises),
generateCode(moduleArgument, hasAwait, promises),
InitFragment.STAGE_ASYNC_BOUNDARY,
0,
"async-boundary",
"return __webpack_exports__;\n" +
(promises.length === 0 ? "})();\n" : "});\n")
);
this.moduleArgument = moduleArgument;
this.hasAwait = hasAwait;
this.promises = promises;
}

merge(other) {
return new AsyncModuleInitFragment(
this.moduleArgument,
this.hasAwait || other.hasAwait,
Array.from(new Set(other.promises.concat(this.promises)))
);
}
Expand Down
8 changes: 7 additions & 1 deletion lib/dependencies/HarmonyCompatibilityDependency.js
Expand Up @@ -17,6 +17,11 @@ const NullDependency = require("./NullDependency");
/** @typedef {import("../Module")} Module */

class HarmonyCompatibilityDependency extends NullDependency {
constructor() {
super();
this.hasAwait = false;
}

get type() {
return "harmony export header";
}
Expand All @@ -39,6 +44,7 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
source,
{ module, runtimeTemplate, moduleGraph, initFragments, runtimeRequirements }
) {
const dep = /** @type {HarmonyCompatibilityDependency} */ (dependency);
const usedExports = moduleGraph.getUsedExports(module);
if (usedExports === true || usedExports === null) {
const content = runtimeTemplate.defineEsModuleFlagStatement({
Expand All @@ -57,7 +63,7 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
if (module.buildMeta.exportsType === "async") {
runtimeRequirements.add(RuntimeGlobals.module);
initFragments.push(
new AsyncModuleInitFragment(module.moduleArgument, [])
new AsyncModuleInitFragment(module.moduleArgument, dep.hasAwait, [])
);
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/dependencies/HarmonyDetectionParserPlugin.js
Expand Up @@ -43,6 +43,7 @@ module.exports = class HarmonyDetectionParserPlugin {
index: -3
};
module.addDependency(compatDep);
parser.state.harmonyCompatibilityDependency = compatDep;
parser.state.harmonyModule = true;
parser.scope.isStrict = true;
module.buildMeta.exportsType = isAsync ? "async" : "namespace";
Expand All @@ -62,6 +63,7 @@ module.exports = class HarmonyDetectionParserPlugin {
"Top-level-await is only supported in EcmaScript Modules"
);
}
parser.state.harmonyCompatibilityDependency.hasAwait = true;
module.buildMeta.exportsType = "async";
});

Expand Down
8 changes: 5 additions & 3 deletions lib/dependencies/HarmonyImportDependency.js
Expand Up @@ -159,9 +159,11 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
if (dep.await) {
templateContext.runtimeRequirements.add(RuntimeGlobals.module);
templateContext.initFragments.push(
new AsyncModuleInitFragment(templateContext.module.moduleArgument, [
dep.getImportVar(templateContext.moduleGraph)
])
new AsyncModuleInitFragment(
templateContext.module.moduleArgument,
false,
[dep.getImportVar(templateContext.moduleGraph)]
)
);
}
}
Expand Down
6 changes: 5 additions & 1 deletion lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js
Expand Up @@ -144,12 +144,16 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator {
return new RawSource(
Template.asString([
...importStatements,
promises.length > 0
promises.length > 1
? `${module.moduleArgument}.exports = Promise.all([${promises.join(
", "
)}]).then(function([${promises.join(
", "
)}]) { return ${instantiateCall}; })`
: promises.length === 1
? `${module.moduleArgument}.exports = ${promises[0]}.then(function(${
promises[0]
}) { return ${instantiateCall}; })`
: `${module.moduleArgument}.exports = ${instantiateCall}`
])
);
Expand Down

0 comments on commit 214e645

Please sign in to comment.