Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
cpeterso opened this issue Sep 2, 2021 · 0 comments

Comments

@cpeterso
Copy link

cpeterso commented Sep 2, 2021

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

function AsmTest(stdlib, foreign, buffer) {
  "use asm";
  function foo() { return 0; }
  return { foo: foo };
}

You can reproduce the error using this JS Fiddle example:

  1. Load https://jsfiddle.net/1kcf69g3/ in Firefox.
  2. Click the Run button.
  3. Open Firefox's DevTools console using Shift+Ctrl+I on Windows or Linux or Shift+Command+I on macOS.
  4. 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:

http://asmjs.org/spec/latest/#validateexport-s

Expected Output

function AsmTest(stdlib, foreign, buffer) {
  "use asm";

  function foo() {
    return 0;
  }

  return {
    foo: foo
  };
}

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 #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:

webtorrent/webtorrent#1830
webtorrent/webtorrent#1252
webtorrent/webtorrent#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:

(function(n,o,u){"use asm";function f(){return 0}return{foo:f}})().foo();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant