babel / babel/minify

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

Open
#1,018 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
4.4k
Forks
217
PR merge metrics
No merged PRs in 30d

Description

**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

```js
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**

```js
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**

```js
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 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:

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](https://terser.org/) load in Firefox without problem. But the version minified by babel-minify (including webtorrent's official [webtorrent.min.js](https://github.com/webtorrent/webtorrent/blob/1499cbfc143bba8733a9cd426877260fbd39c059/webtorrent.min.js) version) have the error.

Here is the minified output from [Terser](https://terser.org/) (which you can test yourself in the [Terser REPL](https://try.terser.org/), 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();
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.