diff options
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/lib/compress.js b/lib/compress.js index 31747c92..bdce24bc 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -355,20 +355,18 @@ merge(Compressor.prototype, { } else { def.fixed = false; } - if (def.init instanceof AST_Defun && !all(def.references, same_defun_scope)) { + if (def.init instanceof AST_Defun && !all(def.references, function(ref) { + var scope = ref.scope; + do { + if (def.scope === scope) return true; + } while (scope instanceof AST_Function && (scope = scope.parent_scope)); + })) { tw.defun_ids[def.id] = undefined; } def.recursive_refs = 0; def.references = []; def.should_replace = undefined; def.single_use = undefined; - - function same_defun_scope(ref) { - var scope = ref.scope; - do { - if (def.scope === scope) return true; - } while (scope instanceof AST_Function && (scope = scope.parent_scope)); - } } function reset_variables(tw, compressor, scope) { @@ -384,11 +382,11 @@ merge(Compressor.prototype, { }); } - function walk_defun(tw, def) { - if (def.id in tw.defun_ids) return; + function mark_defun(tw, def) { + if (def.id in tw.defun_ids) return def.fixed; if (!tw.in_loop) { - tw.defun_ids[def.id] = true; - def.fixed.walk(tw); + tw.defun_ids[def.id] = tw.safe_ids; + return def.fixed; } else if (tw.defun_ids[def.id] !== false) { tw.defun_ids[def.id] = undefined; } @@ -397,7 +395,7 @@ merge(Compressor.prototype, { function walk_defuns(tw, scope) { scope.functions.each(function(def) { if (def.init instanceof AST_Defun && tw.defun_ids[def.id] === undefined) { - tw.defun_ids[def.id] = true; + tw.defun_ids[def.id] = tw.safe_ids; def.init.walk(tw); } }); @@ -536,11 +534,14 @@ merge(Compressor.prototype, { return true; }); def(AST_Call, function(tw, descend) { - descend(); var exp = this.expression; - if (exp instanceof AST_SymbolRef && exp.fixed_value() instanceof AST_Defun) { - walk_defun(tw, exp.definition()); - } + if (!(exp instanceof AST_SymbolRef)) return; + var def = exp.definition(); + if (!(def.fixed instanceof AST_Defun)) return; + var defun = mark_defun(tw, def); + if (!defun) return; + descend(); + defun.walk(tw); return true; }); def(AST_Case, function(tw) { @@ -570,7 +571,7 @@ merge(Compressor.prototype, { }); def(AST_Defun, function(tw, descend, compressor) { var id = this.name.definition().id; - if (!tw.defun_ids[id]) return true; + if (tw.defun_ids[id] !== tw.safe_ids) return true; tw.defun_ids[id] = false; this.inlined = false; push(tw); @@ -707,7 +708,8 @@ merge(Compressor.prototype, { var parent; if (d.fixed instanceof AST_Defun && !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) { - walk_defun(tw, d); + var defun = mark_defun(tw, d); + if (defun) defun.walk(tw); } }); def(AST_Toplevel, function(tw, descend, compressor) { @@ -1121,7 +1123,7 @@ merge(Compressor.prototype, { if (is_lhs(node, multi_replacer.parent())) return node; def.replaced++; value_def.replaced--; - return candidate.value; + return candidate.value.clone(); } // Skip (non-executed) functions and (leading) default case in switch statements if (node instanceof AST_Default || node instanceof AST_Scope) return node; |