aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js36
-rw-r--r--test/compress/arrays.js110
-rw-r--r--test/compress/reduce_vars.js21
3 files changed, 158 insertions, 9 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 4e276528..72f8e636 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4003,17 +4003,17 @@ merge(Compressor.prototype, {
return this;
});
def(AST_Binary, function(compressor, first_in_statement) {
- var right = this.right.drop_side_effect_free(compressor);
+ var right = this.right.drop_side_effect_free(compressor, first_in_statement);
if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
if (lazy_op[this.operator]) {
if (right === this.right) return this;
var node = this.clone();
- node.right = right;
+ node.right = right.drop_side_effect_free(compressor);
return node;
} else {
var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
- return make_sequence(this, [ left, right ]);
+ if (!left) return right;
+ return make_sequence(this, [ left, right.drop_side_effect_free(compressor) ]);
}
});
def(AST_Call, function(compressor, first_in_statement) {
@@ -4666,12 +4666,30 @@ merge(Compressor.prototype, {
if (compressor.option("unsafe")) {
if (is_undeclared_ref(exp)) switch (exp.name) {
case "Array":
- if (self.args.length != 1) {
- return make_node(AST_Array, self, {
- elements: self.args
- }).optimize(compressor);
+ if (self.args.length == 1) {
+ var first = self.args[0];
+ if (first instanceof AST_Number) try {
+ var length = first.getValue();
+ if (length > 6) break;
+ var elements = Array(length);
+ for (var i = 0; i < length; i++) elements[i] = make_node(AST_Hole, self);
+ return make_node(AST_Array, self, {
+ elements: elements
+ });
+ } catch (ex) {
+ compressor.warn("Invalid array length: {length} [{file}:{line},{col}]", {
+ length: length,
+ file: self.start.file,
+ line: self.start.line,
+ col: self.start.col
+ });
+ break;
+ }
+ if (!first.is_boolean(compressor) && !first.is_string(compressor)) break;
}
- break;
+ return make_node(AST_Array, self, {
+ elements: self.args
+ });
case "Object":
if (self.args.length == 0) {
return make_node(AST_Object, self, {
diff --git a/test/compress/arrays.js b/test/compress/arrays.js
index 36292206..497e96c4 100644
--- a/test/compress/arrays.js
+++ b/test/compress/arrays.js
@@ -239,3 +239,113 @@ index_length: {
}
expect_stdout: "1 2"
}
+
+constructor_bad: {
+ options = {
+ unsafe: true
+ }
+ input: {
+ try {
+ Array(NaN);
+ console.log("FAIL1");
+ } catch (ex) {
+ try {
+ new Array(NaN);
+ console.log("FAIL2");
+ } catch (ex) {
+ console.log("PASS");
+ }
+ }
+ try {
+ Array(3.14);
+ console.log("FAIL1");
+ } catch (ex) {
+ try {
+ new Array(3.14);
+ console.log("FAIL2");
+ } catch (ex) {
+ console.log("PASS");
+ }
+ }
+ }
+ expect: {
+ try {
+ Array(NaN);
+ console.log("FAIL1");
+ } catch (ex) {
+ try {
+ Array(NaN);
+ console.log("FAIL2");
+ } catch (ex) {
+ console.log("PASS");
+ }
+ }
+ try {
+ Array(3.14);
+ console.log("FAIL1");
+ } catch (ex) {
+ try {
+ Array(3.14);
+ console.log("FAIL2");
+ } catch (ex) {
+ console.log("PASS");
+ }
+ }
+ }
+ expect_stdout: [
+ "PASS",
+ "PASS",
+ ]
+ expect_warnings: [
+ "WARN: Invalid array length: 3.14 [test/compress/arrays.js:13,12]",
+ "WARN: Invalid array length: 3.14 [test/compress/arrays.js:17,16]",
+ ]
+}
+
+constructor_good: {
+ options = {
+ unsafe: true
+ }
+ input: {
+ console.log(Array());
+ console.log(Array(0));
+ console.log(Array(1));
+ console.log(Array(6));
+ console.log(Array(7));
+ console.log(Array(1, 2));
+ console.log(Array(false));
+ console.log(Array("foo"));
+ console.log(Array(Array));
+ console.log(new Array());
+ console.log(new Array(0));
+ console.log(new Array(1));
+ console.log(new Array(6));
+ console.log(new Array(7));
+ console.log(new Array(1, 2));
+ console.log(new Array(false));
+ console.log(new Array("foo"));
+ console.log(new Array(Array));
+ }
+ expect: {
+ console.log([]);
+ console.log([]);
+ console.log([,]);
+ console.log([,,,,,,]);
+ console.log(Array(7));
+ console.log([ 1, 2 ]);
+ console.log([ false ]);
+ console.log([ "foo" ]);
+ console.log(Array(Array));
+ console.log([]);
+ console.log([]);
+ console.log([,]);
+ console.log([,,,,,,]);
+ console.log(Array(7));
+ console.log([ 1, 2 ]);
+ console.log([ false ]);
+ console.log([ "foo" ]);
+ console.log(Array(Array));
+ }
+ expect_stdout: true
+ expect_warnings: []
+}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 27e53452..fb5038b5 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -6716,3 +6716,24 @@ issue_3297: {
}
expect_stdout: "true"
}
+
+drop_side_effect_free: {
+ options = {
+ collapse_vars: true,
+ evaluate: true,
+ reduce_vars: true,
+ side_effects: true,
+ toplevel: true,
+ }
+ input: {
+ var a = 123;
+ "" + (a && (a.b = 0) || a);
+ console.log(a);
+ }
+ expect: {
+ var a = 123;
+ a.b = 0;
+ console.log(a);
+ }
+ expect_stdout: "123"
+}