var d = node.definition();
d.references.push(node);
if (d.fixed === undefined || !is_safe(d)
- || is_modified(node, 0, d.fixed instanceof AST_Lambda)) {
+ || is_modified(node, 0, node.fixed_value() instanceof AST_Lambda)) {
d.fixed = false;
}
}
if (node instanceof AST_VarDef) {
var d = node.name.definition();
if (d.fixed == null) {
- d.fixed = node.value;
+ d.fixed = node.value && function() {
+ return node.value;
+ };
mark_as_safe(d);
} else if (node.value) {
d.fixed = false;
// So existing transformation rules can work on them.
node.argnames.forEach(function(arg, i) {
var d = arg.definition();
- d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
+ d.fixed = function() {
+ return iife.args[i] || make_node(AST_Undefined, iife);
+ };
mark_as_safe(d);
});
}
}
});
+ AST_SymbolRef.DEFMETHOD("fixed_value", function() {
+ var fixed = this.definition().fixed;
+ if (!fixed || fixed instanceof AST_Node) return fixed;
+ return fixed();
+ });
+
function find_variable(compressor, name) {
var scope, i = 0;
while (scope = compressor.parent(i++)) {
if (this._evaluating) throw def;
this._evaluating = true;
try {
- var d = this.definition();
- if (compressor.option("reduce_vars") && d.fixed) {
+ var fixed = this.fixed_value();
+ if (compressor.option("reduce_vars") && fixed) {
if (compressor.option("unsafe")) {
- if (!HOP(d.fixed, "_evaluated")) {
- d.fixed._evaluated = ev(d.fixed, compressor);
+ if (!HOP(fixed, "_evaluated")) {
+ fixed._evaluated = ev(fixed, compressor);
}
- return d.fixed._evaluated;
+ return fixed._evaluated;
}
- return ev(d.fixed, compressor);
+ return ev(fixed, compressor);
}
} finally {
this._evaluating = false;
if (compressor.option("reduce_vars")
&& exp instanceof AST_SymbolRef) {
var def = exp.definition();
- if (def.fixed instanceof AST_Defun) {
- def.fixed = make_node(AST_Function, def.fixed, def.fixed).clone(true);
+ var fixed = exp.fixed_value();
+ if (fixed instanceof AST_Defun) {
+ def.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true);
}
- if (def.fixed instanceof AST_Function) {
- exp = def.fixed;
+ if (fixed instanceof AST_Function) {
+ exp = fixed;
if (compressor.option("unused")
&& def.references.length == 1
&& !(def.scope.uses_arguments
&& (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
self.expression = e.left;
e.left = self;
- return e.optimize(compressor);
+ return e;
}
// avoids infinite recursion of numerals
if (self.operator != "-"
}
if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
var d = self.definition();
- if (d.fixed) {
+ var fixed = self.fixed_value();
+ if (fixed) {
if (d.should_replace === undefined) {
- var init = d.fixed.evaluate(compressor);
- if (init !== d.fixed) {
- init = make_node_from_constant(init, d.fixed).optimize(compressor);
- init = best_of_expression(init, d.fixed);
+ var init = fixed.evaluate(compressor);
+ if (init !== fixed) {
+ init = make_node_from_constant(init, fixed).optimize(compressor);
+ init = best_of_expression(init, fixed);
var value = init.print_to_string().length;
var name = d.name.length;
var freq = d.references.length;