@@ -1053,9 +1053,6 @@ Compressor.prototype.compress = function(node) {
1053
1053
if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) {
1054
1054
walk();
1055
1055
d.fixed = false;
1056
- } else if (modified) {
1057
- walk();
1058
- d.fixed = 0;
1059
1056
} else {
1060
1057
push_ref(d, sym);
1061
1058
mark(tw, d);
@@ -1064,7 +1061,8 @@ Compressor.prototype.compress = function(node) {
1064
1061
d.single_use = false;
1065
1062
}
1066
1063
tw.loop_ids[d.id] = tw.in_loop;
1067
- sym.fixed = d.fixed = fixed;
1064
+ d.fixed = modified ? 0 : fixed;
1065
+ sym.fixed = fixed;
1068
1066
sym.fixed.assigns = [ node ];
1069
1067
mark_escaped(tw, d, sym.scope, node, right, 0, 1);
1070
1068
}
@@ -1355,8 +1353,10 @@ Compressor.prototype.compress = function(node) {
1355
1353
this.definition().fixed = false;
1356
1354
});
1357
1355
def(AST_SymbolRef, function(tw, descend, compressor) {
1358
- var d = this.definition();
1359
- push_ref(d, this);
1356
+ var ref = this;
1357
+ var d = ref.definition();
1358
+ var fixed = d.fixed || d.last_ref && d.last_ref.fixed;
1359
+ push_ref(d, ref);
1360
1360
if (d.references.length == 1 && !d.fixed && d.orig[0] instanceof AST_SymbolDefun) {
1361
1361
tw.loop_ids[d.id] = tw.in_loop;
1362
1362
}
@@ -1371,14 +1371,27 @@ Compressor.prototype.compress = function(node) {
1371
1371
if (!safe) return;
1372
1372
safe.assign = true;
1373
1373
});
1374
- if (d.fixed === false || d.fixed === 0) {
1374
+ if (d.single_use == "m" && d.fixed) {
1375
+ d.fixed = 0;
1376
+ d.single_use = false;
1377
+ }
1378
+ switch (d.fixed) {
1379
+ case 0:
1380
+ if (!safe_to_read(tw, d)) d.fixed = false;
1381
+ case false:
1375
1382
var redef = d.redefined();
1376
- if (redef && cross_scope(d.scope, this.scope)) redef.single_use = false;
1377
- } else if (d.fixed === undefined || !safe_to_read(tw, d)) {
1383
+ if (redef && cross_scope(d.scope, ref.scope)) redef.single_use = false;
1384
+ break;
1385
+ case undefined:
1378
1386
d.fixed = false;
1379
- } else if (d.fixed) {
1380
- if (this.in_arg && d.orig[0] instanceof AST_SymbolLambda) this.fixed = d.scope;
1381
- var value = this.fixed_value();
1387
+ break;
1388
+ default:
1389
+ if (!safe_to_read(tw, d)) {
1390
+ d.fixed = false;
1391
+ break;
1392
+ }
1393
+ if (ref.in_arg && d.orig[0] instanceof AST_SymbolLambda) ref.fixed = d.scope;
1394
+ var value = ref.fixed_value();
1382
1395
if (recursive) {
1383
1396
d.recursive_refs++;
1384
1397
} else if (value && ref_once(compressor, d)) {
@@ -1387,25 +1400,26 @@ Compressor.prototype.compress = function(node) {
1387
1400
&& !value.pinned()
1388
1401
&& (!d.in_loop || tw.parent() instanceof AST_Call)
1389
1402
|| !d.in_loop
1390
- && d.scope === this .scope.resolve()
1403
+ && d.scope === ref .scope.resolve()
1391
1404
&& value.is_constant_expression();
1392
1405
} else {
1393
1406
d.single_use = false;
1394
1407
}
1395
- if (is_modified(compressor, tw, this , value, 0, is_immutable(value), recursive)) {
1408
+ if (is_modified(compressor, tw, ref , value, 0, is_immutable(value), recursive)) {
1396
1409
if (d.single_use) {
1397
1410
d.single_use = "m";
1398
1411
} else {
1399
1412
d.fixed = 0;
1400
1413
}
1401
1414
}
1402
1415
if (d.fixed && tw.loop_ids[d.id] !== tw.in_loop) d.cross_loop = true;
1403
- mark_escaped(tw, d, this.scope, this, value, 0, 1);
1416
+ mark_escaped(tw, d, ref.scope, ref, value, 0, 1);
1417
+ break;
1404
1418
}
1405
- if (!this .fixed) this .fixed = d.fixed;
1419
+ if (!ref .fixed) ref .fixed = d.fixed === 0 ? fixed : d.fixed;
1406
1420
var parent;
1407
1421
if (value instanceof AST_Lambda
1408
- && !((parent = tw.parent()) instanceof AST_Call && parent.expression === this )) {
1422
+ && !((parent = tw.parent()) instanceof AST_Call && parent.expression === ref )) {
1409
1423
mark_fn_def(tw, d, value);
1410
1424
}
1411
1425
});
@@ -1578,16 +1592,18 @@ Compressor.prototype.compress = function(node) {
1578
1592
this.walk(tw);
1579
1593
});
1580
1594
1581
- AST_Symbol.DEFMETHOD("fixed_value", function() {
1582
- var fixed = this.definition().fixed;
1595
+ AST_Symbol.DEFMETHOD("fixed_value", function(ref_only) {
1596
+ var def = this.definition();
1597
+ var fixed = def.fixed;
1583
1598
if (fixed) {
1584
1599
if (this.fixed) fixed = this.fixed;
1585
1600
return (fixed instanceof AST_Node ? fixed : fixed()).tail_node();
1586
1601
}
1587
1602
fixed = fixed === 0 && this.fixed;
1588
1603
if (!fixed) return fixed;
1589
1604
var value = (fixed instanceof AST_Node ? fixed : fixed()).tail_node();
1590
- return value.is_constant() && value;
1605
+ if (ref_only && def.escaped.depth != 1 && is_object(value, true)) return value;
1606
+ if (value.is_constant()) return value;
1591
1607
});
1592
1608
1593
1609
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
@@ -4510,7 +4526,7 @@ Compressor.prototype.compress = function(node) {
4510
4526
if (is_arguments(def) && !def.scope.rest && all(def.scope.argnames, function(argname) {
4511
4527
return argname instanceof AST_SymbolFunarg;
4512
4528
})) return def.scope.uses_arguments > 2;
4513
- var fixed = this.fixed_value();
4529
+ var fixed = this.fixed_value(true );
4514
4530
if (!fixed) return true;
4515
4531
this._dot_throw = return_true;
4516
4532
if (fixed._dot_throw(compressor)) {
@@ -11454,14 +11470,14 @@ Compressor.prototype.compress = function(node) {
11454
11470
11455
11471
var indexFns = makePredicate("indexOf lastIndexOf");
11456
11472
var commutativeOperators = makePredicate("== === != !== * & | ^");
11457
- function is_object(node) {
11458
- if (node instanceof AST_Assign) return node.operator == "=" && is_object(node.right);
11459
- if (node instanceof AST_Sequence) return is_object(node.tail_node());
11460
- if (node instanceof AST_SymbolRef) return is_object(node.fixed_value());
11473
+ function is_object(node, plain) {
11474
+ if (node instanceof AST_Assign) return !plain && node.operator == "=" && is_object(node.right);
11475
+ if (node instanceof AST_New) return !plain;
11476
+ if (node instanceof AST_Sequence) return is_object(node.tail_node(), plain);
11477
+ if (node instanceof AST_SymbolRef) return !plain && is_object(node.fixed_value());
11461
11478
return node instanceof AST_Array
11462
11479
|| node instanceof AST_Class
11463
11480
|| node instanceof AST_Lambda
11464
- || node instanceof AST_New
11465
11481
|| node instanceof AST_Object;
11466
11482
}
11467
11483
0 commit comments