mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-01 13:42:20 +00:00
0.2.0 - Mid migration
This commit is contained in:
parent
139e6a915e
commit
7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions
17
web/node_modules/webpack/lib/wasm/UnsupportedWebAssemblyFeatureError.js
generated
vendored
Normal file
17
web/node_modules/webpack/lib/wasm/UnsupportedWebAssemblyFeatureError.js
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const WebpackError = require("../WebpackError");
|
||||
|
||||
module.exports = class UnsupportedWebAssemblyFeatureError extends WebpackError {
|
||||
/** @param {string} message Error message */
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "UnsupportedWebAssemblyFeatureError";
|
||||
this.hideStack = true;
|
||||
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
};
|
69
web/node_modules/webpack/lib/wasm/WasmFinalizeExportsPlugin.js
generated
vendored
Normal file
69
web/node_modules/webpack/lib/wasm/WasmFinalizeExportsPlugin.js
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const UnsupportedWebAssemblyFeatureError = require("./UnsupportedWebAssemblyFeatureError");
|
||||
|
||||
class WasmFinalizeExportsPlugin {
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap("WasmFinalizeExportsPlugin", compilation => {
|
||||
compilation.hooks.finishModules.tap(
|
||||
"WasmFinalizeExportsPlugin",
|
||||
modules => {
|
||||
for (const module of modules) {
|
||||
// 1. if a WebAssembly module
|
||||
if (module.type.startsWith("webassembly") === true) {
|
||||
const jsIncompatibleExports =
|
||||
module.buildMeta.jsIncompatibleExports;
|
||||
|
||||
if (jsIncompatibleExports === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const reason of module.reasons) {
|
||||
// 2. is referenced by a non-WebAssembly module
|
||||
if (reason.module.type.startsWith("webassembly") === false) {
|
||||
const ref = compilation.getDependencyReference(
|
||||
reason.module,
|
||||
reason.dependency
|
||||
);
|
||||
|
||||
if (!ref) continue;
|
||||
|
||||
const importedNames = ref.importedNames;
|
||||
|
||||
if (Array.isArray(importedNames)) {
|
||||
importedNames.forEach(name => {
|
||||
// 3. and uses a func with an incompatible JS signature
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
jsIncompatibleExports,
|
||||
name
|
||||
)
|
||||
) {
|
||||
// 4. error
|
||||
/** @type {any} */
|
||||
const error = new UnsupportedWebAssemblyFeatureError(
|
||||
`Export "${name}" with ${jsIncompatibleExports[name]} can only be used for direct wasm to wasm dependencies`
|
||||
);
|
||||
error.module = module;
|
||||
error.origin = reason.module;
|
||||
error.originLoc = reason.dependency.loc;
|
||||
error.dependencies = [reason.dependency];
|
||||
compilation.errors.push(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WasmFinalizeExportsPlugin;
|
341
web/node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js
generated
vendored
Normal file
341
web/node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js
generated
vendored
Normal file
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const Template = require("../Template");
|
||||
const WebAssemblyUtils = require("./WebAssemblyUtils");
|
||||
|
||||
/** @typedef {import("../Module")} Module */
|
||||
/** @typedef {import("../MainTemplate")} MainTemplate */
|
||||
|
||||
// Get all wasm modules
|
||||
const getAllWasmModules = chunk => {
|
||||
const wasmModules = chunk.getAllAsyncChunks();
|
||||
const array = [];
|
||||
for (const chunk of wasmModules) {
|
||||
for (const m of chunk.modulesIterable) {
|
||||
if (m.type.startsWith("webassembly")) {
|
||||
array.push(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
/**
|
||||
* generates the import object function for a module
|
||||
* @param {Module} module the module
|
||||
* @param {boolean} mangle mangle imports
|
||||
* @returns {string} source code
|
||||
*/
|
||||
const generateImportObject = (module, mangle) => {
|
||||
const waitForInstances = new Map();
|
||||
const properties = [];
|
||||
const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies(
|
||||
module,
|
||||
mangle
|
||||
);
|
||||
for (const usedDep of usedWasmDependencies) {
|
||||
const dep = usedDep.dependency;
|
||||
const importedModule = dep.module;
|
||||
const exportName = dep.name;
|
||||
const usedName = importedModule && importedModule.isUsed(exportName);
|
||||
const description = dep.description;
|
||||
const direct = dep.onlyDirectImport;
|
||||
|
||||
const module = usedDep.module;
|
||||
const name = usedDep.name;
|
||||
|
||||
if (direct) {
|
||||
const instanceVar = `m${waitForInstances.size}`;
|
||||
waitForInstances.set(instanceVar, importedModule.id);
|
||||
properties.push({
|
||||
module,
|
||||
name,
|
||||
value: `${instanceVar}[${JSON.stringify(usedName)}]`
|
||||
});
|
||||
} else {
|
||||
const params = description.signature.params.map(
|
||||
(param, k) => "p" + k + param.valtype
|
||||
);
|
||||
|
||||
const mod = `installedModules[${JSON.stringify(importedModule.id)}]`;
|
||||
const func = `${mod}.exports[${JSON.stringify(usedName)}]`;
|
||||
|
||||
properties.push({
|
||||
module,
|
||||
name,
|
||||
value: Template.asString([
|
||||
(importedModule.type.startsWith("webassembly")
|
||||
? `${mod} ? ${func} : `
|
||||
: "") + `function(${params}) {`,
|
||||
Template.indent([`return ${func}(${params});`]),
|
||||
"}"
|
||||
])
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let importObject;
|
||||
if (mangle) {
|
||||
importObject = [
|
||||
"return {",
|
||||
Template.indent([
|
||||
properties.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
|
||||
]),
|
||||
"};"
|
||||
];
|
||||
} else {
|
||||
const propertiesByModule = new Map();
|
||||
for (const p of properties) {
|
||||
let list = propertiesByModule.get(p.module);
|
||||
if (list === undefined) {
|
||||
propertiesByModule.set(p.module, (list = []));
|
||||
}
|
||||
list.push(p);
|
||||
}
|
||||
importObject = [
|
||||
"return {",
|
||||
Template.indent([
|
||||
Array.from(propertiesByModule, ([module, list]) => {
|
||||
return Template.asString([
|
||||
`${JSON.stringify(module)}: {`,
|
||||
Template.indent([
|
||||
list.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
|
||||
]),
|
||||
"}"
|
||||
]);
|
||||
}).join(",\n")
|
||||
]),
|
||||
"};"
|
||||
];
|
||||
}
|
||||
|
||||
if (waitForInstances.size === 1) {
|
||||
const moduleId = Array.from(waitForInstances.values())[0];
|
||||
const promise = `installedWasmModules[${JSON.stringify(moduleId)}]`;
|
||||
const variable = Array.from(waitForInstances.keys())[0];
|
||||
return Template.asString([
|
||||
`${JSON.stringify(module.id)}: function() {`,
|
||||
Template.indent([
|
||||
`return promiseResolve().then(function() { return ${promise}; }).then(function(${variable}) {`,
|
||||
Template.indent(importObject),
|
||||
"});"
|
||||
]),
|
||||
"},"
|
||||
]);
|
||||
} else if (waitForInstances.size > 0) {
|
||||
const promises = Array.from(
|
||||
waitForInstances.values(),
|
||||
id => `installedWasmModules[${JSON.stringify(id)}]`
|
||||
).join(", ");
|
||||
const variables = Array.from(
|
||||
waitForInstances.keys(),
|
||||
(name, i) => `${name} = array[${i}]`
|
||||
).join(", ");
|
||||
return Template.asString([
|
||||
`${JSON.stringify(module.id)}: function() {`,
|
||||
Template.indent([
|
||||
`return promiseResolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`,
|
||||
Template.indent([`var ${variables};`, ...importObject]),
|
||||
"});"
|
||||
]),
|
||||
"},"
|
||||
]);
|
||||
} else {
|
||||
return Template.asString([
|
||||
`${JSON.stringify(module.id)}: function() {`,
|
||||
Template.indent(importObject),
|
||||
"},"
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
class WasmMainTemplatePlugin {
|
||||
constructor({ generateLoadBinaryCode, supportsStreaming, mangleImports }) {
|
||||
this.generateLoadBinaryCode = generateLoadBinaryCode;
|
||||
this.supportsStreaming = supportsStreaming;
|
||||
this.mangleImports = mangleImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MainTemplate} mainTemplate main template
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(mainTemplate) {
|
||||
mainTemplate.hooks.localVars.tap(
|
||||
"WasmMainTemplatePlugin",
|
||||
(source, chunk) => {
|
||||
const wasmModules = getAllWasmModules(chunk);
|
||||
if (wasmModules.length === 0) return source;
|
||||
const importObjects = wasmModules.map(module => {
|
||||
return generateImportObject(module, this.mangleImports);
|
||||
});
|
||||
return Template.asString([
|
||||
source,
|
||||
"",
|
||||
"// object to store loaded and loading wasm modules",
|
||||
"var installedWasmModules = {};",
|
||||
"",
|
||||
// This function is used to delay reading the installed wasm module promises
|
||||
// by a microtask. Sorting them doesn't help because there are egdecases where
|
||||
// sorting is not possible (modules splitted into different chunks).
|
||||
// So we not even trying and solve this by a microtask delay.
|
||||
"function promiseResolve() { return Promise.resolve(); }",
|
||||
"",
|
||||
"var wasmImportObjects = {",
|
||||
Template.indent(importObjects),
|
||||
"};"
|
||||
]);
|
||||
}
|
||||
);
|
||||
mainTemplate.hooks.requireEnsure.tap(
|
||||
"WasmMainTemplatePlugin",
|
||||
(source, chunk, hash) => {
|
||||
const webassemblyModuleFilename =
|
||||
mainTemplate.outputOptions.webassemblyModuleFilename;
|
||||
|
||||
const chunkModuleMaps = chunk.getChunkModuleMaps(m =>
|
||||
m.type.startsWith("webassembly")
|
||||
);
|
||||
if (Object.keys(chunkModuleMaps.id).length === 0) return source;
|
||||
const wasmModuleSrcPath = mainTemplate.getAssetPath(
|
||||
JSON.stringify(webassemblyModuleFilename),
|
||||
{
|
||||
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
|
||||
hashWithLength: length =>
|
||||
`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
|
||||
module: {
|
||||
id: '" + wasmModuleId + "',
|
||||
hash: `" + ${JSON.stringify(
|
||||
chunkModuleMaps.hash
|
||||
)}[wasmModuleId] + "`,
|
||||
hashWithLength(length) {
|
||||
const shortChunkHashMap = Object.create(null);
|
||||
for (const wasmModuleId of Object.keys(chunkModuleMaps.hash)) {
|
||||
if (typeof chunkModuleMaps.hash[wasmModuleId] === "string") {
|
||||
shortChunkHashMap[wasmModuleId] = chunkModuleMaps.hash[
|
||||
wasmModuleId
|
||||
].substr(0, length);
|
||||
}
|
||||
}
|
||||
return `" + ${JSON.stringify(
|
||||
shortChunkHashMap
|
||||
)}[wasmModuleId] + "`;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
const createImportObject = content =>
|
||||
this.mangleImports
|
||||
? `{ ${JSON.stringify(
|
||||
WebAssemblyUtils.MANGLED_MODULE
|
||||
)}: ${content} }`
|
||||
: content;
|
||||
return Template.asString([
|
||||
source,
|
||||
"",
|
||||
"// Fetch + compile chunk loading for webassembly",
|
||||
"",
|
||||
`var wasmModules = ${JSON.stringify(
|
||||
chunkModuleMaps.id
|
||||
)}[chunkId] || [];`,
|
||||
"",
|
||||
"wasmModules.forEach(function(wasmModuleId) {",
|
||||
Template.indent([
|
||||
"var installedWasmModuleData = installedWasmModules[wasmModuleId];",
|
||||
"",
|
||||
'// a Promise means "currently loading" or "already loaded".',
|
||||
"if(installedWasmModuleData)",
|
||||
Template.indent(["promises.push(installedWasmModuleData);"]),
|
||||
"else {",
|
||||
Template.indent([
|
||||
`var importObject = wasmImportObjects[wasmModuleId]();`,
|
||||
`var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`,
|
||||
"var promise;",
|
||||
this.supportsStreaming
|
||||
? Template.asString([
|
||||
"if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {",
|
||||
Template.indent([
|
||||
"promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {",
|
||||
Template.indent([
|
||||
`return WebAssembly.instantiate(items[0], ${createImportObject(
|
||||
"items[1]"
|
||||
)});`
|
||||
]),
|
||||
"});"
|
||||
]),
|
||||
"} else if(typeof WebAssembly.instantiateStreaming === 'function') {",
|
||||
Template.indent([
|
||||
`promise = WebAssembly.instantiateStreaming(req, ${createImportObject(
|
||||
"importObject"
|
||||
)});`
|
||||
])
|
||||
])
|
||||
: Template.asString([
|
||||
"if(importObject instanceof Promise) {",
|
||||
Template.indent([
|
||||
"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });",
|
||||
"promise = Promise.all([",
|
||||
Template.indent([
|
||||
"bytesPromise.then(function(bytes) { return WebAssembly.compile(bytes); }),",
|
||||
"importObject"
|
||||
]),
|
||||
"]).then(function(items) {",
|
||||
Template.indent([
|
||||
`return WebAssembly.instantiate(items[0], ${createImportObject(
|
||||
"items[1]"
|
||||
)});`
|
||||
]),
|
||||
"});"
|
||||
])
|
||||
]),
|
||||
"} else {",
|
||||
Template.indent([
|
||||
"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });",
|
||||
"promise = bytesPromise.then(function(bytes) {",
|
||||
Template.indent([
|
||||
`return WebAssembly.instantiate(bytes, ${createImportObject(
|
||||
"importObject"
|
||||
)});`
|
||||
]),
|
||||
"});"
|
||||
]),
|
||||
"}",
|
||||
"promises.push(installedWasmModules[wasmModuleId] = promise.then(function(res) {",
|
||||
Template.indent([
|
||||
`return ${mainTemplate.requireFn}.w[wasmModuleId] = (res.instance || res).exports;`
|
||||
]),
|
||||
"}));"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"});"
|
||||
]);
|
||||
}
|
||||
);
|
||||
mainTemplate.hooks.requireExtensions.tap(
|
||||
"WasmMainTemplatePlugin",
|
||||
(source, chunk) => {
|
||||
if (!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly"))) {
|
||||
return source;
|
||||
}
|
||||
return Template.asString([
|
||||
source,
|
||||
"",
|
||||
"// object with all WebAssembly.instance exports",
|
||||
`${mainTemplate.requireFn}.w = {};`
|
||||
]);
|
||||
}
|
||||
);
|
||||
mainTemplate.hooks.hash.tap("WasmMainTemplatePlugin", hash => {
|
||||
hash.update("WasmMainTemplatePlugin");
|
||||
hash.update("2");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WasmMainTemplatePlugin;
|
458
web/node_modules/webpack/lib/wasm/WebAssemblyGenerator.js
generated
vendored
Normal file
458
web/node_modules/webpack/lib/wasm/WebAssemblyGenerator.js
generated
vendored
Normal file
|
@ -0,0 +1,458 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const Generator = require("../Generator");
|
||||
const Template = require("../Template");
|
||||
const WebAssemblyUtils = require("./WebAssemblyUtils");
|
||||
const { RawSource } = require("webpack-sources");
|
||||
|
||||
const { editWithAST, addWithAST } = require("@webassemblyjs/wasm-edit");
|
||||
const { decode } = require("@webassemblyjs/wasm-parser");
|
||||
const t = require("@webassemblyjs/ast");
|
||||
const {
|
||||
moduleContextFromModuleAST
|
||||
} = require("@webassemblyjs/helper-module-context");
|
||||
|
||||
const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
|
||||
|
||||
/** @typedef {import("../Module")} Module */
|
||||
/** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */
|
||||
/** @typedef {import("../NormalModule")} NormalModule */
|
||||
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../Dependency").DependencyTemplate} DependencyTemplate */
|
||||
|
||||
/**
|
||||
* @typedef {(ArrayBuffer) => ArrayBuffer} ArrayBufferTransform
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {Function[]} fns transforms
|
||||
* @returns {Function} composed transform
|
||||
*/
|
||||
const compose = (...fns) => {
|
||||
return fns.reduce(
|
||||
(prevFn, nextFn) => {
|
||||
return value => nextFn(prevFn(value));
|
||||
},
|
||||
value => value
|
||||
);
|
||||
};
|
||||
|
||||
// TODO replace with @callback
|
||||
|
||||
/**
|
||||
* Removes the start instruction
|
||||
*
|
||||
* @param {Object} state unused state
|
||||
* @returns {ArrayBufferTransform} transform
|
||||
*/
|
||||
const removeStartFunc = state => bin => {
|
||||
return editWithAST(state.ast, bin, {
|
||||
Start(path) {
|
||||
path.remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get imported globals
|
||||
*
|
||||
* @param {Object} ast Module's AST
|
||||
* @returns {Array<t.ModuleImport>} - nodes
|
||||
*/
|
||||
const getImportedGlobals = ast => {
|
||||
const importedGlobals = [];
|
||||
|
||||
t.traverse(ast, {
|
||||
ModuleImport({ node }) {
|
||||
if (t.isGlobalType(node.descr)) {
|
||||
importedGlobals.push(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return importedGlobals;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the count for imported func
|
||||
*
|
||||
* @param {Object} ast Module's AST
|
||||
* @returns {Number} - count
|
||||
*/
|
||||
const getCountImportedFunc = ast => {
|
||||
let count = 0;
|
||||
|
||||
t.traverse(ast, {
|
||||
ModuleImport({ node }) {
|
||||
if (t.isFuncImportDescr(node.descr)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get next type index
|
||||
*
|
||||
* @param {Object} ast Module's AST
|
||||
* @returns {t.Index} - index
|
||||
*/
|
||||
const getNextTypeIndex = ast => {
|
||||
const typeSectionMetadata = t.getSectionMetadata(ast, "type");
|
||||
|
||||
if (typeSectionMetadata === undefined) {
|
||||
return t.indexLiteral(0);
|
||||
}
|
||||
|
||||
return t.indexLiteral(typeSectionMetadata.vectorOfSize.value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get next func index
|
||||
*
|
||||
* The Func section metadata provide informations for implemented funcs
|
||||
* in order to have the correct index we shift the index by number of external
|
||||
* functions.
|
||||
*
|
||||
* @param {Object} ast Module's AST
|
||||
* @param {Number} countImportedFunc number of imported funcs
|
||||
* @returns {t.Index} - index
|
||||
*/
|
||||
const getNextFuncIndex = (ast, countImportedFunc) => {
|
||||
const funcSectionMetadata = t.getSectionMetadata(ast, "func");
|
||||
|
||||
if (funcSectionMetadata === undefined) {
|
||||
return t.indexLiteral(0 + countImportedFunc);
|
||||
}
|
||||
|
||||
const vectorOfSize = funcSectionMetadata.vectorOfSize.value;
|
||||
|
||||
return t.indexLiteral(vectorOfSize + countImportedFunc);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an init instruction for a global type
|
||||
* @param {t.GlobalType} globalType the global type
|
||||
* @returns {t.Instruction} init expression
|
||||
*/
|
||||
const createDefaultInitForGlobal = globalType => {
|
||||
if (globalType.valtype[0] === "i") {
|
||||
// create NumberLiteral global initializer
|
||||
return t.objectInstruction("const", globalType.valtype, [
|
||||
t.numberLiteralFromRaw(66)
|
||||
]);
|
||||
} else if (globalType.valtype[0] === "f") {
|
||||
// create FloatLiteral global initializer
|
||||
return t.objectInstruction("const", globalType.valtype, [
|
||||
t.floatLiteral(66, false, false, "66")
|
||||
]);
|
||||
} else {
|
||||
throw new Error("unknown type: " + globalType.valtype);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewrite the import globals:
|
||||
* - removes the ModuleImport instruction
|
||||
* - injects at the same offset a mutable global of the same type
|
||||
*
|
||||
* Since the imported globals are before the other global declarations, our
|
||||
* indices will be preserved.
|
||||
*
|
||||
* Note that globals will become mutable.
|
||||
*
|
||||
* @param {Object} state unused state
|
||||
* @returns {ArrayBufferTransform} transform
|
||||
*/
|
||||
const rewriteImportedGlobals = state => bin => {
|
||||
const additionalInitCode = state.additionalInitCode;
|
||||
const newGlobals = [];
|
||||
|
||||
bin = editWithAST(state.ast, bin, {
|
||||
ModuleImport(path) {
|
||||
if (t.isGlobalType(path.node.descr)) {
|
||||
const globalType = path.node.descr;
|
||||
|
||||
globalType.mutability = "var";
|
||||
|
||||
const init = [
|
||||
createDefaultInitForGlobal(globalType),
|
||||
t.instruction("end")
|
||||
];
|
||||
|
||||
newGlobals.push(t.global(globalType, init));
|
||||
|
||||
path.remove();
|
||||
}
|
||||
},
|
||||
|
||||
// in order to preserve non-imported global's order we need to re-inject
|
||||
// those as well
|
||||
Global(path) {
|
||||
const { node } = path;
|
||||
const [init] = node.init;
|
||||
|
||||
if (init.id === "get_global") {
|
||||
node.globalType.mutability = "var";
|
||||
|
||||
const initialGlobalidx = init.args[0];
|
||||
|
||||
node.init = [
|
||||
createDefaultInitForGlobal(node.globalType),
|
||||
t.instruction("end")
|
||||
];
|
||||
|
||||
additionalInitCode.push(
|
||||
/**
|
||||
* get_global in global initializer only works for imported globals.
|
||||
* They have the same indices as the init params, so use the
|
||||
* same index.
|
||||
*/
|
||||
t.instruction("get_local", [initialGlobalidx]),
|
||||
t.instruction("set_global", [t.indexLiteral(newGlobals.length)])
|
||||
);
|
||||
}
|
||||
|
||||
newGlobals.push(node);
|
||||
|
||||
path.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Add global declaration instructions
|
||||
return addWithAST(state.ast, bin, newGlobals);
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewrite the export names
|
||||
* @param {Object} state state
|
||||
* @param {Object} state.ast Module's ast
|
||||
* @param {Module} state.module Module
|
||||
* @param {Set<string>} state.externalExports Module
|
||||
* @returns {ArrayBufferTransform} transform
|
||||
*/
|
||||
const rewriteExportNames = ({ ast, module, externalExports }) => bin => {
|
||||
return editWithAST(ast, bin, {
|
||||
ModuleExport(path) {
|
||||
const isExternal = externalExports.has(path.node.name);
|
||||
if (isExternal) {
|
||||
path.remove();
|
||||
return;
|
||||
}
|
||||
const usedName = module.isUsed(path.node.name);
|
||||
if (!usedName) {
|
||||
path.remove();
|
||||
return;
|
||||
}
|
||||
path.node.name = usedName;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Mangle import names and modules
|
||||
* @param {Object} state state
|
||||
* @param {Object} state.ast Module's ast
|
||||
* @param {Map<string, UsedWasmDependency>} state.usedDependencyMap mappings to mangle names
|
||||
* @returns {ArrayBufferTransform} transform
|
||||
*/
|
||||
const rewriteImports = ({ ast, usedDependencyMap }) => bin => {
|
||||
return editWithAST(ast, bin, {
|
||||
ModuleImport(path) {
|
||||
const result = usedDependencyMap.get(
|
||||
path.node.module + ":" + path.node.name
|
||||
);
|
||||
|
||||
if (result !== undefined) {
|
||||
path.node.module = result.module;
|
||||
path.node.name = result.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an init function.
|
||||
*
|
||||
* The init function fills the globals given input arguments.
|
||||
*
|
||||
* @param {Object} state transformation state
|
||||
* @param {Object} state.ast Module's ast
|
||||
* @param {t.Identifier} state.initFuncId identifier of the init function
|
||||
* @param {t.Index} state.startAtFuncOffset index of the start function
|
||||
* @param {t.ModuleImport[]} state.importedGlobals list of imported globals
|
||||
* @param {t.Instruction[]} state.additionalInitCode list of addition instructions for the init function
|
||||
* @param {t.Index} state.nextFuncIndex index of the next function
|
||||
* @param {t.Index} state.nextTypeIndex index of the next type
|
||||
* @returns {ArrayBufferTransform} transform
|
||||
*/
|
||||
const addInitFunction = ({
|
||||
ast,
|
||||
initFuncId,
|
||||
startAtFuncOffset,
|
||||
importedGlobals,
|
||||
additionalInitCode,
|
||||
nextFuncIndex,
|
||||
nextTypeIndex
|
||||
}) => bin => {
|
||||
const funcParams = importedGlobals.map(importedGlobal => {
|
||||
// used for debugging
|
||||
const id = t.identifier(`${importedGlobal.module}.${importedGlobal.name}`);
|
||||
|
||||
return t.funcParam(importedGlobal.descr.valtype, id);
|
||||
});
|
||||
|
||||
const funcBody = importedGlobals.reduce((acc, importedGlobal, index) => {
|
||||
const args = [t.indexLiteral(index)];
|
||||
const body = [
|
||||
t.instruction("get_local", args),
|
||||
t.instruction("set_global", args)
|
||||
];
|
||||
|
||||
return [...acc, ...body];
|
||||
}, []);
|
||||
|
||||
if (typeof startAtFuncOffset === "number") {
|
||||
funcBody.push(t.callInstruction(t.numberLiteralFromRaw(startAtFuncOffset)));
|
||||
}
|
||||
|
||||
for (const instr of additionalInitCode) {
|
||||
funcBody.push(instr);
|
||||
}
|
||||
|
||||
funcBody.push(t.instruction("end"));
|
||||
|
||||
const funcResults = [];
|
||||
|
||||
// Code section
|
||||
const funcSignature = t.signature(funcParams, funcResults);
|
||||
const func = t.func(initFuncId, funcSignature, funcBody);
|
||||
|
||||
// Type section
|
||||
const functype = t.typeInstruction(undefined, funcSignature);
|
||||
|
||||
// Func section
|
||||
const funcindex = t.indexInFuncSection(nextTypeIndex);
|
||||
|
||||
// Export section
|
||||
const moduleExport = t.moduleExport(
|
||||
initFuncId.value,
|
||||
t.moduleExportDescr("Func", nextFuncIndex)
|
||||
);
|
||||
|
||||
return addWithAST(ast, bin, [func, moduleExport, funcindex, functype]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract mangle mappings from module
|
||||
* @param {Module} module current module
|
||||
* @param {boolean} mangle mangle imports
|
||||
* @returns {Map<string, UsedWasmDependency>} mappings to mangled names
|
||||
*/
|
||||
const getUsedDependencyMap = (module, mangle) => {
|
||||
/** @type {Map<string, UsedWasmDependency>} */
|
||||
const map = new Map();
|
||||
for (const usedDep of WebAssemblyUtils.getUsedDependencies(module, mangle)) {
|
||||
const dep = usedDep.dependency;
|
||||
const request = dep.request;
|
||||
const exportName = dep.name;
|
||||
map.set(request + ":" + exportName, usedDep);
|
||||
}
|
||||
return map;
|
||||
};
|
||||
|
||||
class WebAssemblyGenerator extends Generator {
|
||||
constructor(options) {
|
||||
super();
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module module for which the code should be generated
|
||||
* @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
|
||||
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
||||
* @param {string} type which kind of code should be generated
|
||||
* @returns {Source} generated code
|
||||
*/
|
||||
generate(module, dependencyTemplates, runtimeTemplate, type) {
|
||||
let bin = module.originalSource().source();
|
||||
|
||||
const initFuncId = t.identifier(
|
||||
Array.isArray(module.usedExports)
|
||||
? Template.numberToIdentifer(module.usedExports.length)
|
||||
: "__webpack_init__"
|
||||
);
|
||||
|
||||
// parse it
|
||||
const ast = decode(bin, {
|
||||
ignoreDataSection: true,
|
||||
ignoreCodeSection: true,
|
||||
ignoreCustomNameSection: true
|
||||
});
|
||||
|
||||
const moduleContext = moduleContextFromModuleAST(ast.body[0]);
|
||||
|
||||
const importedGlobals = getImportedGlobals(ast);
|
||||
const countImportedFunc = getCountImportedFunc(ast);
|
||||
const startAtFuncOffset = moduleContext.getStart();
|
||||
const nextFuncIndex = getNextFuncIndex(ast, countImportedFunc);
|
||||
const nextTypeIndex = getNextTypeIndex(ast);
|
||||
|
||||
const usedDependencyMap = getUsedDependencyMap(
|
||||
module,
|
||||
this.options.mangleImports
|
||||
);
|
||||
const externalExports = new Set(
|
||||
module.dependencies
|
||||
.filter(d => d instanceof WebAssemblyExportImportedDependency)
|
||||
.map(d => {
|
||||
const wasmDep = /** @type {WebAssemblyExportImportedDependency} */ (d);
|
||||
return wasmDep.exportName;
|
||||
})
|
||||
);
|
||||
|
||||
/** @type {t.Instruction[]} */
|
||||
const additionalInitCode = [];
|
||||
|
||||
const transform = compose(
|
||||
rewriteExportNames({
|
||||
ast,
|
||||
module,
|
||||
externalExports
|
||||
}),
|
||||
|
||||
removeStartFunc({ ast }),
|
||||
|
||||
rewriteImportedGlobals({ ast, additionalInitCode }),
|
||||
|
||||
rewriteImports({
|
||||
ast,
|
||||
usedDependencyMap
|
||||
}),
|
||||
|
||||
addInitFunction({
|
||||
ast,
|
||||
initFuncId,
|
||||
importedGlobals,
|
||||
additionalInitCode,
|
||||
startAtFuncOffset,
|
||||
nextFuncIndex,
|
||||
nextTypeIndex
|
||||
})
|
||||
);
|
||||
|
||||
const newBin = transform(bin);
|
||||
|
||||
return new RawSource(newBin);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebAssemblyGenerator;
|
88
web/node_modules/webpack/lib/wasm/WebAssemblyInInitialChunkError.js
generated
vendored
Normal file
88
web/node_modules/webpack/lib/wasm/WebAssemblyInInitialChunkError.js
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const WebpackError = require("../WebpackError");
|
||||
|
||||
/** @typedef {import("../Module")} Module */
|
||||
/** @typedef {import("../RequestShortener")} RequestShortener */
|
||||
|
||||
/**
|
||||
* @param {Module} module module to get chains from
|
||||
* @param {RequestShortener} requestShortener to make readable identifiers
|
||||
* @returns {string[]} all chains to the module
|
||||
*/
|
||||
const getInitialModuleChains = (module, requestShortener) => {
|
||||
const queue = [
|
||||
{ head: module, message: module.readableIdentifier(requestShortener) }
|
||||
];
|
||||
/** @type {Set<string>} */
|
||||
const results = new Set();
|
||||
/** @type {Set<string>} */
|
||||
const incompleteResults = new Set();
|
||||
/** @type {Set<Module>} */
|
||||
const visitedModules = new Set();
|
||||
|
||||
for (const chain of queue) {
|
||||
const { head, message } = chain;
|
||||
let final = true;
|
||||
/** @type {Set<Module>} */
|
||||
const alreadyReferencedModules = new Set();
|
||||
for (const reason of head.reasons) {
|
||||
const newHead = reason.module;
|
||||
if (newHead) {
|
||||
if (!newHead.getChunks().some(c => c.canBeInitial())) continue;
|
||||
final = false;
|
||||
if (alreadyReferencedModules.has(newHead)) continue;
|
||||
alreadyReferencedModules.add(newHead);
|
||||
const moduleName = newHead.readableIdentifier(requestShortener);
|
||||
const detail = reason.explanation ? ` (${reason.explanation})` : "";
|
||||
const newMessage = `${moduleName}${detail} --> ${message}`;
|
||||
if (visitedModules.has(newHead)) {
|
||||
incompleteResults.add(`... --> ${newMessage}`);
|
||||
continue;
|
||||
}
|
||||
visitedModules.add(newHead);
|
||||
queue.push({
|
||||
head: newHead,
|
||||
message: newMessage
|
||||
});
|
||||
} else {
|
||||
final = false;
|
||||
const newMessage = reason.explanation
|
||||
? `(${reason.explanation}) --> ${message}`
|
||||
: message;
|
||||
results.add(newMessage);
|
||||
}
|
||||
}
|
||||
if (final) {
|
||||
results.add(message);
|
||||
}
|
||||
}
|
||||
for (const result of incompleteResults) {
|
||||
results.add(result);
|
||||
}
|
||||
return Array.from(results);
|
||||
};
|
||||
|
||||
module.exports = class WebAssemblyInInitialChunkError extends WebpackError {
|
||||
/**
|
||||
* @param {Module} module WASM module
|
||||
* @param {RequestShortener} requestShortener request shortener
|
||||
*/
|
||||
constructor(module, requestShortener) {
|
||||
const moduleChains = getInitialModuleChains(module, requestShortener);
|
||||
const message = `WebAssembly module is included in initial chunk.
|
||||
This is not allowed, because WebAssembly download and compilation must happen asynchronous.
|
||||
Add an async splitpoint (i. e. import()) somewhere between your entrypoint and the WebAssembly module:
|
||||
${moduleChains.map(s => `* ${s}`).join("\n")}`;
|
||||
|
||||
super(message);
|
||||
this.name = "WebAssemblyInInitialChunkError";
|
||||
this.hideStack = true;
|
||||
this.module = module;
|
||||
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
};
|
152
web/node_modules/webpack/lib/wasm/WebAssemblyJavascriptGenerator.js
generated
vendored
Normal file
152
web/node_modules/webpack/lib/wasm/WebAssemblyJavascriptGenerator.js
generated
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const Generator = require("../Generator");
|
||||
const Template = require("../Template");
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
||||
const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
|
||||
|
||||
/** @typedef {import("../NormalModule")} NormalModule */
|
||||
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../Dependency").DependencyTemplate} DependencyTemplate */
|
||||
|
||||
class WebAssemblyJavascriptGenerator extends Generator {
|
||||
/**
|
||||
* @param {NormalModule} module module for which the code should be generated
|
||||
* @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
|
||||
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
||||
* @param {string} type which kind of code should be generated
|
||||
* @returns {Source} generated code
|
||||
*/
|
||||
generate(module, dependencyTemplates, runtimeTemplate, type) {
|
||||
const initIdentifer = Array.isArray(module.usedExports)
|
||||
? Template.numberToIdentifer(module.usedExports.length)
|
||||
: "__webpack_init__";
|
||||
|
||||
let needExportsCopy = false;
|
||||
const importedModules = new Map();
|
||||
const initParams = [];
|
||||
let index = 0;
|
||||
for (const dep of module.dependencies) {
|
||||
const depAsAny = /** @type {any} */ (dep);
|
||||
if (dep.module) {
|
||||
let importData = importedModules.get(dep.module);
|
||||
if (importData === undefined) {
|
||||
importedModules.set(
|
||||
dep.module,
|
||||
(importData = {
|
||||
importVar: `m${index}`,
|
||||
index,
|
||||
request:
|
||||
"userRequest" in depAsAny ? depAsAny.userRequest : undefined,
|
||||
names: new Set(),
|
||||
reexports: []
|
||||
})
|
||||
);
|
||||
index++;
|
||||
}
|
||||
if (dep instanceof WebAssemblyImportDependency) {
|
||||
importData.names.add(dep.name);
|
||||
if (dep.description.type === "GlobalType") {
|
||||
const exportName = dep.name;
|
||||
const usedName = dep.module && dep.module.isUsed(exportName);
|
||||
|
||||
if (dep.module) {
|
||||
if (usedName) {
|
||||
initParams.push(
|
||||
runtimeTemplate.exportFromImport({
|
||||
module: dep.module,
|
||||
request: dep.request,
|
||||
importVar: importData.importVar,
|
||||
originModule: module,
|
||||
exportName: dep.name,
|
||||
asiSafe: true,
|
||||
isCall: false,
|
||||
callContext: null
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dep instanceof WebAssemblyExportImportedDependency) {
|
||||
importData.names.add(dep.name);
|
||||
const usedName = module.isUsed(dep.exportName);
|
||||
if (usedName) {
|
||||
const exportProp = `${module.exportsArgument}[${JSON.stringify(
|
||||
usedName
|
||||
)}]`;
|
||||
const defineStatement = Template.asString([
|
||||
`${exportProp} = ${runtimeTemplate.exportFromImport({
|
||||
module: dep.module,
|
||||
request: dep.request,
|
||||
importVar: importData.importVar,
|
||||
originModule: module,
|
||||
exportName: dep.name,
|
||||
asiSafe: true,
|
||||
isCall: false,
|
||||
callContext: null
|
||||
})};`,
|
||||
`if(WebAssembly.Global) ${exportProp} = ` +
|
||||
`new WebAssembly.Global({ value: ${JSON.stringify(
|
||||
dep.valueType
|
||||
)} }, ${exportProp});`
|
||||
]);
|
||||
importData.reexports.push(defineStatement);
|
||||
needExportsCopy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const importsCode = Template.asString(
|
||||
Array.from(
|
||||
importedModules,
|
||||
([module, { importVar, request, reexports }]) => {
|
||||
const importStatement = runtimeTemplate.importStatement({
|
||||
module,
|
||||
request,
|
||||
importVar,
|
||||
originModule: module
|
||||
});
|
||||
return importStatement + reexports.join("\n");
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// create source
|
||||
const source = new RawSource(
|
||||
[
|
||||
'"use strict";',
|
||||
"// Instantiate WebAssembly module",
|
||||
"var wasmExports = __webpack_require__.w[module.i];",
|
||||
|
||||
!Array.isArray(module.usedExports)
|
||||
? `__webpack_require__.r(${module.exportsArgument});`
|
||||
: "",
|
||||
|
||||
// this must be before import for circular dependencies
|
||||
"// export exports from WebAssembly module",
|
||||
Array.isArray(module.usedExports) && !needExportsCopy
|
||||
? `${module.moduleArgument}.exports = wasmExports;`
|
||||
: "for(var name in wasmExports) " +
|
||||
`if(name != ${JSON.stringify(initIdentifer)}) ` +
|
||||
`${module.exportsArgument}[name] = wasmExports[name];`,
|
||||
"// exec imports from WebAssembly module (for esm order)",
|
||||
importsCode,
|
||||
"",
|
||||
"// exec wasm module",
|
||||
`wasmExports[${JSON.stringify(initIdentifer)}](${initParams.join(
|
||||
", "
|
||||
)})`
|
||||
].join("\n")
|
||||
);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebAssemblyJavascriptGenerator;
|
128
web/node_modules/webpack/lib/wasm/WebAssemblyModulesPlugin.js
generated
vendored
Normal file
128
web/node_modules/webpack/lib/wasm/WebAssemblyModulesPlugin.js
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const Generator = require("../Generator");
|
||||
const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
|
||||
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
||||
const WebAssemblyInInitialChunkError = require("./WebAssemblyInInitialChunkError");
|
||||
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
||||
let WebAssemblyGenerator;
|
||||
let WebAssemblyJavascriptGenerator;
|
||||
let WebAssemblyParser;
|
||||
|
||||
class WebAssemblyModulesPlugin {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Compiler} compiler compiler
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap(
|
||||
"WebAssemblyModulesPlugin",
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
compilation.dependencyFactories.set(
|
||||
WebAssemblyImportDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
WebAssemblyExportImportedDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for("webassembly/experimental")
|
||||
.tap("WebAssemblyModulesPlugin", () => {
|
||||
if (WebAssemblyParser === undefined) {
|
||||
WebAssemblyParser = require("./WebAssemblyParser");
|
||||
}
|
||||
return new WebAssemblyParser();
|
||||
});
|
||||
|
||||
normalModuleFactory.hooks.createGenerator
|
||||
.for("webassembly/experimental")
|
||||
.tap("WebAssemblyModulesPlugin", () => {
|
||||
if (WebAssemblyGenerator === undefined) {
|
||||
WebAssemblyGenerator = require("./WebAssemblyGenerator");
|
||||
}
|
||||
if (WebAssemblyJavascriptGenerator === undefined) {
|
||||
WebAssemblyJavascriptGenerator = require("./WebAssemblyJavascriptGenerator");
|
||||
}
|
||||
return Generator.byType({
|
||||
javascript: new WebAssemblyJavascriptGenerator(),
|
||||
webassembly: new WebAssemblyGenerator(this.options)
|
||||
});
|
||||
});
|
||||
|
||||
compilation.chunkTemplate.hooks.renderManifest.tap(
|
||||
"WebAssemblyModulesPlugin",
|
||||
(result, options) => {
|
||||
const chunk = options.chunk;
|
||||
const outputOptions = options.outputOptions;
|
||||
const moduleTemplates = options.moduleTemplates;
|
||||
const dependencyTemplates = options.dependencyTemplates;
|
||||
|
||||
for (const module of chunk.modulesIterable) {
|
||||
if (module.type && module.type.startsWith("webassembly")) {
|
||||
const filenameTemplate =
|
||||
outputOptions.webassemblyModuleFilename;
|
||||
|
||||
result.push({
|
||||
render: () =>
|
||||
this.renderWebAssembly(
|
||||
module,
|
||||
moduleTemplates.webassembly,
|
||||
dependencyTemplates
|
||||
),
|
||||
filenameTemplate,
|
||||
pathOptions: {
|
||||
module
|
||||
},
|
||||
identifier: `webassemblyModule${module.id}`,
|
||||
hash: module.hash
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
);
|
||||
|
||||
compilation.hooks.afterChunks.tap("WebAssemblyModulesPlugin", () => {
|
||||
const initialWasmModules = new Set();
|
||||
for (const chunk of compilation.chunks) {
|
||||
if (chunk.canBeInitial()) {
|
||||
for (const module of chunk.modulesIterable) {
|
||||
if (module.type.startsWith("webassembly")) {
|
||||
initialWasmModules.add(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const module of initialWasmModules) {
|
||||
compilation.errors.push(
|
||||
new WebAssemblyInInitialChunkError(
|
||||
module,
|
||||
compilation.requestShortener
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
renderWebAssembly(module, moduleTemplate, dependencyTemplates) {
|
||||
return moduleTemplate.render(module, dependencyTemplates, {});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebAssemblyModulesPlugin;
|
175
web/node_modules/webpack/lib/wasm/WebAssemblyParser.js
generated
vendored
Normal file
175
web/node_modules/webpack/lib/wasm/WebAssemblyParser.js
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const t = require("@webassemblyjs/ast");
|
||||
const { decode } = require("@webassemblyjs/wasm-parser");
|
||||
const {
|
||||
moduleContextFromModuleAST
|
||||
} = require("@webassemblyjs/helper-module-context");
|
||||
|
||||
const { Tapable } = require("tapable");
|
||||
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
||||
const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
|
||||
|
||||
/** @typedef {import("../Module")} Module */
|
||||
|
||||
const JS_COMPAT_TYPES = new Set(["i32", "f32", "f64"]);
|
||||
|
||||
/**
|
||||
* @param {t.Signature} signature the func signature
|
||||
* @returns {null | string} the type incompatible with js types
|
||||
*/
|
||||
const getJsIncompatibleType = signature => {
|
||||
for (const param of signature.params) {
|
||||
if (!JS_COMPAT_TYPES.has(param.valtype)) {
|
||||
return `${param.valtype} as parameter`;
|
||||
}
|
||||
}
|
||||
for (const type of signature.results) {
|
||||
if (!JS_COMPAT_TYPES.has(type)) return `${type} as result`;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO why are there two different Signature types?
|
||||
* @param {t.FuncSignature} signature the func signature
|
||||
* @returns {null | string} the type incompatible with js types
|
||||
*/
|
||||
const getJsIncompatibleTypeOfFuncSignature = signature => {
|
||||
for (const param of signature.args) {
|
||||
if (!JS_COMPAT_TYPES.has(param)) {
|
||||
return `${param} as parameter`;
|
||||
}
|
||||
}
|
||||
for (const type of signature.result) {
|
||||
if (!JS_COMPAT_TYPES.has(type)) return `${type} as result`;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const decoderOpts = {
|
||||
ignoreCodeSection: true,
|
||||
ignoreDataSection: true,
|
||||
|
||||
// this will avoid having to lookup with identifiers in the ModuleContext
|
||||
ignoreCustomNameSection: true
|
||||
};
|
||||
|
||||
class WebAssemblyParser extends Tapable {
|
||||
constructor(options) {
|
||||
super();
|
||||
this.hooks = {};
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
parse(binary, state) {
|
||||
// flag it as ESM
|
||||
state.module.buildMeta.exportsType = "namespace";
|
||||
|
||||
// parse it
|
||||
const program = decode(binary, decoderOpts);
|
||||
const module = program.body[0];
|
||||
|
||||
const moduleContext = moduleContextFromModuleAST(module);
|
||||
|
||||
// extract imports and exports
|
||||
const exports = (state.module.buildMeta.providedExports = []);
|
||||
const jsIncompatibleExports = (state.module.buildMeta.jsIncompatibleExports = []);
|
||||
|
||||
const importedGlobals = [];
|
||||
t.traverse(module, {
|
||||
ModuleExport({ node }) {
|
||||
const descriptor = node.descr;
|
||||
|
||||
if (descriptor.exportType === "Func") {
|
||||
const funcidx = descriptor.id.value;
|
||||
|
||||
/** @type {t.FuncSignature} */
|
||||
const funcSignature = moduleContext.getFunction(funcidx);
|
||||
|
||||
const incompatibleType = getJsIncompatibleTypeOfFuncSignature(
|
||||
funcSignature
|
||||
);
|
||||
|
||||
if (incompatibleType) {
|
||||
jsIncompatibleExports[node.name] = incompatibleType;
|
||||
}
|
||||
}
|
||||
|
||||
exports.push(node.name);
|
||||
|
||||
if (node.descr && node.descr.exportType === "Global") {
|
||||
const refNode = importedGlobals[node.descr.id.value];
|
||||
if (refNode) {
|
||||
const dep = new WebAssemblyExportImportedDependency(
|
||||
node.name,
|
||||
refNode.module,
|
||||
refNode.name,
|
||||
refNode.descr.valtype
|
||||
);
|
||||
|
||||
state.module.addDependency(dep);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Global({ node }) {
|
||||
const init = node.init[0];
|
||||
|
||||
let importNode = null;
|
||||
|
||||
if (init.id === "get_global") {
|
||||
const globalIdx = init.args[0].value;
|
||||
|
||||
if (globalIdx < importedGlobals.length) {
|
||||
importNode = importedGlobals[globalIdx];
|
||||
}
|
||||
}
|
||||
|
||||
importedGlobals.push(importNode);
|
||||
},
|
||||
|
||||
ModuleImport({ node }) {
|
||||
/** @type {false | string} */
|
||||
let onlyDirectImport = false;
|
||||
|
||||
if (t.isMemory(node.descr) === true) {
|
||||
onlyDirectImport = "Memory";
|
||||
} else if (t.isTable(node.descr) === true) {
|
||||
onlyDirectImport = "Table";
|
||||
} else if (t.isFuncImportDescr(node.descr) === true) {
|
||||
const incompatibleType = getJsIncompatibleType(node.descr.signature);
|
||||
if (incompatibleType) {
|
||||
onlyDirectImport = `Non-JS-compatible Func Sigurature (${incompatibleType})`;
|
||||
}
|
||||
} else if (t.isGlobalType(node.descr) === true) {
|
||||
const type = node.descr.valtype;
|
||||
if (!JS_COMPAT_TYPES.has(type)) {
|
||||
onlyDirectImport = `Non-JS-compatible Global Type (${type})`;
|
||||
}
|
||||
}
|
||||
|
||||
const dep = new WebAssemblyImportDependency(
|
||||
node.module,
|
||||
node.name,
|
||||
node.descr,
|
||||
onlyDirectImport
|
||||
);
|
||||
|
||||
state.module.addDependency(dep);
|
||||
|
||||
if (t.isGlobalType(node.descr)) {
|
||||
importedGlobals.push(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebAssemblyParser;
|
59
web/node_modules/webpack/lib/wasm/WebAssemblyUtils.js
generated
vendored
Normal file
59
web/node_modules/webpack/lib/wasm/WebAssemblyUtils.js
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const Template = require("../Template");
|
||||
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
||||
|
||||
/** @typedef {import("../Module")} Module */
|
||||
|
||||
/** @typedef {Object} UsedWasmDependency
|
||||
* @property {WebAssemblyImportDependency} dependency the dependency
|
||||
* @property {string} name the export name
|
||||
* @property {string} module the module name
|
||||
*/
|
||||
|
||||
const MANGLED_MODULE = "a";
|
||||
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
* @param {boolean} mangle mangle module and export names
|
||||
* @returns {UsedWasmDependency[]} used dependencies and (mangled) name
|
||||
*/
|
||||
const getUsedDependencies = (module, mangle) => {
|
||||
/** @type {UsedWasmDependency[]} */
|
||||
const array = [];
|
||||
let importIndex = 0;
|
||||
for (const dep of module.dependencies) {
|
||||
if (dep instanceof WebAssemblyImportDependency) {
|
||||
if (dep.description.type === "GlobalType" || dep.module === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const exportName = dep.name;
|
||||
// TODO add the following 3 lines when removing of ModuleExport is possible
|
||||
// const importedModule = dep.module;
|
||||
// const usedName = importedModule && importedModule.isUsed(exportName);
|
||||
// if (usedName !== false) {
|
||||
if (mangle) {
|
||||
array.push({
|
||||
dependency: dep,
|
||||
name: Template.numberToIdentifer(importIndex++),
|
||||
module: MANGLED_MODULE
|
||||
});
|
||||
} else {
|
||||
array.push({
|
||||
dependency: dep,
|
||||
name: exportName,
|
||||
module: dep.request
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
};
|
||||
|
||||
exports.getUsedDependencies = getUsedDependencies;
|
||||
exports.MANGLED_MODULE = MANGLED_MODULE;
|
Loading…
Add table
Add a link
Reference in a new issue