Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30761eede5 | ||
|
|
fb30aeccaf | ||
|
|
226aa1f76b | ||
|
|
6e235602fb | ||
|
|
980fcbb56b | ||
|
|
375ebe316d | ||
|
|
2500930234 | ||
|
|
2f0da2ff05 | ||
|
|
83a3cbf151 | ||
|
|
da8d154571 |
184
lib/compress.js
184
lib/compress.js
@@ -325,22 +325,22 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
var lhs = is_lhs(node, parent);
|
||||
if (lhs) return lhs;
|
||||
if (!immutable
|
||||
&& parent instanceof AST_Call
|
||||
&& parent.expression === node
|
||||
&& !parent.is_expr_pure(compressor)
|
||||
&& (!(value instanceof AST_Function)
|
||||
|| !(parent instanceof AST_New) && value.contains_this())) {
|
||||
return true;
|
||||
if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1);
|
||||
if (parent instanceof AST_Call) {
|
||||
return !immutable
|
||||
&& parent.expression === node
|
||||
&& !parent.is_expr_pure(compressor)
|
||||
&& (!(value instanceof AST_Function)
|
||||
|| !(parent instanceof AST_New) && value.contains_this());
|
||||
}
|
||||
if (parent instanceof AST_Array) {
|
||||
return is_modified(compressor, tw, parent, parent, level + 1);
|
||||
}
|
||||
if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
|
||||
if (parent instanceof AST_ForIn) return parent.init === node;
|
||||
if (parent instanceof AST_ObjectKeyVal) {
|
||||
if (parent.value !== node) return;
|
||||
var obj = tw.parent(level + 1);
|
||||
return is_modified(compressor, tw, obj, obj, level + 2);
|
||||
}
|
||||
if (parent instanceof AST_PropAccess && parent.expression === node) {
|
||||
if (parent instanceof AST_PropAccess) {
|
||||
if (parent.expression !== node) return;
|
||||
var prop = read_property(value, parent);
|
||||
return (!immutable || recursive) && is_modified(compressor, tw, parent, prop, level + 1);
|
||||
}
|
||||
@@ -514,33 +514,41 @@ merge(Compressor.prototype, {
|
||||
|| value instanceof AST_This;
|
||||
}
|
||||
|
||||
function has_escaped(d, node, parent) {
|
||||
if (parent instanceof AST_Assign) return parent.operator == "=" && parent.right === node;
|
||||
if (parent instanceof AST_Call) return parent.expression !== node || parent instanceof AST_New;
|
||||
if (parent instanceof AST_Exit) return parent.value === node && node.scope !== d.scope;
|
||||
if (parent instanceof AST_VarDef) return parent.value === node;
|
||||
}
|
||||
|
||||
function value_in_use(node, parent) {
|
||||
if (parent instanceof AST_Array) return true;
|
||||
if (parent instanceof AST_Binary) return lazy_op[parent.operator];
|
||||
if (parent instanceof AST_Conditional) return parent.condition !== node;
|
||||
if (parent instanceof AST_Sequence) return parent.tail_node() === node;
|
||||
}
|
||||
|
||||
function mark_escaped(tw, d, scope, node, value, level, depth) {
|
||||
var parent = tw.parent(level);
|
||||
if (value && value.is_constant()) return;
|
||||
if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
|
||||
|| parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
|
||||
|| parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
|
||||
|| parent instanceof AST_VarDef && node === parent.value) {
|
||||
if (has_escaped(d, node, parent)) {
|
||||
d.escaped.push(parent);
|
||||
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
||||
if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth;
|
||||
return;
|
||||
} else if (parent instanceof AST_Array
|
||||
|| parent instanceof AST_Binary && lazy_op[parent.operator]
|
||||
|| parent instanceof AST_Conditional && node !== parent.condition
|
||||
|| parent instanceof AST_Sequence && node === parent.tail_node()) {
|
||||
} else if (value_in_use(node, parent)) {
|
||||
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
|
||||
} else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
|
||||
} else if (parent instanceof AST_ObjectKeyVal && parent.value === node) {
|
||||
var obj = tw.parent(level + 1);
|
||||
mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
|
||||
} else if (parent instanceof AST_PropAccess && node === parent.expression) {
|
||||
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
|
||||
value = read_property(value, parent);
|
||||
mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
|
||||
if (value) return;
|
||||
}
|
||||
if (level > 0) return;
|
||||
if (parent instanceof AST_Call && node === parent.expression) return;
|
||||
if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
|
||||
if (parent instanceof AST_Call && parent.expression === node) return;
|
||||
if (parent instanceof AST_Sequence && parent.tail_node() !== node) return;
|
||||
if (parent instanceof AST_SimpleStatement) return;
|
||||
if (parent instanceof AST_Unary && !unary_side_effects[parent.operator]) return;
|
||||
d.direct_access = true;
|
||||
@@ -739,13 +747,11 @@ merge(Compressor.prototype, {
|
||||
push(tw);
|
||||
var init = this.init;
|
||||
init.walk(tw);
|
||||
if (init instanceof AST_Var) {
|
||||
init = init.definitions[0].name;
|
||||
} else while (init instanceof AST_PropAccess) {
|
||||
init = init.expression.tail_node();
|
||||
if (init instanceof AST_SymbolRef) {
|
||||
init.definition().fixed = false;
|
||||
} else if (init instanceof AST_Var) {
|
||||
init.definitions[0].name.definition().fixed = false;
|
||||
}
|
||||
var def = init.definition();
|
||||
if (def) def.fixed = false;
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
@@ -2638,6 +2644,14 @@ merge(Compressor.prototype, {
|
||||
defs = stat.init;
|
||||
}
|
||||
} else if (stat instanceof AST_ForIn) {
|
||||
if (defs && defs.TYPE == stat.init.TYPE) {
|
||||
defs.definitions = defs.definitions.concat(stat.init.definitions);
|
||||
var name = stat.init.definitions[0].name;
|
||||
var ref = make_node(AST_SymbolRef, name, name);
|
||||
name.definition().references.push(ref);
|
||||
stat.init = ref;
|
||||
CHANGED = true;
|
||||
}
|
||||
stat.object = join_assigns_expr(stat.object);
|
||||
} else if (stat instanceof AST_If) {
|
||||
stat.condition = join_assigns_expr(stat.condition);
|
||||
@@ -4298,6 +4312,7 @@ merge(Compressor.prototype, {
|
||||
return sym;
|
||||
};
|
||||
var assign_in_use = Object.create(null);
|
||||
var for_ins = Object.create(null);
|
||||
var in_use = [];
|
||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||
var value_read = Object.create(null);
|
||||
@@ -4588,23 +4603,37 @@ merge(Compressor.prototype, {
|
||||
return !def || fn.name && def === fn.name.definition();
|
||||
}
|
||||
});
|
||||
if (head.length == 0 && tail.length == duplicated) {
|
||||
[].unshift.apply(side_effects, tail.map(function(def) {
|
||||
AST_Node.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
|
||||
var sym = def.name.definition();
|
||||
var ref = make_node(AST_SymbolRef, def.name, def.name);
|
||||
sym.references.push(ref);
|
||||
var assign = make_node(AST_Assign, def, {
|
||||
operator: "=",
|
||||
left: ref,
|
||||
right: def.value
|
||||
});
|
||||
var index = indexOf_assign(sym, def);
|
||||
if (index >= 0) assign_in_use[sym.id][index] = assign;
|
||||
sym.eliminated++;
|
||||
return assign;
|
||||
}));
|
||||
} else if (head.length > 0 || tail.length > 0) {
|
||||
switch (head.length) {
|
||||
case 0:
|
||||
if (tail.length == 0) break;
|
||||
if (tail.length == duplicated) {
|
||||
[].unshift.apply(side_effects, tail.map(function(def) {
|
||||
AST_Node.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
|
||||
var sym = def.name.definition();
|
||||
var ref = make_node(AST_SymbolRef, def.name, def.name);
|
||||
sym.references.push(ref);
|
||||
var assign = make_node(AST_Assign, def, {
|
||||
operator: "=",
|
||||
left: ref,
|
||||
right: def.value
|
||||
});
|
||||
var index = indexOf_assign(sym, def);
|
||||
if (index >= 0) assign_in_use[sym.id][index] = assign;
|
||||
sym.eliminated++;
|
||||
return assign;
|
||||
}));
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
if (tail.length == 0) {
|
||||
var id = head[0].name.definition().id;
|
||||
if (id in for_ins) {
|
||||
node.definitions = head;
|
||||
for_ins[id].init = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
node.definitions = head.concat(tail);
|
||||
body.push(node);
|
||||
}
|
||||
@@ -4613,16 +4642,7 @@ merge(Compressor.prototype, {
|
||||
body: make_sequence(node, side_effects)
|
||||
}));
|
||||
}
|
||||
switch (body.length) {
|
||||
case 0:
|
||||
return in_list ? List.skip : make_node(AST_EmptyStatement, node);
|
||||
case 1:
|
||||
return body[0];
|
||||
default:
|
||||
return in_list ? List.splice(body) : make_node(AST_BlockStatement, node, {
|
||||
body: body
|
||||
});
|
||||
}
|
||||
return insert_statements(body, node, in_list);
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement && node.body instanceof AST_For) {
|
||||
// Certain combination of unused name + side effect leads to invalid AST:
|
||||
@@ -4682,15 +4702,22 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
var def = sym.definition();
|
||||
if (!def) return;
|
||||
if (def.scope !== self) return;
|
||||
if (def.id in in_use_ids) return;
|
||||
if (def.scope !== self && member(def, self.enclosed)) return;
|
||||
log(sym, "Dropping unused loop variable {name}");
|
||||
if (for_ins[def.id] === node) delete for_ins[def.id];
|
||||
var body = [];
|
||||
var value = node.object.drop_side_effect_free(compressor);
|
||||
if (!value) return in_list ? List.skip : make_node(AST_EmptyStatement, node);
|
||||
AST_Node.warn("Side effects in object of for-in loop [{file}:{line},{col}]", value.start);
|
||||
return make_node(AST_SimpleStatement, node, {
|
||||
body: value
|
||||
});
|
||||
if (value) {
|
||||
AST_Node.warn("Side effects in object of for-in loop [{file}:{line},{col}]", value.start);
|
||||
body.push(make_node(AST_SimpleStatement, node, {
|
||||
body: value
|
||||
}));
|
||||
}
|
||||
if (node.init instanceof AST_Definitions && def.orig[0] instanceof AST_SymbolCatch) {
|
||||
body.push(node.init);
|
||||
}
|
||||
return insert_statements(body, node, in_list);
|
||||
} else if (node instanceof AST_Sequence) {
|
||||
if (node.expressions.length == 1) return node.expressions[0];
|
||||
}
|
||||
@@ -4723,6 +4750,19 @@ merge(Compressor.prototype, {
|
||||
};
|
||||
}
|
||||
|
||||
function insert_statements(body, orig, in_list) {
|
||||
switch (body.length) {
|
||||
case 0:
|
||||
return in_list ? List.skip : make_node(AST_EmptyStatement, orig);
|
||||
case 1:
|
||||
return body[0];
|
||||
default:
|
||||
return in_list ? List.splice(body) : make_node(AST_BlockStatement, orig, {
|
||||
body: body
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function track_assigns(def, node) {
|
||||
if (def.scope !== self) return false;
|
||||
if (!def.fixed || !node.fixed) assign_in_use[def.id] = false;
|
||||
@@ -4800,6 +4840,10 @@ merge(Compressor.prototype, {
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_ForIn) {
|
||||
if (node.init instanceof AST_SymbolRef && scope === self) {
|
||||
var id = node.init.definition().id;
|
||||
if (!(id in for_ins)) for_ins[id] = node;
|
||||
}
|
||||
if (!drop_vars || !compressor.option("loops")) return;
|
||||
if (!is_empty(node.body)) return;
|
||||
if (node.init.has_side_effects(compressor)) return;
|
||||
@@ -7512,13 +7556,15 @@ merge(Compressor.prototype, {
|
||||
&& self.left.is_number(compressor)) {
|
||||
if (self.left.left instanceof AST_Constant) {
|
||||
var lhs = make_binary(self.left, self.operator, self.left.left, self.right, self.left.left.start, self.right.end);
|
||||
self = make_binary(self, self.left.operator, lhs, self.left.right);
|
||||
self = make_binary(self, self.left.operator, try_evaluate(compressor, lhs), self.left.right);
|
||||
} else if (self.left.right instanceof AST_Constant) {
|
||||
var rhs = make_binary(self.left, align(self.left.operator, self.operator), self.left.right, self.right, self.left.right.start, self.right.end);
|
||||
if (self.left.operator != "-"
|
||||
|| !self.right.value
|
||||
|| rhs.evaluate(compressor)
|
||||
|| !self.left.left.is_negative_zero()) {
|
||||
var op = align(self.left.operator, self.operator);
|
||||
var rhs = try_evaluate(compressor, make_binary(self.left, op, self.left.right, self.right));
|
||||
if (rhs.is_constant()
|
||||
&& !(self.left.operator == "-"
|
||||
&& self.right.value != 0
|
||||
&& +rhs.value == 0
|
||||
&& self.left.left.is_negative_zero())) {
|
||||
self = make_binary(self, self.left.operator, self.left.left, rhs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.10.3",
|
||||
"version": "3.10.4",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -2848,3 +2848,60 @@ issue_4025: {
|
||||
"1 1 1",
|
||||
]
|
||||
}
|
||||
|
||||
forin_var_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var k;
|
||||
for (k in [ 1, 2 ])
|
||||
console.log(k);
|
||||
for (k in { PASS: 3 })
|
||||
console.log(k);
|
||||
console.log(k);
|
||||
}
|
||||
expect: {
|
||||
for (var k in [ 1, 2 ])
|
||||
console.log(k);
|
||||
for (k in { PASS: 3 })
|
||||
console.log(k);
|
||||
console.log(k);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
"1",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
forin_var_2: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
switch (0) {
|
||||
case function() {
|
||||
for (a in 0);
|
||||
}:
|
||||
var b = 0;
|
||||
}
|
||||
for (var c = 0; a;);
|
||||
var a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
switch (0) {
|
||||
case function() {
|
||||
for (a in 0);
|
||||
}:
|
||||
}
|
||||
for (; a;);
|
||||
var a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
@@ -1483,8 +1483,7 @@ issue_2663_2: {
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var i;
|
||||
for (i in { a: 1, b: 2, c: 3 })
|
||||
for (var i in { a: 1, b: 2, c: 3 })
|
||||
j = i, console.log(j);
|
||||
var j;
|
||||
})();
|
||||
|
||||
@@ -277,8 +277,8 @@ join_object_assignments_forin: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = { a: "PASS" };
|
||||
for (var a in o)
|
||||
var o = { a: "PASS" }, a;
|
||||
for (a in o)
|
||||
return o[a];
|
||||
}());
|
||||
}
|
||||
|
||||
@@ -1009,3 +1009,82 @@ issue_4082: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4084: {
|
||||
options = {
|
||||
keep_fargs: "strict",
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
function f(a) {
|
||||
var b = a++;
|
||||
for (a in "foo");
|
||||
}
|
||||
f();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
(function() {
|
||||
0;
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4091_1: {
|
||||
options = {
|
||||
loops: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
for (var e in 42);
|
||||
}
|
||||
console.log(e && e);
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
var e;
|
||||
}
|
||||
console.log(e && e);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4091_2: {
|
||||
options = {
|
||||
loops: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
for (e in 42);
|
||||
var e;
|
||||
}
|
||||
console.log(e && e);
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
var e;
|
||||
}
|
||||
console.log(e && e);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
@@ -637,6 +637,22 @@ evaluate_7_unsafe_math: {
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_8_unsafe_math: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "42" ];
|
||||
console.log(a * (1 / 7));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "42" ];
|
||||
console.log(+a / 7);
|
||||
}
|
||||
expect_stdout: "6"
|
||||
}
|
||||
|
||||
NaN_redefined: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
var o = this;
|
||||
|
||||
for (var k in o) L17060: {
|
||||
a++;
|
||||
UNUSED: {
|
||||
console.log(0 - .1 - .1 - .1);
|
||||
}
|
||||
|
||||
var a;
|
||||
|
||||
console.log(k);
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
// (beautified)
|
||||
var o = this;
|
||||
|
||||
for (var k in o) {}
|
||||
|
||||
var a;
|
||||
|
||||
console.log(k);
|
||||
// output: a
|
||||
console.log(0 - 1 - .1 - .1);
|
||||
// output: -1.2000000000000002
|
||||
//
|
||||
// minify: k
|
||||
// minify: -1.2
|
||||
//
|
||||
// options: {
|
||||
// "compress": {
|
||||
// "unsafe_math": true
|
||||
// },
|
||||
// "mangle": false
|
||||
// }
|
||||
@@ -24,6 +24,9 @@ describe("test/reduce.js", function() {
|
||||
});
|
||||
it("Should eliminate unreferenced labels", function() {
|
||||
var result = reduce_test(read("test/input/reduce/label.js"), {
|
||||
compress: {
|
||||
unsafe_math: true,
|
||||
},
|
||||
mangle: false,
|
||||
}, {
|
||||
verbose: false,
|
||||
|
||||
@@ -112,19 +112,18 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
// no structural AST changes before this point.
|
||||
if (node.start._permute >= REPLACEMENTS.length) return;
|
||||
|
||||
if (parent instanceof U.AST_Assign
|
||||
&& parent.left === node
|
||||
|| parent instanceof U.AST_Unary
|
||||
&& parent.expression === node
|
||||
&& ["++", "--", "delete"].indexOf(parent.operator) >= 0) {
|
||||
// ignore lvalues
|
||||
// ignore lvalues
|
||||
if (parent instanceof U.AST_Assign && parent.left === node) return;
|
||||
if (parent instanceof U.AST_Unary && parent.expression === node) switch (parent.operator) {
|
||||
case "++":
|
||||
case "--":
|
||||
case "delete":
|
||||
return;
|
||||
}
|
||||
if ((parent instanceof U.AST_For || parent instanceof U.AST_ForIn)
|
||||
&& parent.init === node && node instanceof U.AST_Var) {
|
||||
// preserve for (var ...)
|
||||
return node;
|
||||
}
|
||||
// preserve for (var xxx; ...)
|
||||
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Var) return node;
|
||||
// preserve for (xxx in ...)
|
||||
if (parent instanceof U.AST_ForIn && parent.init === node) return node;
|
||||
|
||||
// node specific permutations with no parent logic
|
||||
|
||||
@@ -452,6 +451,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
node.start = JSON.parse(JSON.stringify(node.start));
|
||||
node.start._permute = 0;
|
||||
}));
|
||||
var before_iterations = testcase;
|
||||
for (var c = 0; c < max_iterations; ++c) {
|
||||
if (verbose && pass == 1 && c % 25 == 0) {
|
||||
log("// reduce test pass " + pass + ", iteration " + c + ": " + testcase.length + " bytes");
|
||||
@@ -494,7 +494,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c == 0) break;
|
||||
if (before_iterations === testcase) break;
|
||||
if (verbose) {
|
||||
log("// reduce test pass " + pass + ": " + testcase.length + " bytes");
|
||||
}
|
||||
@@ -557,7 +557,7 @@ function try_beautify(testcase, minify_options, expected, result_cache, timeout)
|
||||
code: testcase,
|
||||
};
|
||||
} else {
|
||||
var actual = run_code(result.code, toplevel, result_cache, timeout);
|
||||
var actual = run_code(result.code, toplevel, result_cache, timeout).result;
|
||||
if (!sandbox.same_stdout(expected, actual)) return {
|
||||
code: testcase,
|
||||
};
|
||||
@@ -650,7 +650,15 @@ function wrap_with_console_log(node) {
|
||||
|
||||
function run_code(code, toplevel, result_cache, timeout) {
|
||||
var key = crypto.createHash("sha1").update(code).digest("base64");
|
||||
return result_cache[key] || (result_cache[key] = sandbox.run_code(code, toplevel, timeout));
|
||||
var value = result_cache[key];
|
||||
if (!value) {
|
||||
var start = Date.now();
|
||||
result_cache[key] = value = {
|
||||
result: sandbox.run_code(code, toplevel, timeout),
|
||||
elapsed: Date.now() - start,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
@@ -658,21 +666,19 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
if (minified.error) return minified;
|
||||
|
||||
var toplevel = sandbox.has_toplevel(minify_options);
|
||||
var elapsed = Date.now();
|
||||
var unminified_result = run_code(code, toplevel, result_cache, max_timeout);
|
||||
elapsed = Date.now() - elapsed;
|
||||
var timeout = Math.min(100 * elapsed, max_timeout);
|
||||
var minified_result = run_code(minified.code, toplevel, result_cache, timeout);
|
||||
var unminified = run_code(code, toplevel, result_cache, max_timeout);
|
||||
var timeout = Math.min(100 * unminified.elapsed, max_timeout);
|
||||
var minified_result = run_code(minified.code, toplevel, result_cache, timeout).result;
|
||||
|
||||
if (sandbox.same_stdout(unminified_result, minified_result)) {
|
||||
return is_timed_out(unminified_result) && is_timed_out(minified_result) && {
|
||||
if (sandbox.same_stdout(unminified.result, minified_result)) {
|
||||
return is_timed_out(unminified.result) && is_timed_out(minified_result) && {
|
||||
timed_out: true,
|
||||
};
|
||||
}
|
||||
return {
|
||||
unminified_result: unminified_result,
|
||||
unminified_result: unminified.result,
|
||||
minified_result: minified_result,
|
||||
elapsed: elapsed,
|
||||
elapsed: unminified.elapsed,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ process.on("beforeExit", function() {
|
||||
if (queued > 3) {
|
||||
process.stdout.write("0");
|
||||
} else if (now - earliest > 0 && total > 1) {
|
||||
process.stdout.write(Math.min(20 * (now - earliest) / (total - 1), 6300000).toFixed(0));
|
||||
process.stdout.write(Math.min(20 * (now - earliest) / (total - 1), 18000000).toFixed(0));
|
||||
} else {
|
||||
process.stdout.write("3600000");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user