@@ -1675,6 +1675,7 @@ Compressor.prototype.compress = function(node) {
16751675 if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
16761676 }
16771677 }
1678+ return false;
16781679 }
16791680
16801681 var identifier_atom = makePredicate("Infinity NaN undefined");
@@ -1917,7 +1918,7 @@ Compressor.prototype.compress = function(node) {
19171918 var in_lambda = last_of(compressor, function(node) {
19181919 return node instanceof AST_Lambda;
19191920 });
1920- var block_scope, in_loop, in_try, scope;
1921+ var block_scope, iife_in_try, in_iife_single, in_loop, in_try, scope;
19211922 find_loop_scope_try();
19221923 var changed, last_changed, max_iter = 10;
19231924 do {
@@ -2490,10 +2491,10 @@ Compressor.prototype.compress = function(node) {
24902491 var after = stop_after;
24912492 var if_hit = stop_if_hit;
24922493 for (var i = 0; !abort && i < fn.argnames.length; i++) {
2493- if (may_throw_arg (reject, fn.argnames[i], node.args[i])) abort = true;
2494+ if (arg_may_throw (reject, fn.argnames[i], node.args[i])) abort = true;
24942495 }
24952496 if (!abort) {
2496- if (fn.rest && may_throw_arg (reject, fn.rest, make_node(AST_Array, node, {
2497+ if (fn.rest && arg_may_throw (reject, fn.rest, make_node(AST_Array, node, {
24972498 elements: node.args.slice(i),
24982499 }))) {
24992500 abort = true;
@@ -2579,128 +2580,134 @@ Compressor.prototype.compress = function(node) {
25792580 }
25802581 }
25812582
2582- function may_throw_arg (reject, node, value) {
2583+ function arg_may_throw (reject, node, value) {
25832584 if (node instanceof AST_DefaultValue) {
25842585 return reject(node.value)
2585- || may_throw_arg (reject, node.name, node.value)
2586- || !is_undefined(value) && may_throw_arg (reject, node.name, value);
2586+ || arg_may_throw (reject, node.name, node.value)
2587+ || !is_undefined(value) && arg_may_throw (reject, node.name, value);
25872588 }
25882589 if (!value) return !(node instanceof AST_Symbol);
25892590 if (node instanceof AST_Destructured) {
2590- if (node.rest && may_throw_arg (reject, node.rest)) return true;
2591+ if (node.rest && arg_may_throw (reject, node.rest)) return true;
25912592 if (node instanceof AST_DestructuredArray) {
25922593 if (value instanceof AST_Array) return !all(node.elements, function(element, index) {
2593- return !may_throw_arg (reject, element, value[index]);
2594+ return !arg_may_throw (reject, element, value[index]);
25942595 });
25952596 return value.is_string(compressor) && !all(node.elements, function(element) {
2596- return !may_throw_arg (reject, element);
2597+ return !arg_may_throw (reject, element);
25972598 });
25982599 }
25992600 if (node instanceof AST_DestructuredObject) {
26002601 if (value.may_throw_on_access(compressor)) return true;
26012602 return !all(node.properties, function(prop) {
26022603 if (prop.key instanceof AST_Node && reject(prop.key)) return false;
2603- return !may_throw_arg (reject, prop.value);
2604+ return !arg_may_throw (reject, prop.value);
26042605 });
26052606 }
26062607 }
26072608 }
26082609
26092610 function extract_args() {
2610- var iife, fn = compressor.self();
2611- if (fn instanceof AST_LambdaExpression
2612- && !is_generator(fn)
2613- && !fn.uses_arguments
2614- && !fn.pinned()
2615- && (iife = compressor.parent()) instanceof AST_Call
2616- && iife.expression === fn
2617- && is_iife_single(iife)
2618- && all(iife.args, function(arg) {
2619- return !(arg instanceof AST_Spread);
2620- })) {
2621- var fn_strict = fn.in_strict_mode(compressor)
2622- && !fn.parent_scope.resolve(true).in_strict_mode(compressor);
2623- var check_arg = false, has_await;
2624- if (is_async(fn)) {
2625- check_arg = true;
2626- has_await = function(node) {
2627- return node instanceof AST_Symbol && node.name == "await";
2628- };
2629- } else {
2630- check_arg = find_try(compressor, 1, iife, null, true, true);
2631- has_await = function(node) {
2632- return node instanceof AST_Await && !tw.find_parent(AST_Scope);
2633- };
2611+ if (in_iife_single === false) return;
2612+ var iife = compressor.parent(), fn = compressor.self();
2613+ if (in_iife_single === undefined) {
2614+ if (!(fn instanceof AST_LambdaExpression)
2615+ || is_generator(fn)
2616+ || fn.uses_arguments
2617+ || fn.pinned()
2618+ || !(iife instanceof AST_Call)
2619+ || iife.expression !== fn
2620+ || !all(iife.args, function(arg) {
2621+ return !(arg instanceof AST_Spread);
2622+ })) {
2623+ in_iife_single = false;
2624+ return;
26342625 }
2635- var arg_scope = null;
2636- var tw = new TreeWalker(function(node, descend) {
2637- if (!arg) return true;
2638- if (has_await(node) || node instanceof AST_Yield) {
2639- arg = null;
2640- return true;
2641- }
2642- if (node instanceof AST_ObjectIdentity && (fn_strict || !arg_scope)) {
2643- arg = null;
2644- return true;
2645- }
2646- if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
2647- var s = node.definition().scope;
2648- if (s !== scope) while (s = s.parent_scope) {
2649- if (s === scope) return true;
2650- }
2651- arg = null;
2652- }
2653- if (node instanceof AST_Scope && !is_arrow(node)) {
2654- var save_scope = arg_scope;
2655- arg_scope = node;
2656- descend();
2657- arg_scope = save_scope;
2658- return true;
2659- }
2660- });
2661- args = iife.args.slice();
2662- var len = args.length;
2663- var names = new Dictionary();
2664- for (var i = fn.argnames.length; --i >= 0;) {
2665- var sym = fn.argnames[i];
2666- var arg = args[i];
2667- var value = null;
2668- if (sym instanceof AST_DefaultValue) {
2669- value = sym.value;
2670- sym = sym.name;
2671- args[len + i] = value;
2672- }
2673- if (sym instanceof AST_Destructured) {
2674- if (check_arg && may_throw_arg(function(node) {
2675- return node.has_side_effects(compressor);
2676- }, sym, arg)) {
2677- candidates.length = 0;
2678- break;
2679- }
2680- args[len + i] = fn.argnames[i];
2681- continue;
2626+ if (!is_iife_single(iife)) return;
2627+ in_iife_single = true;
2628+ }
2629+ var fn_strict = fn.in_strict_mode(compressor)
2630+ && !fn.parent_scope.resolve(true).in_strict_mode(compressor);
2631+ var has_await;
2632+ if (is_async(fn)) {
2633+ has_await = function(node) {
2634+ return node instanceof AST_Symbol && node.name == "await";
2635+ };
2636+ iife_in_try = true;
2637+ } else {
2638+ has_await = function(node) {
2639+ return node instanceof AST_Await && !tw.find_parent(AST_Scope);
2640+ };
2641+ if (iife_in_try === undefined) iife_in_try = find_try(compressor, 1, iife, null, true, true);
2642+ }
2643+ var arg_scope = null;
2644+ var tw = new TreeWalker(function(node, descend) {
2645+ if (!arg) return true;
2646+ if (has_await(node) || node instanceof AST_Yield) {
2647+ arg = null;
2648+ return true;
2649+ }
2650+ if (node instanceof AST_ObjectIdentity && (fn_strict || !arg_scope)) {
2651+ arg = null;
2652+ return true;
2653+ }
2654+ if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
2655+ var s = node.definition().scope;
2656+ if (s !== scope) while (s = s.parent_scope) {
2657+ if (s === scope) return true;
26822658 }
2683- if (names.has(sym.name)) continue;
2684- names.set(sym.name, true);
2685- if (value) arg = is_undefined(arg) ? value : null;
2686- if (!arg && !value) {
2687- arg = make_node(AST_Undefined, sym).transform(compressor);
2688- } else if (arg instanceof AST_Lambda && arg.pinned()) {
2689- arg = null;
2690- } else if (arg) {
2691- arg.walk(tw);
2659+ arg = null;
2660+ }
2661+ if (node instanceof AST_Scope && !is_arrow(node)) {
2662+ var save_scope = arg_scope;
2663+ arg_scope = node;
2664+ descend();
2665+ arg_scope = save_scope;
2666+ return true;
2667+ }
2668+ });
2669+ args = iife.args.slice();
2670+ var len = args.length;
2671+ var names = new Dictionary();
2672+ for (var i = fn.argnames.length; --i >= 0;) {
2673+ var sym = fn.argnames[i];
2674+ var arg = args[i];
2675+ var value = null;
2676+ if (sym instanceof AST_DefaultValue) {
2677+ value = sym.value;
2678+ sym = sym.name;
2679+ args[len + i] = value;
2680+ }
2681+ if (sym instanceof AST_Destructured) {
2682+ if (iife_in_try && arg_may_throw(function(node) {
2683+ return node.has_side_effects(compressor);
2684+ }, sym, arg)) {
2685+ candidates.length = 0;
2686+ break;
26922687 }
2693- if (!arg) continue;
2694- var candidate = make_node(AST_VarDef, sym, {
2695- name: sym,
2696- value: arg,
2697- });
2698- candidate.name_index = i;
2699- candidate.arg_index = value ? len + i : i;
2700- candidates.unshift([ candidate ]);
2688+ args[len + i] = fn.argnames[i];
2689+ continue;
27012690 }
2702- if (fn.rest) args.push(fn.rest);
2691+ if (names.has(sym.name)) continue;
2692+ names.set(sym.name, true);
2693+ if (value) arg = is_undefined(arg) ? value : null;
2694+ if (!arg && !value) {
2695+ arg = make_node(AST_Undefined, sym).transform(compressor);
2696+ } else if (arg instanceof AST_Lambda && arg.pinned()) {
2697+ arg = null;
2698+ } else if (arg) {
2699+ arg.walk(tw);
2700+ }
2701+ if (!arg) continue;
2702+ var candidate = make_node(AST_VarDef, sym, {
2703+ name: sym,
2704+ value: arg,
2705+ });
2706+ candidate.name_index = i;
2707+ candidate.arg_index = value ? len + i : i;
2708+ candidates.unshift([ candidate ]);
27032709 }
2710+ if (fn.rest) args.push(fn.rest);
27042711 }
27052712
27062713 function extract_candidates(expr, unused) {
0 commit comments