[Pkg-javascript-commits] [uglifyjs] 174/491: refactor `throw` usage within `compress` (#2193)
Jonas Smedegaard
dr at jones.dk
Wed Feb 14 19:51:32 UTC 2018
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.
commit 20e4f8277fc69b275600770c5d41fa1b75b9984f
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Mon Jul 3 02:10:56 2017 +0800
refactor `throw` usage within `compress` (#2193)
Eliminate exceptional constructs from normal control flow.
---
lib/compress.js | 205 ++++++++++++++++++++++++++++++--------------------------
1 file changed, 111 insertions(+), 94 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index eb3ba75..db45c56 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1198,21 +1198,21 @@ merge(Compressor.prototype, {
for (var i = 0, len = statements.length; i < len; i++) {
var stat = statements[i];
if (prev) {
- if (stat instanceof AST_For) {
- try {
- prev.body.walk(new TreeWalker(function(node){
- if (node instanceof AST_Binary && node.operator == "in")
- throw cons_seq;
- }));
- if (stat.init && !(stat.init instanceof AST_Definitions)) {
- stat.init = cons_seq(stat.init);
+ if (stat instanceof AST_For && !(stat.init instanceof AST_Definitions)) {
+ var abort = false;
+ prev.body.walk(new TreeWalker(function(node) {
+ if (abort) return true;
+ if (node instanceof AST_Binary && node.operator == "in") {
+ abort = true;
+ return true;
}
- else if (!stat.init) {
+ }));
+ if (!abort) {
+ if (stat.init) stat.init = cons_seq(stat.init);
+ else {
stat.init = prev.body.drop_side_effect_free(compressor);
n--;
}
- } catch(ex) {
- if (ex !== cons_seq) throw ex;
}
}
else if (stat instanceof AST_If) {
@@ -1532,13 +1532,8 @@ merge(Compressor.prototype, {
// descendant of AST_Node.
AST_Node.DEFMETHOD("evaluate", function(compressor){
if (!compressor.option("evaluate")) return this;
- try {
- var val = this._eval(compressor);
- return !val || val instanceof RegExp || typeof val != "object" ? val : this;
- } catch(ex) {
- if (ex !== def) throw ex;
- return this;
- }
+ var val = this._eval(compressor);
+ return !val || val instanceof RegExp || typeof val != "object" ? val : this;
});
var unaryPrefix = makePredicate("! ~ - + void");
AST_Node.DEFMETHOD("is_constant", function(){
@@ -1584,27 +1579,28 @@ merge(Compressor.prototype, {
def(AST_Statement, function(){
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
});
- def(AST_Lambda, function(){
- throw def;
- });
+ def(AST_Lambda, return_this);
function ev(node, compressor) {
if (!compressor) throw new Error("Compressor must be passed");
return node._eval(compressor);
};
- def(AST_Node, function(){
- throw def; // not constant
- });
+ def(AST_Node, return_this);
def(AST_Constant, function(){
return this.getValue();
});
def(AST_Array, function(compressor){
if (compressor.option("unsafe")) {
- return this.elements.map(function(element) {
- return ev(element, compressor);
- });
+ var elements = [];
+ for (var i = 0, len = this.elements.length; i < len; i++) {
+ var element = this.elements[i];
+ var value = ev(element, compressor);
+ if (element === value) return this;
+ elements.push(value);
+ }
+ return elements;
}
- throw def;
+ return this;
});
def(AST_Object, function(compressor){
if (compressor.option("unsafe")) {
@@ -1616,105 +1612,121 @@ merge(Compressor.prototype, {
key = key.name;
} else if (key instanceof AST_Node) {
key = ev(key, compressor);
+ if (key === prop.key) return this;
}
if (typeof Object.prototype[key] === 'function') {
- throw def;
+ return this;
}
val[key] = ev(prop.value, compressor);
+ if (val[key] === prop.value) return this;
}
return val;
}
- throw def;
+ return this;
});
def(AST_UnaryPrefix, function(compressor){
- var e = this.expression;
+ // Function would be evaluated to an array and so typeof would
+ // incorrectly return 'object'. Hence making is a special case.
+ if (this.operator == "typeof" && this.expression instanceof AST_Function) {
+ return typeof function(){};
+ }
+ var e = ev(this.expression, compressor);
+ if (e === this.expression) return this;
switch (this.operator) {
- case "!": return !ev(e, compressor);
+ case "!": return !e;
case "typeof":
- // Function would be evaluated to an array and so typeof would
- // incorrectly return 'object'. Hence making is a special case.
- if (e instanceof AST_Function) return typeof function(){};
-
- e = ev(e, compressor);
-
// typeof <RegExp> returns "object" or "function" on different platforms
// so cannot evaluate reliably
- if (e instanceof RegExp) throw def;
-
+ if (e instanceof RegExp) return this;
return typeof e;
- case "void": return void ev(e, compressor);
- case "~": return ~ev(e, compressor);
- case "-": return -ev(e, compressor);
- case "+": return +ev(e, compressor);
+ case "void": return void e;
+ case "~": return ~e;
+ case "-": return -e;
+ case "+": return +e;
}
- throw def;
+ return this;
});
- def(AST_Binary, function(c){
- var left = this.left, right = this.right, result;
+ def(AST_Binary, function(compressor){
+ var left = ev(this.left, compressor);
+ if (left === this.left) return this;
+ var right = ev(this.right, compressor);
+ if (right === this.right) return this;
+ var result;
switch (this.operator) {
- case "&&" : result = ev(left, c) && ev(right, c); break;
- case "||" : result = ev(left, c) || ev(right, c); break;
- case "|" : result = ev(left, c) | ev(right, c); break;
- case "&" : result = ev(left, c) & ev(right, c); break;
- case "^" : result = ev(left, c) ^ ev(right, c); break;
- case "+" : result = ev(left, c) + ev(right, c); break;
- case "*" : result = ev(left, c) * ev(right, c); break;
- case "/" : result = ev(left, c) / ev(right, c); break;
- case "%" : result = ev(left, c) % ev(right, c); break;
- case "-" : result = ev(left, c) - ev(right, c); break;
- case "<<" : result = ev(left, c) << ev(right, c); break;
- case ">>" : result = ev(left, c) >> ev(right, c); break;
- case ">>>" : result = ev(left, c) >>> ev(right, c); break;
- case "==" : result = ev(left, c) == ev(right, c); break;
- case "===" : result = ev(left, c) === ev(right, c); break;
- case "!=" : result = ev(left, c) != ev(right, c); break;
- case "!==" : result = ev(left, c) !== ev(right, c); break;
- case "<" : result = ev(left, c) < ev(right, c); break;
- case "<=" : result = ev(left, c) <= ev(right, c); break;
- case ">" : result = ev(left, c) > ev(right, c); break;
- case ">=" : result = ev(left, c) >= ev(right, c); break;
+ case "&&" : result = left && right; break;
+ case "||" : result = left || right; break;
+ case "|" : result = left | right; break;
+ case "&" : result = left & right; break;
+ case "^" : result = left ^ right; break;
+ case "+" : result = left + right; break;
+ case "*" : result = left * right; break;
+ case "/" : result = left / right; break;
+ case "%" : result = left % right; break;
+ case "-" : result = left - right; break;
+ case "<<" : result = left << right; break;
+ case ">>" : result = left >> right; break;
+ case ">>>" : result = left >>> right; break;
+ case "==" : result = left == right; break;
+ case "===" : result = left === right; break;
+ case "!=" : result = left != right; break;
+ case "!==" : result = left !== right; break;
+ case "<" : result = left < right; break;
+ case "<=" : result = left <= right; break;
+ case ">" : result = left > right; break;
+ case ">=" : result = left >= right; break;
default:
- throw def;
+ return this;
}
- if (isNaN(result) && c.find_parent(AST_With)) {
+ if (isNaN(result) && compressor.find_parent(AST_With)) {
// leave original expression as is
- throw def;
+ return this;
}
return result;
});
def(AST_Conditional, function(compressor){
- return ev(this.condition, compressor)
- ? ev(this.consequent, compressor)
- : ev(this.alternative, compressor);
+ var condition = ev(this.condition, compressor);
+ if (condition === this.condition) return this;
+ var node = condition ? this.consequent : this.alternative;
+ var value = ev(node, compressor);
+ return value === node ? this : value;
});
def(AST_SymbolRef, function(compressor){
- if (!compressor.option("reduce_vars") || this._evaluating) throw def;
- this._evaluating = true;
- try {
- var fixed = this.fixed_value();
- if (!fixed) throw def;
- var value = ev(fixed, compressor);
- if (!HOP(fixed, "_eval")) fixed._eval = function() {
- return value;
- };
- if (value && typeof value == "object" && this.definition().escaped) throw def;
+ if (!compressor.option("reduce_vars")) return this;
+ this._eval = return_this;
+ var fixed = this.fixed_value();
+ if (!fixed) {
+ delete this._eval;
+ return this;
+ }
+ var value = ev(fixed, compressor);
+ if (value === fixed) {
+ delete this._eval;
+ return this;
+ }
+ if (!HOP(fixed, "_eval")) fixed._eval = function() {
return value;
- } finally {
- this._evaluating = false;
+ };
+ if (value && typeof value == "object" && this.definition().escaped) {
+ delete this._eval;
+ return this;
}
+ this._eval = fixed._eval;
+ return value;
});
def(AST_PropAccess, function(compressor){
if (compressor.option("unsafe")) {
var key = this.property;
if (key instanceof AST_Node) {
key = ev(key, compressor);
+ if (key === this.property) return this;
}
var val = ev(this.expression, compressor);
+ if (val === this.expression) return this;
if (val && HOP(val, key)) {
return val[key];
}
}
- throw def;
+ return this;
});
var object_fns = [
'constructor',
@@ -1760,19 +1772,24 @@ merge(Compressor.prototype, {
var key = exp.property;
if (key instanceof AST_Node) {
key = ev(key, compressor);
+ if (key === exp.property) return this;
}
var val = ev(exp.expression, compressor);
+ if (val === exp.expression) return this;
if ((val && native_fns[val.constructor.name] || return_false)(key)) {
- return val[key].apply(val, this.args.map(function(arg) {
- return ev(arg, compressor);
- }));
+ var args = [];
+ for (var i = 0, len = this.args.length; i < len; i++) {
+ var arg = this.args[i];
+ var value = ev(arg, compressor);
+ if (arg === value) return this;
+ args.push(value);
+ }
+ return val[key].apply(val, args);
}
}
- throw def;
- });
- def(AST_New, function(compressor){
- throw def;
+ return this;
});
+ def(AST_New, return_this);
})(function(node, func){
node.DEFMETHOD("_eval", func);
});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list