From 593677d2ff04f61a2230c18722ec89b820ee0307 Mon Sep 17 00:00:00 2001 From: kzc Date: Mon, 5 Oct 2015 19:51:09 -0400 Subject: [PATCH] Add proper support for "use asm"; blocks. Disable -c optimization within "use asm"; sections and preserve floating point literals in their original form. Non-asm.js sections are optimized as before. Asm.js sections can still be mangled and minified of whitespace. No special command line flags are required. --- bin/uglifyjs | 2 +- lib/compress.js | 26 ++++++++++++++------------ lib/output.js | 6 +++++- lib/parse.js | 3 +++ lib/scope.js | 4 ++++ 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/bin/uglifyjs b/bin/uglifyjs index fbb053d8..00342b8f 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -401,7 +401,7 @@ async.eachLimit(files, 1, function (file, cb) { writeNameCache("props", cache); })(); - var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint; + var SCOPE_IS_NEEDED = COMPRESS || MANGLE || BEAUTIFY || ARGS.lint; var TL_CACHE = readNameCache("vars"); if (SCOPE_IS_NEEDED) { diff --git a/lib/compress.js b/lib/compress.js index 8360473f..216aade9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -111,6 +111,7 @@ merge(Compressor.prototype, { node.DEFMETHOD("optimize", function(compressor){ var self = this; if (self._optimized) return self; + if (compressor.has_directive("use asm")) return self; var opt = optimizer(self, compressor); opt._optimized = true; if (opt === self) return opt; @@ -1026,6 +1027,7 @@ merge(Compressor.prototype, { AST_Scope.DEFMETHOD("drop_unused", function(compressor){ var self = this; + if (compressor.has_directive("use asm")) return self; if (compressor.option("unused") && !(self instanceof AST_Toplevel) && !self.uses_eval @@ -1205,9 +1207,10 @@ merge(Compressor.prototype, { }); AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){ + var self = this; + if (compressor.has_directive("use asm")) return self; var hoist_funs = compressor.option("hoist_funs"); var hoist_vars = compressor.option("hoist_vars"); - var self = this; if (hoist_funs || hoist_vars) { var dirs = []; var hoisted = []; @@ -2028,15 +2031,14 @@ merge(Compressor.prototype, { var commutativeOperators = makePredicate("== === != !== * & | ^"); OPT(AST_Binary, function(self, compressor){ - var reverse = compressor.has_directive("use asm") ? noop - : function(op, force) { - if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) { - if (op) self.operator = op; - var tmp = self.left; - self.left = self.right; - self.right = tmp; - } - }; + function reverse(op, force) { + if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) { + if (op) self.operator = op; + var tmp = self.left; + self.left = self.right; + self.right = tmp; + } + } if (commutativeOperators(self.operator)) { if (self.right instanceof AST_Constant && !(self.left instanceof AST_Constant)) { @@ -2104,10 +2106,10 @@ merge(Compressor.prototype, { if (compressor.option("conditionals")) { if (self.operator == "&&") { var ll = self.left.evaluate(compressor); - var rr = self.right.evaluate(compressor); if (ll.length > 1) { if (ll[1]) { compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); + var rr = self.right.evaluate(compressor); return rr[0]; } else { compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); @@ -2117,13 +2119,13 @@ merge(Compressor.prototype, { } else if (self.operator == "||") { var ll = self.left.evaluate(compressor); - var rr = self.right.evaluate(compressor); if (ll.length > 1) { if (ll[1]) { compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); return ll[0]; } else { compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); + var rr = self.right.evaluate(compressor); return rr[0]; } } diff --git a/lib/output.js b/lib/output.js index 3b4c1469..06c1e429 100644 --- a/lib/output.js +++ b/lib/output.js @@ -1158,7 +1158,11 @@ function OutputStream(options) { output.print_string(self.getValue(), self.quote); }); DEFPRINT(AST_Number, function(self, output){ - output.print(make_num(self.getValue())); + if (self.value_string !== undefined && self.scope && self.scope.has_directive('use asm')) { + output.print(self.value_string); + } else { + output.print(make_num(self.getValue())); + } }); function regexp_safe_literal(code) { diff --git a/lib/parse.js b/lib/parse.js index cbfb5757..830b5227 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1149,6 +1149,9 @@ function parse($TEXT, options) { break; case "num": ret = new AST_Number({ start: tok, end: tok, value: tok.value }); + var value_string = $TEXT.substring(tok.pos, tok.endpos); + if (value_string.indexOf('.') >= 0) + ret.value_string = value_string; break; case "string": ret = new AST_String({ diff --git a/lib/scope.js b/lib/scope.js index 6c19c19a..06bd65ae 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -119,6 +119,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ push_uniq(scope.directives, node.value); return true; } + if (node instanceof AST_Number) { + node.scope = scope; + return true; + } if (node instanceof AST_With) { for (var s = scope; s; s = s.parent_scope) s.uses_with = true; -- 2.34.1