Skip to content

Commit 59f08fb

Browse files
authored
Use ESTree-based optimizer for core JS passes, to support ES6+ inputs (#7973)
Fixes #6000 The key change here is to rewrite the JS optimizer passes that run in a normal `-O3` etc. build from the Uglify1 AST to ESTree. With ESTree we can use modern parsers etc. so that we support ES6+ inputs to js libraries, pre-jses, EM_ASM, etc. Aside from that rewrite, the other changes are less critical and can be altered later. Specifically, this uses acorn for parsing and terser for outputting, but we could switch to anything using ESTree very easily. Acorn is nice for parsing since it's small and standalone. For outputting I experimented with astring, which is small and nice, and escodegen, which looks very robust, but neither could output compact-enough JS to not regress our JS code sizes. This is not truly critical since for minimal code size people should use closure anyhow, however, it's nice for default builds to be small (and we don't run closure by default), and I didn't want to regress anything. Using the terser outputter achieves that. (Since it uses the Uglify2 AST internally, this means using their tool to convert ESTree to Uglify2.) They may be some minor code size changes with this PR, just because we use a different outputter now, but nothing major in either direction. Most changes seem positive actually. Sizes after closure are unchanged. This uses almost unmodified versions of acorn and terser, but they are stripped down to what we need, and I had to make two modifications, see these PRs: [acornjs/acorn#793](acornjs/acorn#793) (quote the error on parse exceptions) and [mishoo/UglifyJS#3323](mishoo/UglifyJS#3323) (preserve quoted properties). This may very slightly regress compile times when using those passes, as Uglify1 was just very fast. However, the change should be very small. This does _not_ rewrite every single JS optimizer pass. In particular the asm.js passes don't need to support ES6, and so don't need to be rewritten. There are also optional passes that do not run by default, that we can convert later depending on priority.
1 parent c3e6c60 commit 59f08fb

25 files changed

+17441
-601
lines changed

Diff for: tests/optimizer/AJSDCE-output.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
21
var z = fleefl();
2+
33
var zz = fleefl();
4+
45
function g(a) {
56
return a + 1;
67
}
8+
79
Module["g"] = g;
10+
811
function h(a) {
912
return a + 1;
1013
}
14+
1115
print(h(123));
12-
((function() {
16+
17+
(function() {
1318
var z = fleefl();
1419
var zz = fleefl();
1520
function g(a) {
@@ -20,8 +25,9 @@ print(h(123));
2025
return a + 1;
2126
}
2227
print(hh(123));
23-
}))();
28+
})();
29+
2430
function glue() {
2531
}
26-
glue();
2732

33+
glue();

Diff for: tests/optimizer/JSDCE-fors-output.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
for (var i in x) {}
2+
3+
for (var j = 0; ;) {}

Diff for: tests/optimizer/JSDCE-fors.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
for (var i in x) {}
3+
for (var j = 0;;) {}
4+

Diff for: tests/optimizer/JSDCE-hasOwnProperty-output.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
function hasOwnProperty(obj, prop) {
22
return Object.prototype.hasOwnProperty.call(obj, prop);
33
}
4+
45
if (hasOwnProperty({}, "prop_name")) {
56
console.log("yeah");
67
}

Diff for: tests/optimizer/JSDCE-output.js

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
1-
21
var z = fleefl();
2+
33
var zz = fleefl();
4+
45
var keeperObj = {
56
x: fleefl()
67
};
8+
79
var keeperArray = [ 1, 2, "3", four() ];
10+
811
function g(a) {
912
return a + 1;
1013
}
14+
1115
Module["g"] = g;
16+
1217
function h(a) {
1318
return a + 1;
1419
}
20+
1521
print(h(123));
16-
((function() {
22+
23+
(function() {
1724
var z = fleefl();
1825
var zz = fleefl();
1926
function g(a) {
@@ -24,31 +31,38 @@ print(h(123));
2431
return a + 1;
2532
}
2633
print(hh(123));
27-
}))();
34+
})();
35+
2836
function glue() {
2937
function lookup() {
3038
throw 1;
3139
}
3240
}
41+
3342
glue();
43+
3444
function _glCreateShader() {
3545
return 1;
3646
}
47+
3748
function emulate() {
3849
_glCreateShader = function _glCreateShader(shaderType) {
3950
return glCreateShader();
4051
};
4152
}
53+
4254
emulate();
55+
4356
___cxa_find_matching_catch_before();
57+
4458
function ___cxa_find_matching_catch_before() {
4559
if (!___cxa_find_matching_catch_before.buffer) ___cxa_find_matching_catch_before.buffer = {};
4660
}
61+
4762
function ___cxa_find_matching_catch_after() {
4863
if (!___cxa_find_matching_catch_after.buffer) ___cxa_find_matching_catch_after.buffer = {};
4964
}
50-
___cxa_find_matching_catch_after();
51-
var dotOther = Side.effect;
52-
5365

66+
___cxa_find_matching_catch_after();
5467

68+
var dotOther = Side.effect;

Diff for: tests/optimizer/JSDCE-uglifyjsNodeTypes-output.js

-54
This file was deleted.

Diff for: tests/optimizer/JSDCE-uglifyjsNodeTypes.js

-47
This file was deleted.

Diff for: tests/optimizer/applyDCEGraphRemovals-output.js

+23-9
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
11
var name;
2+
23
var asmLibraryArg = {
34
"save1": 1,
45
"save2": 2
56
};
7+
68
var expD1 = Module["expD1"] = asm["expD1"];
9+
710
var expD2 = Module["expD2"] = asm["expD2"];
11+
812
var expD3 = Module["expD3"] = asm["expD3"];
9-
var expD4 = undefined;
10-
var expI1 = Module["expI1"] = (function() {
13+
14+
var expD4;
15+
16+
var expI1 = Module["expI1"] = function() {
1117
return Module["asm"]["expI1"].apply(null, arguments);
12-
});
13-
var expI2 = Module["expI2"] = (function() {
18+
};
19+
20+
var expI2 = Module["expI2"] = function() {
1421
return Module["asm"]["expI2"].apply(null, arguments);
15-
});
16-
var expI3 = Module["expI3"] = (function() {
22+
};
23+
24+
var expI3 = Module["expI3"] = function() {
1725
return Module["asm"]["expI3"].apply(null, arguments);
18-
});
19-
var expI4 = undefined;
26+
};
27+
28+
var expI4;
29+
2030
expD1;
31+
2132
Module["expD2"];
33+
2234
asm["expD3"];
35+
2336
expI1;
37+
2438
Module["expI2"];
25-
asm["expI3"];
2639

40+
asm["expI3"];

Diff for: tests/optimizer/applyImportAndExportNameChanges-output.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var name;
2+
23
var asmLibraryArg = {
34
"a": 1,
45
"A": 33,
@@ -12,10 +13,9 @@ var asmLibraryArg = {
1213
"d": ___syscall140,
1314
"q": ___syscall146
1415
};
15-
var expD1 = Module["expD1"] = asm["c"];
16-
var expI1 = Module["expI1"] = (function() {
17-
return Module["asm"]["d"].apply(null, arguments);
18-
});
19-
2016

17+
var expD1 = Module["expD1"] = asm["c"];
2118

19+
var expI1 = Module["expI1"] = function() {
20+
return Module["asm"]["d"].apply(null, arguments);
21+
};

0 commit comments

Comments
 (0)