// original code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;
function f0(a_1) {
return a_1 += (c = c + 1) + (a++ + [ typeof f2 == "function" && --_calls_ >= 0 && f2(void function() {
c = 1 + c, (("undefined" ^ "c") >> ([ , 0 ].length === 2) - 24..toString()) % ((Infinity & undefined) >>> (4 ^ "a"));
}(), --b + a++, delete b), , (c = c + 1) + (a_1 && a_1[/[abc4]/.test(([ (c = 1 + c,
((a_1 && (a_1[c = 1 + c, "b" >> 24..toString() >>> "function" + "c" != (a_1 && (a_1.c = 0 / -1 - (a_1 && (a_1[c = 1 + c,
(-2 <= "function" || 0 + false) << (1 == 2) % (38..toString() == ([ , 0 ].length === 2))] >>>= "b" & []))))] += 0 >>> 23..toString())) & (3 ^ 3)) << ((5 | 25) >> "undefined" + 5)), , (c = 1 + c,
(c = c + 1, "foo" >> "object") != ((c = c + 1, "foo") ^ (1, 5))), (c = 1 + c, (38..toString() ^ 2) - (-4 !== -5) != (NaN === "number") < null + 24..toString()), (c = 1 + c,
("object" ^ -1) > 3 - 22 < (!2 !== (a_1 = 5 >>> {}))) ][c = 1 + c, -1 & -1 && (23..toString(),
Infinity), (a_1 <<= "a" != false) << (undefined < this)] || b || 5).toString())] || a || 3).toString(), --b + (--b + delete b || a || 3).toString(), a_1 && a_1[b = a] ].NaN || a || 3).toString();
}
var c = f0([]);
console.log(null, a, b, c, Infinity, NaN, undefined);
// uglified code
// (beautified)
var o = 10, t = 100, n = 10, i = 0;
i = function(e) {
return e + ((i += 1) + "") + (t++ + [ "function" == typeof f2 && 0 <= --o && f2(void (i = 1 + i), --n + t++, delete n), , (i += 1) + "" + (e && e[/[abc4]/.test("" + ([ (i = 1 + i,
(0 & (e && (e[i = 1 + i, 0 != (e && (e.c = -0 - (e && (e[i = 1 + i, 0] >>>= 0))))] += 0))) << 29), , (i = 1 + i,
!0), !0, !0 < (!1 !== (e = 5)) ][i = 1 + (1 + (1 + ((i += 1) + 1))), (e <<= !0) << (void 0 < this)] || n || 5))] || t || 3), --n + "" + (--n + delete n || t || 3), e && e[n = t] ].NaN || t || 3);
}([]), console.log(null, t, n, i, 1 / 0, NaN, void 0);
md5-ab4809c032f319bbb50e9f2b606dba8b
original result:
null 101 101 '01101' Infinity NaN undefined
uglified result:
null 101 101 '1101' Infinity NaN undefined
minify(options):
{
"compress": {
"passes": 1000000,
"unsafe": true
},
"toplevel": true
}
@kzc this one's a little tricky.
$ cat test.js
console.log(function(a) {
return a + (a[0] = 0).toString();
}([]));
$ cat test.js | node
00
$ uglifyjs test.js -c unsafe | node
0
$ uglifyjs test.js -c unsafe
console.log(function(a) {
return a + "" + (a[0] = 0);
}([]));
Good one.
Given the dynamic nature of the language, I suspect that a bug-free optimizing JS compiler is not possible.
A bit worse than that - most browser (except Chrome) used to be capable of handling large memory usage (say 64GB), but all that has changed in the last couple of years.
Firefox nowadays blows up around the 20GB mark, and for some bizarre reason Microsoft decided to "update" IE11 such that it can't only use 2GB before going OOM. (Safari won't even load WebWorker properly since at least a year ago so let's not mention that.)
I've been amazed by the speed of these JS JIT engines, but it's only possible with some compromises as you've discovered. You can only imagine the bug attack surface of these engines given their incredible complexity.
I'm also curious what JS applications you're designing that need 64GB in a browser. The language was invented to do simple form field validation, after all. :-)
Just running data analytics with distributed storage, nothing fancy 馃槈
Thought I would (ab)use web technologies as much as I could, but the recent push of feature creep and security theatre is really making me wonder if I should migrate away from this platform.
Still remember back in the days when Internet Explorer first introduced CSS crop and transparency filters − making image kernels (e.g. sharpen, motion blur) to work inside the browser was hours of fun. 馃ぃ
the recent push of feature creep and security theatre is really making me wonder if I should migrate away from this platform
That's been my thought as well. The back end alternatives all have their own issues and baggage though.
making image kernels (e.g. sharpen, motion blur) to work inside the browser was hours of fun. 馃ぃ
I didn't even know that was a thing! It's getting harder and harder to be a programming generalist these days - so much technology to learn. You're basically forced to to pick a silo and run with it.
After #3710:
$ uglifyjs test.js --toplevel -mc passes=1000000,unsafe --reduce-test
// reduce test pass 1, iteration 0: 1271 bytes
// reduce test pass 1, iteration 25: 918 bytes
// reduce test pass 1, iteration 50: 726 bytes
// reduce test pass 1, iteration 75: 373 bytes
// reduce test pass 1, iteration 100: 260 bytes
// reduce test pass 1, iteration 125: 131 bytes
// reduce test pass 1: 131 bytes
// reduce test pass 2: 126 bytes
// reduce test pass 3: 126 bytes
var a = 0, b = 0;
function f0(a_1) {
return a_1 += (a_1[0] >>>= 0).toString();
}
var c = f0([]);
console.log(null, a, b, c, Infinity, NaN, undefined);
// output: null 0 0 00 Infinity NaN undefined
// minify: null 0 0 0 Infinity NaN undefined
// options: {"compress":{"passes":1000000,"unsafe":true},"mangle":true,"toplevel":true}
Not bad at all. Just curious what was generated before #3710.
The reduced result looks to be the same when run against #3705 for the test case above.
However, I've seen a slight improvement in other test cases - generally as result of the AST_BlockStatement splice.