@@ -352,23 +352,6 @@ merge(Compressor.prototype, {
|
||||
return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
|
||||
}
|
||||
|
||||
function is_content_constant(ref, depth) {
|
||||
var escaped = ref.definition().escaped;
|
||||
switch (escaped.length) {
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
var found = false;
|
||||
escaped[0].walk(new TreeWalker(function(node) {
|
||||
if (found) return true;
|
||||
if (node === ref) return found = true;
|
||||
}));
|
||||
return found;
|
||||
default:
|
||||
return depth <= escaped.depth;
|
||||
}
|
||||
}
|
||||
|
||||
(function(def) {
|
||||
def(AST_Node, noop);
|
||||
|
||||
@@ -512,16 +495,10 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
}
|
||||
|
||||
function to_value(def, sym, fixed) {
|
||||
if (fixed == null) {
|
||||
fixed = make_node(AST_Undefined, sym);
|
||||
} else if (typeof fixed == "function") {
|
||||
fixed = fixed();
|
||||
}
|
||||
if (fixed instanceof AST_Array || fixed instanceof AST_Object) {
|
||||
if (!is_content_constant(sym)) return false;
|
||||
}
|
||||
return fixed;
|
||||
function make_ref(ref, fixed) {
|
||||
var node = make_node(AST_SymbolRef, ref, ref);
|
||||
node.fixed = fixed || make_node(AST_Undefined, ref);
|
||||
return node;
|
||||
}
|
||||
|
||||
function ref_once(compressor, def) {
|
||||
@@ -618,10 +595,9 @@ merge(Compressor.prototype, {
|
||||
};
|
||||
} else {
|
||||
sym.fixed = d.fixed = function() {
|
||||
var value = to_value(d, sym, fixed);
|
||||
return value && make_node(AST_Binary, node, {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
left: value,
|
||||
left: make_ref(sym, fixed),
|
||||
right: node.right
|
||||
});
|
||||
};
|
||||
@@ -900,12 +876,11 @@ merge(Compressor.prototype, {
|
||||
push_ref(d, exp);
|
||||
mark(tw, d);
|
||||
d.fixed = function() {
|
||||
var value = to_value(d, exp, fixed);
|
||||
return value && make_node(AST_Binary, node, {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
left: make_node(AST_UnaryPrefix, node, {
|
||||
operator: "+",
|
||||
expression: value
|
||||
expression: make_ref(exp, fixed)
|
||||
}),
|
||||
right: make_node(AST_Number, node, {
|
||||
value: 1
|
||||
@@ -918,10 +893,9 @@ merge(Compressor.prototype, {
|
||||
exp.fixed = d.fixed;
|
||||
} else {
|
||||
exp.fixed = function() {
|
||||
var value = to_value(d, exp, fixed);
|
||||
return value && make_node(AST_UnaryPrefix, node, {
|
||||
return make_node(AST_UnaryPrefix, node, {
|
||||
operator: "+",
|
||||
expression: value
|
||||
expression: make_ref(exp, fixed)
|
||||
});
|
||||
};
|
||||
exp.fixed.assigns = fixed && fixed.assigns;
|
||||
@@ -3416,7 +3390,8 @@ merge(Compressor.prototype, {
|
||||
&& e.fixed_value() instanceof AST_Lambda)) {
|
||||
return typeof function(){};
|
||||
}
|
||||
if (!non_converting_unary[op]) depth++;
|
||||
var def = e instanceof AST_SymbolRef && e.definition();
|
||||
if (!non_converting_unary[op] && !(def && def.fixed)) depth++;
|
||||
var v = e._eval(compressor, ignore_side_effects, cached, depth);
|
||||
if (v === e) {
|
||||
if (ignore_side_effects && op == "void") return;
|
||||
@@ -3435,9 +3410,8 @@ merge(Compressor.prototype, {
|
||||
case "+": return +v;
|
||||
case "++":
|
||||
case "--":
|
||||
if (!(e instanceof AST_SymbolRef)) return this;
|
||||
if (!def) return this;
|
||||
if (!ignore_side_effects) {
|
||||
var def = e.definition();
|
||||
if (def.undeclared) return this;
|
||||
if (def.last_ref !== e) return this;
|
||||
}
|
||||
@@ -3460,7 +3434,8 @@ merge(Compressor.prototype, {
|
||||
if (def.last_ref !== e) return this;
|
||||
}
|
||||
}
|
||||
var v = e._eval(compressor, ignore_side_effects, cached, depth + 1);
|
||||
if (!(e instanceof AST_SymbolRef && e.definition().fixed)) depth++;
|
||||
var v = e._eval(compressor, ignore_side_effects, cached, depth);
|
||||
if (v === e) return this;
|
||||
modified(e);
|
||||
return +v;
|
||||
@@ -3522,6 +3497,22 @@ merge(Compressor.prototype, {
|
||||
var value = node._eval(compressor, ignore_side_effects, cached, depth);
|
||||
return value === node ? this : value;
|
||||
});
|
||||
function verify_escaped(ref, depth) {
|
||||
var escaped = ref.definition().escaped;
|
||||
switch (escaped.length) {
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
var found = false;
|
||||
escaped[0].walk(new TreeWalker(function(node) {
|
||||
if (found) return true;
|
||||
if (node === ref) return found = true;
|
||||
}));
|
||||
return found;
|
||||
default:
|
||||
return depth <= escaped.depth;
|
||||
}
|
||||
}
|
||||
def(AST_SymbolRef, function(compressor, ignore_side_effects, cached, depth) {
|
||||
var fixed = this.fixed_value();
|
||||
if (!fixed) return this;
|
||||
@@ -3538,8 +3529,7 @@ merge(Compressor.prototype, {
|
||||
};
|
||||
cached.push(fixed);
|
||||
}
|
||||
if (value && typeof value == "object" && !is_content_constant(this, depth)) return this;
|
||||
return value;
|
||||
return value && typeof value == "object" && !verify_escaped(this, depth) ? this : value;
|
||||
});
|
||||
var global_objs = {
|
||||
Array: Array,
|
||||
|
||||
Reference in New Issue
Block a user