Compare commits

...

12 Commits

Author SHA1 Message Date
Alex Lam S.L
a9ef659bcb v3.15.5 2022-05-11 05:26:10 +08:00
Alex Lam S.L
35c2149dbd fix corner case in merge_vars (#5437)
fixes #5436
2022-05-08 04:16:28 +08:00
Alex Lam S.L
89a35f9fcd fix corner case in reduce_vars (#5435)
fixes #5434
2022-05-06 09:32:47 +08:00
Alex Lam S.L
1a4e99dc2d avoid v8 quirks in ufuzz (#5431)
closes #5428
closes #5429
2022-04-25 21:33:31 +08:00
Alex Lam S.L
cb870f6fd6 document v8 quirks (#5430)
closes #5428
closes #5429
2022-04-21 02:51:53 +08:00
Alex Lam S.L
a0c0c294c5 fix corner case in assignments (#5426)
fixes #5425
2022-04-19 13:19:30 +08:00
Alex Lam S.L
fbdb7eeda3 fix corner case in merge_vars (#5424)
fixes #5423
2022-04-19 09:04:06 +08:00
Alex Lam S.L
1bc0fccc8c improve ufuzz resilience (#5422) 2022-04-18 13:03:01 +08:00
Alex Lam S.L
20252c6483 fix corner case in merge_vars (#5421)
fixes #5420
2022-04-18 06:38:08 +08:00
Alex Lam S.L
e396912ea2 suppress false positives with export & import (#5418) 2022-04-16 04:27:50 +08:00
Alex Lam S.L
5ebfa78f56 fix corner case with arguments (#5417)
fixes #5416
2022-04-15 06:52:10 +08:00
Alex Lam S.L
950609f578 fix corner case in inline (#5415)
fixes #5414
2022-04-13 06:19:37 +08:00
12 changed files with 359 additions and 81 deletions

View File

@@ -1373,3 +1373,19 @@ To allow for better optimizations, the compiler makes various assumptions:
// TypeError: const 'a' has already been declared
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
try {
class A {
static 42;
static get 42() {}
}
console.log("PASS");
} catch (e) {
console.log("FAIL");
}
// Expected: "PASS"
// Actual: "FAIL"
```
UglifyJS may modify the input which in turn may suppress those errors.

View File

@@ -649,7 +649,7 @@ Compressor.prototype.compress = function(node) {
}
if (!HOP(tw.safe_ids, def.id)) {
if (!safe) return false;
if (safe.read) {
if (safe.read || tw.in_loop) {
var scope = tw.find_parent(AST_BlockScope);
if (scope instanceof AST_Class) return false;
if (def.scope.resolve() !== scope.resolve()) return false;
@@ -6081,18 +6081,15 @@ Compressor.prototype.compress = function(node) {
}
if (node instanceof AST_Call) {
var exp = node.expression;
var tail = exp.tail_node();
if (!(tail instanceof AST_LambdaExpression)) {
if (exp instanceof AST_LambdaExpression) {
node.args.forEach(function(arg) {
arg.walk(tw);
});
exp.walk(tw);
} else {
descend();
return mark_expression(exp);
mark_expression(exp);
}
if (exp !== tail) exp.expressions.slice(0, -1).forEach(function(node) {
node.walk(tw);
});
node.args.forEach(function(arg) {
arg.walk(tw);
});
tail.walk(tw);
return true;
}
if (node instanceof AST_Class) {
@@ -6105,9 +6102,10 @@ Compressor.prototype.compress = function(node) {
if (prop.static) {
prop.value.walk(tw);
} else {
push(tw);
push();
segment.block = node;
prop.value.walk(tw);
pop(tw);
pop();
}
});
return true;
@@ -6172,6 +6170,8 @@ Compressor.prototype.compress = function(node) {
if (node === self) root = segment;
if (node instanceof AST_Lambda) {
if (node.name) references[node.name.definition().id] = false;
var parent = tw.parent();
var in_iife = parent && parent.TYPE == "Call" && parent.expression === node;
var marker = node.uses_arguments && !tw.has_directive("use strict") ? function(node) {
if (node instanceof AST_SymbolFunarg) references[node.definition().id] = false;
} : function(node) {
@@ -6187,11 +6187,13 @@ Compressor.prototype.compress = function(node) {
|| node.parent_scope.find_variable(ref.name) === def)) {
references[def.id] = false;
references[ldef.id] = false;
} else {
} else if (in_iife) {
var save = segment;
pop();
mark(ref, true);
segment = save;
} else {
mark(ref, true);
}
return true;
});
@@ -6214,7 +6216,8 @@ Compressor.prototype.compress = function(node) {
} else {
descend();
}
return mark_expression(exp);
mark_expression(exp);
return true;
}
if (node instanceof AST_Switch) {
node.expression.walk(tw);
@@ -6246,9 +6249,7 @@ Compressor.prototype.compress = function(node) {
if (node instanceof AST_Try) {
var save_try = in_try;
in_try = node;
var save = segment;
walk_body(node, tw);
segment = save;
if (node.bcatch) {
if (node.bcatch.argname) node.bcatch.argname.mark_symbol(function(node) {
if (node instanceof AST_SymbolCatch) {
@@ -6266,7 +6267,6 @@ Compressor.prototype.compress = function(node) {
}
}
in_try = save_try;
segment = save;
if (node.bfinally) node.bfinally.walk(tw);
return true;
}
@@ -6316,11 +6316,9 @@ Compressor.prototype.compress = function(node) {
}
function mark_expression(exp) {
if (compressor.option("ie")) {
var sym = root_expr(exp);
if (sym instanceof AST_SymbolRef) sym.walk(tw);
}
return true;
if (!compressor.option("ie")) return;
var sym = root_expr(exp);
if (sym instanceof AST_SymbolRef) sym.walk(tw);
}
function walk_cond(condition, consequent, alternative) {
@@ -11142,9 +11140,15 @@ Compressor.prototype.compress = function(node) {
&& assign instanceof AST_Assign
&& assign.operator == "="
&& self.left.equivalent_to(assign.left)) {
self.right = assign.right;
assign.right = self;
return assign;
return make_node(AST_Assign, self, {
operator: "=",
left: assign.left,
right: make_node(AST_Binary, self, {
operator: self.operator,
left: self.left,
right: assign.right,
}),
}).optimize(compressor);
}
}
if (compressor.option("comparisons")) switch (self.operator) {
@@ -13382,7 +13386,7 @@ Compressor.prototype.compress = function(node) {
});
var body = [];
fn.variables.each(function(def, name) {
if (name == "arguments") return;
if (!arrow && name == "arguments" && def.orig.length == 1) return;
names.set(name, true);
scope.enclosed.push(def);
scope.variables.set(name, def);

View File

@@ -469,6 +469,7 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
name: "arguments",
scope: this,
start: this.start,
end: this.end,
}));

View File

@@ -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.15.4",
"version": "3.15.5",
"engines": {
"node": ">=0.8.0"
},

View File

@@ -1018,3 +1018,91 @@ issue_5356: {
expect_stdout: "NaN"
node_version: ">=4"
}
issue_5414_1: {
options = {
arrows: true,
if_return: true,
inline: true,
toplevel: true,
}
input: {
(() => {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
})();
}
expect: {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
}
expect_stdout: true
node_version: ">=4"
}
issue_5414_2: {
options = {
arrows: true,
inline: true,
side_effects: true,
toplevel: true,
}
input: {
(() => {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
})();
}
expect: {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
}
expect_stdout: true
node_version: ">=4"
}
issue_5416: {
options = {
dead_code: true,
evaluate: true,
inline: true,
loops: true,
unused: true,
}
input: {
var f = () => {
while ((() => {
console;
var a = function g(arguments) {
console.log(arguments);
}();
})());
};
f();
}
expect: {
var f = () => {
{
arguments = void 0;
console;
console.log(arguments);
var arguments;
}
};
f();
}
expect_stdout: "undefined"
node_version: ">=4"
}

View File

@@ -2571,3 +2571,33 @@ issue_5389: {
expect_stdout: "PASS PASS"
node_version: ">=12"
}
issue_5436: {
options = {
merge_vars: true,
}
input: {
function f(a) {
class A {
p = a;
}
var b = "FAIL";
A == b && b();
return new A();
}
console.log(f("PASS").p);
}
expect: {
function f(a) {
class A {
p = a;
}
var b = "FAIL";
A == b && b();
return new A();
}
console.log(f("PASS").p);
}
expect_stdout: "PASS"
node_version: ">=12"
}

View File

@@ -3535,3 +3535,34 @@ issue_5405_2: {
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5423: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a, b;
function f({
[function() {
if (++a)
return 42;
}()]: c
}) {}
f(b = f);
console.log(typeof b);
}
expect: {
var a, b;
function f({
[function() {
if (++a)
return 42;
}()]: c
}) {}
f(b = f);
console.log(typeof b);
}
expect_stdout: "function"
node_version: ">=6"
}

View File

@@ -3702,3 +3702,33 @@ issue_5182: {
]
node_version: ">=4"
}
issue_5420: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
do {
var a = "FAIL 1";
a && a.p;
a = "FAIL 2";
try {
continue;
} catch (e) {}
var b = "FAIL 3";
} while (console.log(b || "PASS"));
}
expect: {
do {
var a = "FAIL 1";
a && a.p;
a = "FAIL 2";
try {
continue;
} catch (e) {}
var b = "FAIL 3";
} while (console.log(b || "PASS"));
}
expect_stdout: "PASS"
}

View File

@@ -7861,3 +7861,38 @@ issue_5324: {
}
expect_stdout: "NaN"
}
issue_5434: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function(a) {
for (var i = 0; i < 2; i++) {
var b = "FAIL";
f && f();
a = b;
var f = function() {
b = "PASS";
};
}
return a;
}());
}
expect: {
console.log(function(a) {
for (var i = 0; i < 2; i++) {
var b = "FAIL";
f && f();
a = b;
var f = function() {
b = "PASS";
};
}
return a;
}());
}
expect_stdout: "PASS"
}

View File

@@ -1525,3 +1525,25 @@ issue_5385_2: {
]
node_version: ">=10"
}
issue_5425: {
options = {
assignments: true,
ie: true,
toplevel: true,
unused: true,
yields: true,
}
input: {
var a = "FAIL";
var b = function* f() {}(a ? a = "PASS" : 42);
console.log(a, typeof f);
}
expect: {
var a = "FAIL";
(function* f() {})(a && (a = "PASS"));
console.log(a, typeof f);
}
expect_stdout: "PASS undefined"
node_version: ">=4"
}

View File

@@ -52,8 +52,11 @@ exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expec
return typeof expected == typeof actual && strip_func_ids(expected) == strip_func_ids(actual);
};
exports.patch_module_statements = function(code) {
var count = 0, has_default = "", imports = [];
code = code.replace(/\bexport(?:\s*\{[^{}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
var count = 0, has_default = "", imports = [], strict_mode = "";
code = code.replace(/^\s*("|')use strict\1\s*;?/, function(match) {
strict_mode = match;
return "";
}).replace(/\bexport(?:\s*\{[^{}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
if (/^export\s+default/.test(match)) has_default = "var _uglify_export_default_;";
if (!header) return "";
if (header.length == 1) return "0, " + header;
@@ -78,7 +81,7 @@ exports.patch_module_statements = function(code) {
return "";
});
imports.push("");
return has_default + imports.join("\n") + code;
return strict_mode + has_default + imports.join("\n") + code;
};
function is_error(result) {

View File

@@ -128,7 +128,7 @@ for (var i = 2; i < process.argv.length; ++i) {
var SUPPORT = function(matrix) {
for (var name in matrix) {
matrix[name] = typeof sandbox.run_code(matrix[name]) == "string";
matrix[name] = !sandbox.is_error(sandbox.run_code(matrix[name]));
}
return matrix;
}({
@@ -1824,7 +1824,13 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
declared.push(internal);
}
if (SUPPORT.class_field && rng(2)) {
s += internal || createObjectKey(recurmax, stmtDepth, canThrow);
if (internal) {
s += internal;
} else if (fixed && bug_static_class_field) {
s += getDotKey();
} else {
s += createObjectKey(recurmax, stmtDepth, canThrow);
}
if (rng(5)) {
async = bug_async_class_await && fixed && 0;
generator = false;
@@ -2110,7 +2116,7 @@ function try_beautify(code, toplevel, result, printfn, options) {
} else if (options) {
var uglified = UglifyJS.minify(beautified.code, JSON.parse(options));
var expected, actual;
if (typeof uglify_code != "string" || uglified.error) {
if (sandbox.is_error(uglify_code) || uglified.error) {
expected = uglify_code;
actual = uglified.error;
} else {
@@ -2147,7 +2153,7 @@ function log_suspects(minify_options, component) {
m[component] = o;
m.validate = true;
var result = UglifyJS.minify(original_code, m);
if (typeof uglify_code != "string") {
if (sandbox.is_error(uglify_code)) {
return !sandbox.same_stdout(uglify_code, result.error);
} else if (result.error) {
errorln("Error testing options." + component + "." + name);
@@ -2175,7 +2181,7 @@ function log_suspects_global(options, toplevel) {
m[component] = false;
m.validate = true;
var result = UglifyJS.minify(original_code, m);
if (typeof uglify_code != "string") {
if (sandbox.is_error(uglify_code)) {
return !sandbox.same_stdout(uglify_code, result.error);
} else if (result.error) {
errorln("Error testing options." + component);
@@ -2204,7 +2210,16 @@ function log(options) {
errorln();
errorln();
errorln("//-------------------------------------------------------------");
if (typeof uglify_code == "string") {
if (sandbox.is_error(uglify_code)) {
errorln("// !!! uglify failed !!!");
errorln(uglify_code);
if (original_erred) {
errorln();
errorln();
errorln("original stacktrace:");
errorln(original_result);
}
} else {
errorln("// uglified code");
try_beautify(uglify_code, toplevel, uglify_result, errorln);
errorln();
@@ -2213,15 +2228,6 @@ function log(options) {
errorln(original_result);
errorln("uglified result:");
errorln(uglify_result);
} else {
errorln("// !!! uglify failed !!!");
errorln(uglify_code);
if (errored) {
errorln();
errorln();
errorln("original stacktrace:");
errorln(original_result);
}
}
errorln("//-------------------------------------------------------------");
if (!ok) {
@@ -2426,22 +2432,23 @@ var beautify_options = {
},
};
var minify_options = require("./options.json");
if (typeof sandbox.run_code("A:if (0) B:; else B:;") != "string") {
if (sandbox.is_error(sandbox.run_code("A:if (0) B:; else B:;"))) {
minify_options.forEach(function(o) {
if (!("mangle" in o)) o.mangle = {};
if (o.mangle) o.mangle.v8 = true;
});
}
var bug_async_arrow_rest = function() {};
if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && typeof sandbox.run_code("async (a = f(...[], b)) => 0;") != "string") {
if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && sandbox.is_error(sandbox.run_code("async (a = f(...[], b)) => 0;"))) {
bug_async_arrow_rest = function(ex) {
return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter";
};
}
var bug_async_class_await = SUPPORT.async && SUPPORT.class_field && typeof sandbox.run_code("var await; async function f() { class A { static p = await; } }") != "string";
var bug_for_of_async = SUPPORT.for_await_of && typeof sandbox.run_code("var async; for (async of []);") != "string";
var bug_for_of_var = SUPPORT.for_of && SUPPORT.let && typeof sandbox.run_code("try {} catch (e) { for (var e of []); }") != "string";
if (SUPPORT.destructuring && typeof sandbox.run_code("console.log([ 1 ], {} = 2);") != "string") {
var bug_async_class_await = SUPPORT.async && SUPPORT.class_field && sandbox.is_error(sandbox.run_code("var await; async function f() { class A { static p = await; } }"));
var bug_for_of_async = SUPPORT.for_await_of && sandbox.is_error(sandbox.run_code("var async; for (async of []);"));
var bug_for_of_var = SUPPORT.for_of && SUPPORT.let && sandbox.is_error(sandbox.run_code("try {} catch (e) { for (var e of []); }"));
var bug_static_class_field = SUPPORT.class_field && sandbox.is_error(sandbox.run_code("class A { static 42; static get 42() {} }"));
if (SUPPORT.destructuring && sandbox.is_error(sandbox.run_code("console.log([ 1 ], {} = 2);"))) {
beautify_options.output.v8 = true;
minify_options.forEach(function(o) {
if (!("output" in o)) o.output = {};
@@ -2450,7 +2457,7 @@ if (SUPPORT.destructuring && typeof sandbox.run_code("console.log([ 1 ], {} = 2)
}
beautify_options = JSON.stringify(beautify_options);
minify_options = minify_options.map(JSON.stringify);
var original_code, original_result, errored;
var original_code, original_result, original_erred;
var uglify_code, uglify_result, ok;
for (var round = 1; round <= num_iterations; round++) {
process.stdout.write(round + " of " + num_iterations + "\r");
@@ -2458,7 +2465,7 @@ for (var round = 1; round <= num_iterations; round++) {
original_code = createTopLevelCode();
var orig_result = [ run_code(original_code), run_code(original_code, true) ];
if (orig_result.some(function(result, toplevel) {
if (typeof result == "string") return;
if (!sandbox.is_error(result)) return;
println();
println();
println("//=============================================================");
@@ -2480,19 +2487,20 @@ for (var round = 1; round <= num_iterations; round++) {
o.validate = true;
uglify_code = UglifyJS.minify(original_code, o);
original_result = orig_result[toplevel ? 1 : 0];
errored = typeof original_result != "string";
original_erred = sandbox.is_error(original_result);
if (!uglify_code.error) {
uglify_code = uglify_code.code;
uglify_result = run_code(uglify_code, toplevel);
ok = sandbox.same_stdout(original_result, uglify_result);
var uglify_erred = sandbox.is_error(uglify_result);
// ignore v8 parser bug
if (!ok && bug_async_arrow_rest(uglify_result)) ok = true;
if (!ok && uglify_erred && bug_async_arrow_rest(uglify_result)) ok = true;
// ignore runtime platform bugs
if (!ok && uglify_result.message == "Script execution aborted.") ok = true;
if (!ok && uglify_erred && uglify_result.message == "Script execution aborted.") ok = true;
// handle difference caused by time-outs
if (!ok) {
if (errored && is_error_timeout(original_result)) {
if (is_error_timeout(uglify_result)) {
if (original_erred && is_error_timeout(original_result)) {
if (uglify_erred && is_error_timeout(uglify_result)) {
// ignore difference in error message
ok = true;
} else {
@@ -2500,21 +2508,23 @@ for (var round = 1; round <= num_iterations; round++) {
if (!orig_result[toplevel ? 3 : 2]) orig_result[toplevel ? 3 : 2] = run_code(original_code, toplevel, 10000);
ok = sandbox.same_stdout(orig_result[toplevel ? 3 : 2], uglify_result);
}
} else if (is_error_timeout(uglify_result)) {
} else if (uglify_erred && is_error_timeout(uglify_result)) {
// ignore spurious time-outs
var waited_result = run_code(uglify_code, toplevel, 10000);
ok = sandbox.same_stdout(original_result, waited_result);
}
}
// ignore declaration order of global variables
if (!ok && !toplevel && uglify_result.name != "SyntaxError" && original_result.name != "SyntaxError") {
ok = sandbox.same_stdout(run_code(sort_globals(original_code)), run_code(sort_globals(uglify_code)));
if (!ok && !toplevel) {
if (!(original_erred && original_result.name == "SyntaxError") && !(uglify_erred && uglify_result.name == "SyntaxError")) {
ok = sandbox.same_stdout(run_code(sort_globals(original_code)), run_code(sort_globals(uglify_code)));
}
}
// ignore numerical imprecision caused by `unsafe_math`
if (!ok && o.compress && o.compress.unsafe_math && typeof original_result == typeof uglify_result) {
if (typeof original_result == "string") {
if (!ok && o.compress && o.compress.unsafe_math) {
if (typeof original_result == "string" && typeof uglify_result == "string") {
ok = fuzzy_match(original_result, uglify_result);
} else if (sandbox.is_error(original_result)) {
} else if (original_erred && uglify_erred) {
ok = original_result.name == uglify_result.name && fuzzy_match(original_result.message, uglify_result.message);
}
if (!ok) {
@@ -2523,19 +2533,19 @@ for (var round = 1; round <= num_iterations; round++) {
}
}
// ignore difference in error message caused by Temporal Dead Zone
if (!ok && errored && uglify_result.name == "ReferenceError" && original_result.name == "ReferenceError") ok = true;
if (!ok && original_erred && uglify_erred && original_result.name == "ReferenceError" && uglify_result.name == "ReferenceError") ok = true;
// ignore difference due to implicit strict-mode in `class`
if (!ok && /\bclass\b/.test(original_code)) {
var original_strict = run_code('"use strict";\n' + original_code, toplevel);
if (/^(Syntax|Type)Error$/.test(uglify_result.name)) {
ok = typeof original_strict != "string";
if (uglify_erred && /^(Syntax|Type)Error$/.test(uglify_result.name)) {
ok = sandbox.is_error(original_strict);
} else {
ok = sandbox.same_stdout(original_strict, uglify_result);
}
}
// ignore difference in error message caused by `import` symbol redeclaration
if (!ok && errored && /\bimport\b/.test(original_code)) {
if (is_error_redeclaration(uglify_result) && is_error_redeclaration(original_result)) ok = true;
if (!ok && original_erred && uglify_erred && /\bimport\b/.test(original_code)) {
if (is_error_redeclaration(original_result) && is_error_redeclaration(uglify_result)) ok = true;
}
// ignore difference due to `__proto__` assignment
if (!ok && /\b__proto__\b/.test(original_code)) {
@@ -2544,24 +2554,32 @@ for (var round = 1; round <= num_iterations; round++) {
ok = sandbox.same_stdout(original_proto, uglify_proto);
}
// ignore difference in error message caused by `in`
if (!ok && errored && is_error_in(uglify_result) && is_error_in(original_result)) ok = true;
if (!ok && original_erred && uglify_erred) {
if (is_error_in(original_result) && is_error_in(uglify_result)) ok = true;
}
// ignore difference in error message caused by spread syntax
if (!ok && errored && is_error_spread(uglify_result) && is_error_spread(original_result)) ok = true;
if (!ok && original_erred && uglify_erred) {
if (is_error_spread(original_result) && is_error_spread(uglify_result)) ok = true;
}
// ignore difference in depth of termination caused by infinite recursion
if (!ok && errored && is_error_recursion(original_result)) {
if (is_error_recursion(uglify_result) || typeof uglify_result == "string") ok = true;
if (!ok && original_erred && is_error_recursion(original_result)) {
if (!uglify_erred || is_error_recursion(uglify_result)) ok = true;
}
// ignore difference in error message caused by destructuring
if (!ok && errored && is_error_destructuring(uglify_result) && is_error_destructuring(original_result)) {
ok = true;
if (!ok && original_erred && uglify_erred) {
if (is_error_destructuring(original_result) && is_error_destructuring(uglify_result)) ok = true;
}
// ignore difference in error message caused by call on class
if (!ok && errored && is_error_class_constructor(uglify_result) && is_error_class_constructor(original_result)) {
ok = true;
if (!ok && original_erred && uglify_erred) {
if (is_error_class_constructor(original_result) && is_error_class_constructor(uglify_result)) {
ok = true;
}
}
// ignore difference in error message caused by setting getter-only property
if (!ok && errored && is_error_getter_only_property(uglify_result) && is_error_getter_only_property(original_result)) {
ok = true;
if (!ok && original_erred && uglify_erred) {
if (is_error_getter_only_property(original_result) && is_error_getter_only_property(uglify_result)) {
ok = true;
}
}
// ignore errors above when caught by try-catch
if (!ok) {
@@ -2573,7 +2591,7 @@ for (var round = 1; round <= num_iterations; round++) {
}
} else {
uglify_code = uglify_code.error;
ok = errored && uglify_code.name == original_result.name;
ok = original_erred && uglify_code.name == original_result.name;
}
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
if (!ok && isFinite(num_iterations)) {