Remove unused OpenJPEG wasm fallback logic
Emscripten generates code that allows the caller to provide the Wasm module (thorugh Module.instantiateWasm), with a fallback in case .instantiateWasm is not provided. We always define instantiateWasm, so we can hard-code the check and let our dead code elimination logic remove the unused fallback. This commit also improved the dead code elimination logic so that if a function declaration becomes unused as a result of removing dead code, the function itself is removed.
This commit is contained in:
parent
2bb8099831
commit
aebe0cb67f
@ -47,6 +47,25 @@ function handlePreprocessorAction(ctx, actionName, args, path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function babelPluginPDFJSPreprocessor(babel, ctx) {
|
function babelPluginPDFJSPreprocessor(babel, ctx) {
|
||||||
|
function removeUnusedFunctions(path) {
|
||||||
|
let removed;
|
||||||
|
do {
|
||||||
|
removed = false;
|
||||||
|
path.scope.crawl();
|
||||||
|
for (const name in path.scope.bindings) {
|
||||||
|
const binding = path.scope.bindings[name];
|
||||||
|
if (!binding.referenced) {
|
||||||
|
const { path: bindingPath } = binding;
|
||||||
|
if (bindingPath.isFunctionDeclaration()) {
|
||||||
|
bindingPath.remove();
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we removed some functions, there might be new unused ones
|
||||||
|
} while (removed);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: "babel-plugin-pdfjs-preprocessor",
|
name: "babel-plugin-pdfjs-preprocessor",
|
||||||
manipulateOptions({ parserOpts }) {
|
manipulateOptions({ parserOpts }) {
|
||||||
@ -173,36 +192,6 @@ function babelPluginPDFJSPreprocessor(babel, ctx) {
|
|||||||
path.replaceWith(t.importExpression(source));
|
path.replaceWith(t.importExpression(source));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NewExpression(path) {
|
|
||||||
const { node } = path;
|
|
||||||
|
|
||||||
if (
|
|
||||||
t.isIdentifier(node.callee, { name: "URL" }) &&
|
|
||||||
node.arguments.length === 2
|
|
||||||
) {
|
|
||||||
const [arg1, arg2] = node.arguments;
|
|
||||||
|
|
||||||
if (
|
|
||||||
arg1.type === "StringLiteral" &&
|
|
||||||
arg1.value.endsWith(".wasm") &&
|
|
||||||
arg2.type === "MemberExpression"
|
|
||||||
) {
|
|
||||||
// This statement is generated by the Emscripten Compiler (emcc),
|
|
||||||
// however we're manually loading wasm-files and we want to ensure
|
|
||||||
// that bundlers will leave it alone; this *must* include Webpack.
|
|
||||||
arg1.leadingComments = [
|
|
||||||
{
|
|
||||||
type: "CommentBlock",
|
|
||||||
value: "webpackIgnore: true",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "CommentBlock",
|
|
||||||
value: "@vite-ignore",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"BlockStatement|StaticBlock": {
|
"BlockStatement|StaticBlock": {
|
||||||
// Visit node in post-order so that recursive flattening
|
// Visit node in post-order so that recursive flattening
|
||||||
// of blocks works correctly.
|
// of blocks works correctly.
|
||||||
@ -255,6 +244,8 @@ function babelPluginPDFJSPreprocessor(babel, ctx) {
|
|||||||
// Function body ends with return without arg -- removing it.
|
// Function body ends with return without arg -- removing it.
|
||||||
body.pop();
|
body.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeUnusedFunctions(path);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ClassMethod: {
|
ClassMethod: {
|
||||||
@ -277,6 +268,26 @@ function babelPluginPDFJSPreprocessor(babel, ctx) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Program: {
|
||||||
|
exit(path) {
|
||||||
|
if (path.node.sourceType === "module") {
|
||||||
|
removeUnusedFunctions(path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MemberExpression(path) {
|
||||||
|
// The Emscripten Compiler (emcc) generates code that allows the caller
|
||||||
|
// to provide the Wasm module (thorugh Module.instantiateWasm), with
|
||||||
|
// a fallback in case .instantiateWasm is not provided.
|
||||||
|
// We always define instantiateWasm, so we can hard-code the check
|
||||||
|
// and let our dead code elimination logic remove the unused fallback.
|
||||||
|
if (
|
||||||
|
path.parentPath.isIfStatement({ test: path.node }) &&
|
||||||
|
path.matchesPattern("Module.instantiateWasm")
|
||||||
|
) {
|
||||||
|
path.replaceWith(t.booleanLiteral(true));
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,3 +8,4 @@ function test() {
|
|||||||
}
|
}
|
||||||
"4";
|
"4";
|
||||||
}
|
}
|
||||||
|
test();
|
||||||
|
|||||||
1
external/builder/fixtures_babel/blocks.js
vendored
1
external/builder/fixtures_babel/blocks.js
vendored
@ -17,3 +17,4 @@ function test() {
|
|||||||
"4";
|
"4";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
test();
|
||||||
|
|||||||
@ -2,10 +2,12 @@ function f1() {
|
|||||||
"1";
|
"1";
|
||||||
"2";
|
"2";
|
||||||
}
|
}
|
||||||
|
f1();
|
||||||
function f2() {
|
function f2() {
|
||||||
"1";
|
"1";
|
||||||
"2";
|
"2";
|
||||||
}
|
}
|
||||||
|
f2();
|
||||||
function f3() {
|
function f3() {
|
||||||
if ("1") {
|
if ("1") {
|
||||||
"1";
|
"1";
|
||||||
@ -15,3 +17,4 @@ function f3() {
|
|||||||
"4";
|
"4";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f3();
|
||||||
|
|||||||
3
external/builder/fixtures_babel/comments.js
vendored
3
external/builder/fixtures_babel/comments.js
vendored
@ -6,6 +6,7 @@ function f1() {
|
|||||||
"2";
|
"2";
|
||||||
/* tail */
|
/* tail */
|
||||||
}
|
}
|
||||||
|
f1();
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
// head
|
// head
|
||||||
@ -14,6 +15,7 @@ function f2() {
|
|||||||
"2";
|
"2";
|
||||||
// tail
|
// tail
|
||||||
}
|
}
|
||||||
|
f2();
|
||||||
|
|
||||||
function f3() {
|
function f3() {
|
||||||
if ("1") { // begin block
|
if ("1") { // begin block
|
||||||
@ -24,3 +26,4 @@ function f3() {
|
|||||||
"4";
|
"4";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f3();
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
function f1() {}
|
function f1() {}
|
||||||
|
f1();
|
||||||
function f2() {
|
function f2() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
f2();
|
||||||
function f3() {
|
function f3() {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
throw "test";
|
throw "test";
|
||||||
}
|
}
|
||||||
|
f3();
|
||||||
function f4() {
|
function f4() {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
}
|
}
|
||||||
|
f4();
|
||||||
var obj = {
|
var obj = {
|
||||||
method1() {},
|
method1() {},
|
||||||
method2() {}
|
method2() {}
|
||||||
|
|||||||
4
external/builder/fixtures_babel/deadcode.js
vendored
4
external/builder/fixtures_babel/deadcode.js
vendored
@ -2,17 +2,20 @@ function f1() {
|
|||||||
return;
|
return;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
}
|
}
|
||||||
|
f1();
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
return 1;
|
return 1;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
}
|
}
|
||||||
|
f2();
|
||||||
|
|
||||||
function f3() {
|
function f3() {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
throw "test";
|
throw "test";
|
||||||
var j = 0;
|
var j = 0;
|
||||||
}
|
}
|
||||||
|
f3();
|
||||||
|
|
||||||
function f4() {
|
function f4() {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
@ -22,6 +25,7 @@ function f4() {
|
|||||||
throw "test";
|
throw "test";
|
||||||
var j = 0;
|
var j = 0;
|
||||||
}
|
}
|
||||||
|
f4();
|
||||||
|
|
||||||
var obj = {
|
var obj = {
|
||||||
method1() { return; var i = 0; },
|
method1() { return; var i = 0; },
|
||||||
|
|||||||
@ -16,3 +16,4 @@ if ('1') {
|
|||||||
function f1() {
|
function f1() {
|
||||||
"1";
|
"1";
|
||||||
}
|
}
|
||||||
|
f1();
|
||||||
|
|||||||
1
external/builder/fixtures_babel/ifs.js
vendored
1
external/builder/fixtures_babel/ifs.js
vendored
@ -32,3 +32,4 @@ function f1() {
|
|||||||
"2";
|
"2";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f1();
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
const wasmUrl = new URL(
|
|
||||||
/*webpackIgnore: true*/
|
|
||||||
/*@vite-ignore*/
|
|
||||||
"qwerty.wasm", import.meta.url);
|
|
||||||
1
external/builder/fixtures_babel/ignore.js
vendored
1
external/builder/fixtures_babel/ignore.js
vendored
@ -1 +0,0 @@
|
|||||||
const wasmUrl = new URL("qwerty.wasm" , import.meta.url);
|
|
||||||
5
external/builder/fixtures_babel/unused-function-expected.js
vendored
Normal file
5
external/builder/fixtures_babel/unused-function-expected.js
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
function usedByUsed() {}
|
||||||
|
function used() {
|
||||||
|
usedByUsed();
|
||||||
|
}
|
||||||
|
used();
|
||||||
14
external/builder/fixtures_babel/unused-function.js
vendored
Normal file
14
external/builder/fixtures_babel/unused-function.js
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function usedByUsed() {}
|
||||||
|
function usedByUnused() {}
|
||||||
|
function usedByRemovedCode() {}
|
||||||
|
|
||||||
|
function used() {
|
||||||
|
usedByUsed();
|
||||||
|
return;
|
||||||
|
usedByRemovedCode();
|
||||||
|
}
|
||||||
|
function unused() {
|
||||||
|
usedByUnused();
|
||||||
|
}
|
||||||
|
|
||||||
|
used();
|
||||||
27
gulpfile.mjs
27
gulpfile.mjs
@ -339,6 +339,33 @@ function createWebpackConfig(
|
|||||||
new webpack2.BannerPlugin({ banner: licenseHeaderLibre, raw: true })
|
new webpack2.BannerPlugin({ banner: licenseHeaderLibre, raw: true })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
plugins.push({
|
||||||
|
/** @param {import('webpack').Compiler} compiler */
|
||||||
|
apply(compiler) {
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
compiler.hooks.afterCompile.tap("VerifyImportMeta", compilation => {
|
||||||
|
for (const asset of compilation.getAssets()) {
|
||||||
|
if (asset.name.endsWith(".mjs")) {
|
||||||
|
const source = asset.source.source();
|
||||||
|
if (
|
||||||
|
typeof source === "string" &&
|
||||||
|
/new URL\([^,)]*,\s*import\.meta\.url/.test(source)
|
||||||
|
) {
|
||||||
|
errors.push(
|
||||||
|
`Output module ${asset.name} uses new URL(..., import.meta.url)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
compiler.hooks.afterEmit.tap("VerifyImportMeta", compilation => {
|
||||||
|
// Emit the errors after emitting the files, so that it's possible to
|
||||||
|
// look at the contents of the invalid bundle.
|
||||||
|
compilation.errors.push(...errors);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const alias = createWebpackAlias(bundleDefines);
|
const alias = createWebpackAlias(bundleDefines);
|
||||||
const experiments = isModule ? { outputModule: true } : undefined;
|
const experiments = isModule ? { outputModule: true } : undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user