asm.js code minified with babel-plugin-minify-dead-code-elimination causes "asm.js type error: initializer of exported object literal must be name of function" error in Firefox #1018
asm.js code minified with the "babel-plugin-minify-dead-code-elimination plugin causes an asm.js type error: initializer of exported object literal must be name of function error in Firefox.
NOTE: Even those this console message says "error", the code will still run correctly. However, Firefox will use its regular JS JIT instead of its asm.js-optimized JIT since the code's is no longer valid asm.js syntax.
To Reproduce
Minimal code to reproduce the bug
function AsmTest(stdlib, foreign, buffer) {
"use asm";
function foo() { return 0; }
return { foo: foo };
}
You can reproduce the error using this JS Fiddle example:
Open Firefox's DevTools console using Shift+Ctrl+I on Windows or Linux or Shift+Command+I on macOS.
Filter the console output for "asm.js".
You will see two asm.js messages, the first when Firefox JITs the GoodAsmTest() function and second when Firefox JITs the BadAsmTest() function:
Successfully compiled asm.js code (total compilation time 0ms)
asm.js type error: initializer of exported object literal must be name of function
NOTE: You must keep the DevTools console closed when you run the script! If you open the DevTools console before you run the script, Firefox disables its JIT and you will see a console message like asm.js type error: Disabled by lack of compiler support or asm.js type error: Asm.js optimizer disabled because debugger is active instead of the asm.js type error: initializer of exported object literal must be name of function JIT error.
Actual Output
function AsmTest() {
"use asm";
return {
foo: function () {
return 0;
}
};
}
The problem is that babel-minify is converting a standalone function definition into a function object in the AsmTest() function's return statement. asm.js requires that use asm functions return an object literal whose property values are function identifiers, not function objects:
You must manually add the babel-plugin-minify-dead-code-elimination plugin.
Possible solution
This problem could be avoided if babel-minify ignored use asm functions, as suggested in https://github.com/babel/minify/issues/599, or didn't run the the babel-plugin-minify-dead-code-elimination plugin on use asm functions.
Additional context
Here are multiple bug reports about this asm.js error in webtorrent.js caused by babel-minify:
The unminified version of webtorrent.js and a version minified by Terser load in Firefox without problem. But the version minified by babel-minify (including webtorrent's official webtorrent.min.js version) have the error.
Here is the minified output from Terser (which you can test yourself in the Terser REPL, which doesn't cause this asm.js error because it retains the standalone function f:
Describe the bug
asm.js code minified with the "babel-plugin-minify-dead-code-elimination plugin causes an
asm.js type error: initializer of exported object literal must be name of function
error in Firefox.NOTE: Even those this console message says "error", the code will still run correctly. However, Firefox will use its regular JS JIT instead of its asm.js-optimized JIT since the code's is no longer valid asm.js syntax.
To Reproduce
Minimal code to reproduce the bug
You can reproduce the error using this JS Fiddle example:
Run
button.Shift
+Ctrl
+I
on Windows or Linux orShift
+Command
+I
on macOS.You will see two asm.js messages, the first when Firefox JITs the
GoodAsmTest()
function and second when Firefox JITs theBadAsmTest()
function:NOTE: You must keep the DevTools console closed when you run the script! If you open the DevTools console before you run the script, Firefox disables its JIT and you will see a console message like
asm.js type error: Disabled by lack of compiler support
orasm.js type error: Asm.js optimizer disabled because debugger is active
instead of theasm.js type error: initializer of exported object literal must be name of function
JIT error.Actual Output
The problem is that babel-minify is converting a standalone function definition into a function object in the
AsmTest()
function'sreturn
statement. asm.js requires thatuse asm
functions return an object literal whose property values are function identifiers, not function objects:http://asmjs.org/spec/latest/#validateexport-s
Expected Output
Configuration
How are you using babel-minify?
Here is a live example of the bug in the Babel REPL with the
babel-plugin-minify-dead-code-elimination
plugin added:https://babeljs.io/repl/#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.6&spec=false&loose=false&code_lz=GYVwdgxgLglg9mABAQQM4FsAqBTVUAUeAJgDYwBGANIsHAE7YwDmY15Iww2dAlIgN4AoRIgBEIVNkQBDDKIDcwmuGjwktOPj79EDKCDpIADPMQBfJXoNIdGgFw04cc4rNA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=script&lineWrap=false&presets=env%2Creact%2Cstage-2&prettier=false&targets=&version=7.15.3&externalPlugins=babel-plugin-minify-dead-code-elimination%400.5.1&assumptions=%7B%7D
You must manually add the
babel-plugin-minify-dead-code-elimination
plugin.Possible solution
This problem could be avoided if babel-minify ignored
use asm
functions, as suggested in https://github.com/babel/minify/issues/599, or didn't run the thebabel-plugin-minify-dead-code-elimination
plugin onuse asm
functions.Additional context
Here are multiple bug reports about this asm.js error in webtorrent.js caused by babel-minify:
https://github.com/webtorrent/webtorrent/issues/1830 https://github.com/webtorrent/webtorrent/issues/1252 https://github.com/webtorrent/webtorrent/issues/281
The unminified version of webtorrent.js and a version minified by Terser load in Firefox without problem. But the version minified by babel-minify (including webtorrent's official webtorrent.min.js version) have the error.
Here is the minified output from Terser (which you can test yourself in the Terser REPL, which doesn't cause this asm.js error because it retains the standalone function
f
: