2017-03-24 17:46:12 +00:00
|
|
|
// derived from https://github.com/qfox/uglyfuzzer by Peter van der Zee
|
|
|
|
|
"use strict";
|
|
|
|
|
|
2017-04-15 15:50:50 +00:00
|
|
|
// check both CLI and file modes of nodejs (!). See #1695 for details. and the various settings of uglify.
|
2017-03-31 09:23:50 +00:00
|
|
|
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
|
|
|
|
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
|
|
|
|
|
2020-12-28 05:32:07 +00:00
|
|
|
require("../../tools/tty");
|
2017-03-24 17:46:12 +00:00
|
|
|
|
2019-10-20 20:11:14 +00:00
|
|
|
var UglifyJS = require("../..");
|
2017-04-01 09:09:52 +00:00
|
|
|
var randomBytes = require("crypto").randomBytes;
|
2019-10-20 20:11:14 +00:00
|
|
|
var sandbox = require("../sandbox");
|
2020-02-06 02:50:59 +00:00
|
|
|
var reduce_test = require("../reduce");
|
2017-03-24 17:46:12 +00:00
|
|
|
|
2017-04-01 21:11:29 +00:00
|
|
|
var MAX_GENERATED_TOPLEVELS_PER_RUN = 1;
|
2017-03-31 09:23:50 +00:00
|
|
|
var MAX_GENERATION_RECURSION_DEPTH = 12;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
var INTERVAL_COUNT = 100;
|
|
|
|
|
|
2017-04-22 14:15:04 +00:00
|
|
|
var STMT_ARG_TO_ID = Object.create(null);
|
|
|
|
|
var STMTS_TO_USE = [];
|
|
|
|
|
function STMT_(name) {
|
|
|
|
|
return STMT_ARG_TO_ID[name] = STMTS_TO_USE.push(STMTS_TO_USE.length) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var STMT_BLOCK = STMT_("block");
|
|
|
|
|
var STMT_IF_ELSE = STMT_("ifelse");
|
|
|
|
|
var STMT_DO_WHILE = STMT_("dowhile");
|
|
|
|
|
var STMT_WHILE = STMT_("while");
|
|
|
|
|
var STMT_FOR_LOOP = STMT_("forloop");
|
2021-02-08 20:28:23 +00:00
|
|
|
var STMT_FOR_ENUM = STMT_("forenum");
|
2017-04-22 14:15:04 +00:00
|
|
|
var STMT_SEMI = STMT_("semi");
|
|
|
|
|
var STMT_EXPR = STMT_("expr");
|
|
|
|
|
var STMT_SWITCH = STMT_("switch");
|
|
|
|
|
var STMT_VAR = STMT_("var");
|
|
|
|
|
var STMT_RETURN_ETC = STMT_("stop");
|
|
|
|
|
var STMT_FUNC_EXPR = STMT_("funcexpr");
|
|
|
|
|
var STMT_TRY = STMT_("try");
|
|
|
|
|
var STMT_C = STMT_("c");
|
2017-03-31 09:23:50 +00:00
|
|
|
|
|
|
|
|
var STMT_FIRST_LEVEL_OVERRIDE = -1;
|
|
|
|
|
var STMT_SECOND_LEVEL_OVERRIDE = -1;
|
|
|
|
|
var STMT_COUNT_FROM_GLOBAL = true; // count statement depth from nearest function scope or just global scope?
|
|
|
|
|
|
|
|
|
|
var num_iterations = +process.argv[2] || 1/0;
|
|
|
|
|
var verbose = false; // log every generated test
|
|
|
|
|
var verbose_interval = false; // log every 100 generated tests
|
2017-04-23 12:05:22 +00:00
|
|
|
var use_strict = false;
|
2017-05-14 18:37:53 +00:00
|
|
|
var catch_redef = require.main === module;
|
|
|
|
|
var generate_directive = require.main === module;
|
2017-03-31 09:23:50 +00:00
|
|
|
for (var i = 2; i < process.argv.length; ++i) {
|
|
|
|
|
switch (process.argv[i]) {
|
2019-10-27 06:17:35 +00:00
|
|
|
case "-v":
|
2017-03-31 21:47:11 +00:00
|
|
|
verbose = true;
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "-V":
|
2017-03-31 21:47:11 +00:00
|
|
|
verbose_interval = true;
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "-t":
|
2017-03-31 21:47:11 +00:00
|
|
|
MAX_GENERATED_TOPLEVELS_PER_RUN = +process.argv[++i];
|
2019-10-27 06:17:35 +00:00
|
|
|
if (!MAX_GENERATED_TOPLEVELS_PER_RUN) throw new Error("Must generate at least one toplevel per run");
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "-r":
|
2017-03-31 21:47:11 +00:00
|
|
|
MAX_GENERATION_RECURSION_DEPTH = +process.argv[++i];
|
2019-10-27 06:17:35 +00:00
|
|
|
if (!MAX_GENERATION_RECURSION_DEPTH) throw new Error("Recursion depth must be at least 1");
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "-s1":
|
2017-03-31 21:47:11 +00:00
|
|
|
var name = process.argv[++i];
|
|
|
|
|
STMT_FIRST_LEVEL_OVERRIDE = STMT_ARG_TO_ID[name];
|
2019-10-27 06:17:35 +00:00
|
|
|
if (!(STMT_FIRST_LEVEL_OVERRIDE >= 0)) throw new Error("Unknown statement name; use -? to get a list");
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "-s2":
|
2017-03-31 21:47:11 +00:00
|
|
|
var name = process.argv[++i];
|
|
|
|
|
STMT_SECOND_LEVEL_OVERRIDE = STMT_ARG_TO_ID[name];
|
2019-10-27 06:17:35 +00:00
|
|
|
if (!(STMT_SECOND_LEVEL_OVERRIDE >= 0)) throw new Error("Unknown statement name; use -? to get a list");
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--no-catch-redef":
|
2017-05-14 18:37:53 +00:00
|
|
|
catch_redef = false;
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--no-directive":
|
2017-05-14 18:37:53 +00:00
|
|
|
generate_directive = false;
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--use-strict":
|
2017-04-23 12:05:22 +00:00
|
|
|
use_strict = true;
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--stmt-depth-from-func":
|
2017-03-31 21:47:11 +00:00
|
|
|
STMT_COUNT_FROM_GLOBAL = false;
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--only-stmt":
|
|
|
|
|
STMTS_TO_USE = process.argv[++i].split(",").map(function(name) {
|
|
|
|
|
return STMT_ARG_TO_ID[name];
|
|
|
|
|
});
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--without-stmt":
|
2017-03-31 21:47:11 +00:00
|
|
|
// meh. it runs once it's fine.
|
2019-10-27 06:17:35 +00:00
|
|
|
process.argv[++i].split(",").forEach(function(name) {
|
2017-03-31 21:47:11 +00:00
|
|
|
var omit = STMT_ARG_TO_ID[name];
|
2019-10-27 06:17:35 +00:00
|
|
|
STMTS_TO_USE = STMTS_TO_USE.filter(function(id) {
|
|
|
|
|
return id !== omit;
|
|
|
|
|
});
|
2017-03-31 21:47:11 +00:00
|
|
|
});
|
|
|
|
|
break;
|
2019-10-27 06:17:35 +00:00
|
|
|
case "--help":
|
|
|
|
|
case "-h":
|
|
|
|
|
case "-?":
|
|
|
|
|
println("** UglifyJS fuzzer help **");
|
|
|
|
|
println("Valid options (optional):");
|
|
|
|
|
println("<number>: generate this many cases (if used must be first arg)");
|
|
|
|
|
println("-v: print every generated test case");
|
|
|
|
|
println("-V: print every 100th generated test case");
|
|
|
|
|
println("-t <int>: generate this many toplevels per run (more take longer)");
|
|
|
|
|
println("-r <int>: maximum recursion depth for generator (higher takes longer)");
|
|
|
|
|
println("-s1 <statement name>: force the first level statement to be this one (see list below)");
|
|
|
|
|
println("-s2 <statement name>: force the second level statement to be this one (see list below)");
|
|
|
|
|
println("--no-catch-redef: do not redefine catch variables");
|
|
|
|
|
println("--no-directive: do not generate directives");
|
2017-06-09 07:56:28 +00:00
|
|
|
println('--use-strict: generate "use strict"');
|
2019-10-27 06:17:35 +00:00
|
|
|
println("--stmt-depth-from-func: reset statement depth counter at each function, counts from global otherwise");
|
|
|
|
|
println("--only-stmt <statement names>: a comma delimited white list of statements that may be generated");
|
|
|
|
|
println("--without-stmt <statement names>: a comma delimited black list of statements never to generate");
|
|
|
|
|
println("List of accepted statement names: " + Object.keys(STMT_ARG_TO_ID));
|
|
|
|
|
println("** UglifyJS fuzzer exiting **");
|
2017-03-31 21:47:11 +00:00
|
|
|
return 0;
|
|
|
|
|
default:
|
|
|
|
|
// first arg may be a number.
|
2019-10-27 06:17:35 +00:00
|
|
|
if (i > 2 || !parseInt(process.argv[i], 10)) throw new Error("Unknown argument[" + process.argv[i] + "]; see -h for help");
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-11 19:43:12 +00:00
|
|
|
var SUPPORT = function(matrix) {
|
|
|
|
|
for (var name in matrix) {
|
2022-04-18 05:03:01 +00:00
|
|
|
matrix[name] = !sandbox.is_error(sandbox.run_code(matrix[name]));
|
2020-12-11 19:43:12 +00:00
|
|
|
}
|
|
|
|
|
return matrix;
|
|
|
|
|
}({
|
2020-12-17 10:23:41 +00:00
|
|
|
arrow: "a => 0;",
|
2020-12-11 19:43:12 +00:00
|
|
|
async: "async function f(){}",
|
2021-02-07 22:44:20 +00:00
|
|
|
async_generator: "async function* f(){}",
|
2021-01-24 01:51:18 +00:00
|
|
|
bigint: "42n",
|
2020-12-11 19:43:12 +00:00
|
|
|
catch_omit_var: "try {} catch {}",
|
2021-02-23 14:55:08 +00:00
|
|
|
class: "class C { f() {} }",
|
|
|
|
|
class_field: "class C { p = 0; }",
|
|
|
|
|
class_private: "class C { #f() {} }",
|
2022-06-06 04:01:15 +00:00
|
|
|
class_static_init: "class C { static {} }",
|
2020-12-11 19:43:12 +00:00
|
|
|
computed_key: "({[0]: 0});",
|
2020-12-17 10:23:41 +00:00
|
|
|
const_block: "var a; { const a = 0; }",
|
2020-12-23 22:22:55 +00:00
|
|
|
default_value: "[ a = 0 ] = [];",
|
2020-12-11 19:43:12 +00:00
|
|
|
destructuring: "[] = [];",
|
2021-01-24 21:48:51 +00:00
|
|
|
exponentiation: "0 ** 0",
|
2021-02-08 20:28:23 +00:00
|
|
|
for_await_of: "async function f(a) { for await (a of []); }",
|
|
|
|
|
for_of: "for (var a of []);",
|
2021-02-07 22:44:20 +00:00
|
|
|
generator: "function* f(){}",
|
2020-12-11 19:43:12 +00:00
|
|
|
let: "let a;",
|
2021-03-22 20:59:43 +00:00
|
|
|
logical_assignment: "[].p ??= 0;",
|
2021-03-16 06:34:36 +00:00
|
|
|
new_target: "function f() { new.target; }",
|
2021-02-23 21:57:11 +00:00
|
|
|
nullish: "0 ?? 0",
|
2021-05-03 02:08:29 +00:00
|
|
|
optional_chaining: "0?.p",
|
2021-01-07 02:04:09 +00:00
|
|
|
rest: "var [...a] = [];",
|
|
|
|
|
rest_object: "var {...a} = {};",
|
2020-12-11 19:43:12 +00:00
|
|
|
spread: "[...[]];",
|
|
|
|
|
spread_object: "({...0});",
|
2021-02-01 02:36:45 +00:00
|
|
|
template: "``",
|
2020-12-11 19:43:12 +00:00
|
|
|
trailing_comma: "function f(a,) {}",
|
|
|
|
|
});
|
2021-03-20 22:33:45 +00:00
|
|
|
if (SUPPORT.exponentiation && sandbox.run_code("console.log(10 ** 100 === Math.pow(10, 100));") !== "true\n") {
|
|
|
|
|
SUPPORT.exponentiation = false;
|
|
|
|
|
}
|
2020-12-11 19:43:12 +00:00
|
|
|
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
var VALUES = [
|
2018-01-05 21:54:53 +00:00
|
|
|
'"a"',
|
|
|
|
|
'"b"',
|
|
|
|
|
'"c"',
|
2017-04-02 20:00:33 +00:00
|
|
|
'""',
|
2019-10-27 06:17:35 +00:00
|
|
|
"true",
|
|
|
|
|
"false",
|
|
|
|
|
" /[a2][^e]+$/ ",
|
|
|
|
|
"(-1)",
|
|
|
|
|
"(-2)",
|
|
|
|
|
"(-3)",
|
|
|
|
|
"(-4)",
|
|
|
|
|
"(-5)",
|
|
|
|
|
"0",
|
|
|
|
|
"1",
|
|
|
|
|
"2",
|
|
|
|
|
"3",
|
|
|
|
|
"4",
|
|
|
|
|
"5",
|
|
|
|
|
"22",
|
2021-01-24 21:48:51 +00:00
|
|
|
"(-0)", // 0/-0 !== 0
|
2019-10-27 06:17:35 +00:00
|
|
|
"23..toString()",
|
|
|
|
|
"24 .toString()",
|
|
|
|
|
"25. ",
|
|
|
|
|
"0x26.toString()",
|
|
|
|
|
"NaN",
|
|
|
|
|
"null",
|
2021-03-03 07:42:46 +00:00
|
|
|
"Infinity",
|
|
|
|
|
"undefined",
|
2019-10-27 06:17:35 +00:00
|
|
|
"[]",
|
|
|
|
|
"[,0][1]", // an array with elisions... but this is always false
|
|
|
|
|
"([,0].length === 2)", // an array with elisions... this is always true
|
|
|
|
|
"({})", // wrapped the object causes too many syntax errors in statements
|
2017-03-31 09:23:50 +00:00
|
|
|
'"foo"',
|
2017-04-01 18:08:46 +00:00
|
|
|
'"bar"',
|
|
|
|
|
'"undefined"',
|
|
|
|
|
'"object"',
|
|
|
|
|
'"number"',
|
|
|
|
|
'"function"',
|
2019-10-27 06:17:35 +00:00
|
|
|
"this",
|
2017-04-01 18:08:46 +00:00
|
|
|
];
|
2021-04-02 20:31:29 +00:00
|
|
|
VALUES = VALUES.concat(VALUES);
|
|
|
|
|
VALUES = VALUES.concat(VALUES);
|
2021-04-06 13:34:27 +00:00
|
|
|
VALUES = VALUES.concat(VALUES);
|
2021-01-24 01:51:18 +00:00
|
|
|
if (SUPPORT.bigint) VALUES = VALUES.concat([
|
2021-01-24 21:48:51 +00:00
|
|
|
"(!0o644n)",
|
2021-01-24 01:51:18 +00:00
|
|
|
"([3n][0] > 2)",
|
|
|
|
|
"(-42n).toString()",
|
|
|
|
|
"Number(0XDEADn << 16n | 0xbeefn)",
|
|
|
|
|
]);
|
2021-04-02 20:31:29 +00:00
|
|
|
VALUES = VALUES.concat(VALUES);
|
|
|
|
|
VALUES = VALUES.concat(VALUES);
|
|
|
|
|
VALUES = VALUES.concat(VALUES);
|
2021-04-06 13:34:27 +00:00
|
|
|
VALUES = VALUES.concat(VALUES);
|
2021-04-02 20:31:29 +00:00
|
|
|
VALUES.push("import.meta");
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
2020-06-07 21:23:23 +00:00
|
|
|
var BINARY_OPS = [
|
2019-10-27 06:17:35 +00:00
|
|
|
" + ", // spaces needed to disambiguate with ++ cases (could otherwise cause syntax errors)
|
|
|
|
|
" - ",
|
|
|
|
|
"/",
|
|
|
|
|
"*",
|
|
|
|
|
"&",
|
|
|
|
|
"|",
|
|
|
|
|
"^",
|
|
|
|
|
"<",
|
|
|
|
|
"<=",
|
|
|
|
|
">",
|
|
|
|
|
">=",
|
|
|
|
|
"==",
|
|
|
|
|
"===",
|
|
|
|
|
"!=",
|
|
|
|
|
"!==",
|
|
|
|
|
"<<",
|
|
|
|
|
">>",
|
|
|
|
|
">>>",
|
|
|
|
|
"%",
|
|
|
|
|
"&&",
|
|
|
|
|
"||",
|
2020-06-07 21:23:23 +00:00
|
|
|
"^",
|
|
|
|
|
",",
|
|
|
|
|
];
|
|
|
|
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
2021-02-23 21:57:11 +00:00
|
|
|
if (SUPPORT.nullish) BINARY_OPS.push("??");
|
2020-06-07 21:23:23 +00:00
|
|
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
|
|
|
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
2021-01-24 21:48:51 +00:00
|
|
|
if (SUPPORT.exponentiation) BINARY_OPS.push("**");
|
2020-06-07 21:23:23 +00:00
|
|
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
2020-06-29 01:06:23 +00:00
|
|
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
2022-06-12 02:01:54 +00:00
|
|
|
BINARY_OPS.push(" in ", " instanceof ");
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
2021-03-20 22:33:45 +00:00
|
|
|
var ASSIGNMENTS = [ "=" ];
|
|
|
|
|
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
|
|
|
|
ASSIGNMENTS.push("+=");
|
|
|
|
|
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
|
|
|
|
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
|
|
|
|
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
|
|
|
|
ASSIGNMENTS = ASSIGNMENTS.concat([
|
2019-10-27 06:17:35 +00:00
|
|
|
"-=",
|
|
|
|
|
"*=",
|
|
|
|
|
"/=",
|
2021-03-15 13:53:48 +00:00
|
|
|
"%=",
|
2019-10-27 06:17:35 +00:00
|
|
|
"&=",
|
|
|
|
|
"|=",
|
|
|
|
|
"^=",
|
|
|
|
|
"<<=",
|
|
|
|
|
">>=",
|
|
|
|
|
">>>=",
|
2021-03-20 22:33:45 +00:00
|
|
|
]);
|
2021-03-22 20:59:43 +00:00
|
|
|
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
|
|
|
|
if (SUPPORT.exponentiation) ASSIGNMENTS.push("**=");
|
|
|
|
|
if (SUPPORT.logical_assignment) ASSIGNMENTS = ASSIGNMENTS.concat([
|
|
|
|
|
"&&=",
|
|
|
|
|
"||=",
|
|
|
|
|
"??=",
|
|
|
|
|
]);
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
2017-04-07 10:47:30 +00:00
|
|
|
var UNARY_SAFE = [
|
2019-10-27 06:17:35 +00:00
|
|
|
"+",
|
|
|
|
|
"-",
|
|
|
|
|
"~",
|
|
|
|
|
"!",
|
|
|
|
|
"void ",
|
|
|
|
|
"delete ",
|
2017-04-07 10:47:30 +00:00
|
|
|
];
|
|
|
|
|
var UNARY_POSTFIX = [
|
2019-10-27 06:17:35 +00:00
|
|
|
"++",
|
|
|
|
|
"--",
|
2017-04-07 10:47:30 +00:00
|
|
|
];
|
|
|
|
|
var UNARY_PREFIX = UNARY_POSTFIX.concat(UNARY_SAFE);
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
|
|
|
|
var NO_COMMA = true;
|
2017-03-31 09:23:50 +00:00
|
|
|
var COMMA_OK = false;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
var MAYBE = true;
|
2017-03-31 09:23:50 +00:00
|
|
|
var MANDATORY = false;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
var CAN_THROW = true;
|
|
|
|
|
var CANNOT_THROW = false;
|
|
|
|
|
var CAN_BREAK = true;
|
2017-03-31 09:23:50 +00:00
|
|
|
var CANNOT_BREAK = false;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
var CAN_CONTINUE = true;
|
2017-03-31 09:23:50 +00:00
|
|
|
var CANNOT_CONTINUE = false;
|
|
|
|
|
var CAN_RETURN = false;
|
|
|
|
|
var CANNOT_RETURN = true;
|
2017-12-20 15:52:18 +00:00
|
|
|
var NO_DEFUN = false;
|
|
|
|
|
var DEFUN_OK = true;
|
2017-03-31 09:23:50 +00:00
|
|
|
var DONT_STORE = true;
|
2020-10-11 17:18:57 +00:00
|
|
|
var NO_CONST = true;
|
2020-11-08 05:17:53 +00:00
|
|
|
var NO_DUPLICATE = true;
|
2021-02-23 14:55:08 +00:00
|
|
|
var NO_LAMBDA = true;
|
|
|
|
|
var NO_TEMPLATE = true;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
|
|
|
|
var VAR_NAMES = [
|
2019-10-27 06:17:35 +00:00
|
|
|
"a",
|
|
|
|
|
"a",
|
|
|
|
|
"a",
|
|
|
|
|
"a",
|
|
|
|
|
"b",
|
|
|
|
|
"b",
|
|
|
|
|
"b",
|
|
|
|
|
"b",
|
|
|
|
|
"c", // prevent redeclaring this, avoid assigning to this
|
|
|
|
|
"foo",
|
|
|
|
|
"foo",
|
|
|
|
|
"bar",
|
|
|
|
|
"bar",
|
|
|
|
|
"undefined",
|
|
|
|
|
"NaN",
|
|
|
|
|
"Infinity",
|
|
|
|
|
"arguments",
|
2020-12-06 21:22:40 +00:00
|
|
|
"async",
|
|
|
|
|
"await",
|
2021-10-20 18:14:29 +00:00
|
|
|
"let",
|
2021-02-10 12:40:57 +00:00
|
|
|
"yield",
|
2017-04-07 10:47:30 +00:00
|
|
|
];
|
2017-03-31 09:23:50 +00:00
|
|
|
var INITIAL_NAMES_LEN = VAR_NAMES.length;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
|
|
|
|
var TYPEOF_OUTCOMES = [
|
2019-10-27 06:17:35 +00:00
|
|
|
"function",
|
|
|
|
|
"undefined",
|
|
|
|
|
"string",
|
|
|
|
|
"number",
|
|
|
|
|
"object",
|
|
|
|
|
"boolean",
|
|
|
|
|
"special",
|
|
|
|
|
"unknown",
|
|
|
|
|
"symbol",
|
|
|
|
|
"crap",
|
|
|
|
|
];
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
|
2020-11-25 01:33:42 +00:00
|
|
|
var avoid_vars = [];
|
2021-10-20 18:14:29 +00:00
|
|
|
var block_vars = [ "let" ];
|
2021-02-23 14:55:08 +00:00
|
|
|
var lambda_vars = [];
|
2017-05-14 18:37:53 +00:00
|
|
|
var unique_vars = [];
|
2021-02-23 14:55:08 +00:00
|
|
|
var classes = [];
|
2021-05-13 11:57:36 +00:00
|
|
|
var allow_this = true;
|
2020-12-06 21:22:40 +00:00
|
|
|
var async = false;
|
2021-03-07 20:25:56 +00:00
|
|
|
var has_await = false;
|
2021-02-26 20:56:34 +00:00
|
|
|
var export_default = false;
|
2021-02-07 22:44:20 +00:00
|
|
|
var generator = false;
|
2017-03-31 09:23:50 +00:00
|
|
|
var loops = 0;
|
|
|
|
|
var funcs = 0;
|
2021-02-23 14:55:08 +00:00
|
|
|
var clazz = 0;
|
2021-03-03 07:42:46 +00:00
|
|
|
var imports = 0;
|
2021-02-23 14:55:08 +00:00
|
|
|
var in_class = 0;
|
2017-12-20 15:52:18 +00:00
|
|
|
var called = Object.create(null);
|
2017-04-22 14:15:04 +00:00
|
|
|
var labels = 10000;
|
2017-03-26 10:18:44 +00:00
|
|
|
|
2022-08-11 19:55:54 +00:00
|
|
|
function rng(limit) {
|
2017-04-01 21:11:29 +00:00
|
|
|
var r = randomBytes(2).readUInt16LE(0) / 65536;
|
2022-08-11 19:55:54 +00:00
|
|
|
return Math.floor(limit * r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_num(max) {
|
|
|
|
|
if (rng(max + 1) == 0) return 0;
|
|
|
|
|
var i = 1;
|
|
|
|
|
while (i < max && rng(2)) i++;
|
|
|
|
|
return i;
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2017-04-23 12:05:22 +00:00
|
|
|
function strictMode() {
|
2019-10-27 06:17:35 +00:00
|
|
|
return use_strict && rng(4) == 0 ? '"use strict";' : "";
|
2017-04-23 12:05:22 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-26 20:56:34 +00:00
|
|
|
function appendExport(stmtDepth, allowDefault) {
|
2021-02-28 18:27:41 +00:00
|
|
|
if (SUPPORT.destructuring && stmtDepth == 1 && rng(20) == 0) {
|
2021-02-26 20:56:34 +00:00
|
|
|
if (allowDefault && !export_default && rng(5) == 0) {
|
|
|
|
|
export_default = true;
|
|
|
|
|
return "export default ";
|
|
|
|
|
}
|
|
|
|
|
return "export ";
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 07:42:46 +00:00
|
|
|
function mayDefer(code) {
|
2021-03-07 20:25:56 +00:00
|
|
|
if (SUPPORT.arrow && rng(200) == 0) {
|
|
|
|
|
has_await = true;
|
|
|
|
|
return "void setImmediate(() => (" + code + "))";
|
|
|
|
|
}
|
|
|
|
|
return code;
|
2021-03-03 07:42:46 +00:00
|
|
|
}
|
|
|
|
|
|
2017-03-31 09:23:50 +00:00
|
|
|
function createTopLevelCode() {
|
2017-05-14 18:37:53 +00:00
|
|
|
VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list
|
2021-10-20 18:14:29 +00:00
|
|
|
block_vars.length = 1;
|
2021-02-23 14:55:08 +00:00
|
|
|
lambda_vars.length = 0;
|
2017-05-14 18:37:53 +00:00
|
|
|
unique_vars.length = 0;
|
2021-02-23 14:55:08 +00:00
|
|
|
classes.length = 0;
|
2021-05-13 11:57:36 +00:00
|
|
|
allow_this = true;
|
2022-06-06 03:52:01 +00:00
|
|
|
async = SUPPORT.async && rng(200) == 0;
|
2021-03-07 20:25:56 +00:00
|
|
|
has_await = false;
|
2021-02-26 20:56:34 +00:00
|
|
|
export_default = false;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = false;
|
2017-05-14 18:37:53 +00:00
|
|
|
loops = 0;
|
|
|
|
|
funcs = 0;
|
2021-02-23 14:55:08 +00:00
|
|
|
clazz = 0;
|
2021-03-03 07:42:46 +00:00
|
|
|
imports = 0;
|
2022-06-06 03:52:01 +00:00
|
|
|
in_class = async;
|
2017-12-20 15:52:18 +00:00
|
|
|
called = Object.create(null);
|
2021-02-26 20:56:34 +00:00
|
|
|
var s = [
|
2017-04-23 12:05:22 +00:00
|
|
|
strictMode(),
|
2021-02-26 20:56:34 +00:00
|
|
|
appendExport(1) + "var _calls_ = 10, a = 100, b = 10, c = 0;",
|
|
|
|
|
];
|
|
|
|
|
createBlockVariables(MAX_GENERATION_RECURSION_DEPTH, 0, CANNOT_THROW, function(defns) {
|
|
|
|
|
s.push(defns());
|
|
|
|
|
if (rng(2)) {
|
|
|
|
|
s.push(createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0));
|
|
|
|
|
} else {
|
2022-08-09 16:20:20 +00:00
|
|
|
s.push(createFunctions(MAX_GENERATED_TOPLEVELS_PER_RUN, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0));
|
2021-02-26 20:56:34 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
2021-03-07 20:25:56 +00:00
|
|
|
var log = "console.log(null, a, b, c, Infinity, NaN, undefined)";
|
|
|
|
|
if (SUPPORT.arrow && has_await && rng(20) == 0) log = "setImmediate(() => " + log + ")";
|
|
|
|
|
s.push(log + ";");
|
2021-02-26 20:56:34 +00:00
|
|
|
return s.join("\n");
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2017-12-20 15:52:18 +00:00
|
|
|
function createFunctions(n, recurmax, allowDefun, canThrow, stmtDepth) {
|
2019-10-27 06:17:35 +00:00
|
|
|
if (--recurmax < 0) { return ";"; }
|
|
|
|
|
var s = "";
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(n - 1) + 1; --i >= 0;) {
|
2019-10-27 06:17:35 +00:00
|
|
|
s += createFunction(recurmax, allowDefun, canThrow, stmtDepth) + "\n";
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
return s;
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-07 02:07:34 +00:00
|
|
|
function addTrailingComma(list) {
|
2020-12-11 19:43:12 +00:00
|
|
|
return SUPPORT.trailing_comma && list && rng(20) == 0 ? list + "," : list;
|
2020-12-07 02:07:34 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-07 22:44:20 +00:00
|
|
|
function createParams(was_async, was_generator, noDuplicate) {
|
2020-12-17 10:23:41 +00:00
|
|
|
var save_async = async;
|
2021-04-23 23:17:30 +00:00
|
|
|
if (!async) async = was_async;
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
2021-04-23 23:17:30 +00:00
|
|
|
if (!generator) generator = was_generator;
|
2020-11-08 05:17:53 +00:00
|
|
|
var len = unique_vars.length;
|
2017-04-07 10:47:30 +00:00
|
|
|
var params = [];
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(3); --i >= 0;) {
|
2020-11-08 05:17:53 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
2021-02-23 14:55:08 +00:00
|
|
|
if (noDuplicate || in_class) unique_vars.push(name);
|
2020-11-08 05:17:53 +00:00
|
|
|
params.push(name);
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
2020-11-08 05:17:53 +00:00
|
|
|
unique_vars.length = len;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-17 10:23:41 +00:00
|
|
|
async = save_async;
|
2020-12-07 02:07:34 +00:00
|
|
|
return addTrailingComma(params.join(", "));
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-01 09:20:13 +00:00
|
|
|
function createArgs(recurmax, stmtDepth, canThrow, noTemplate) {
|
2020-12-05 21:19:31 +00:00
|
|
|
recurmax--;
|
2021-02-01 09:20:13 +00:00
|
|
|
if (SUPPORT.template && !noTemplate && rng(20) == 0) return createTemplateLiteral(recurmax, stmtDepth, canThrow);
|
2017-04-07 10:47:30 +00:00
|
|
|
var args = [];
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(3); --i >= 0;) switch (SUPPORT.spread ? rng(50) : 3) {
|
2020-12-05 21:19:31 +00:00
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
var name = getVarName();
|
2021-02-23 14:55:08 +00:00
|
|
|
if (canThrow && rng(20) == 0) {
|
2020-12-05 21:19:31 +00:00
|
|
|
args.push("..." + name);
|
|
|
|
|
} else {
|
|
|
|
|
args.push('...("" + ' + name + ")");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
args.push("..." + createArrayLiteral(recurmax, stmtDepth, canThrow));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2020-12-17 10:23:41 +00:00
|
|
|
args.push(rng(2) ? createValue() : createExpression(recurmax, NO_COMMA, stmtDepth, canThrow));
|
2020-12-05 21:19:31 +00:00
|
|
|
break;
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
2021-02-01 09:20:13 +00:00
|
|
|
return "(" + addTrailingComma(args.join(", ")) + ")";
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-07 22:44:20 +00:00
|
|
|
function createAssignmentPairs(recurmax, stmtDepth, canThrow, nameLenBefore, was_async, was_generator) {
|
2020-11-17 00:01:24 +00:00
|
|
|
var avoid = [];
|
|
|
|
|
var len = unique_vars.length;
|
2020-12-23 22:22:55 +00:00
|
|
|
var pairs = createPairs(recurmax, !nameLenBefore);
|
2021-01-07 02:04:09 +00:00
|
|
|
pairs.has_rest = nameLenBefore && convertToRest(pairs.names);
|
2020-11-17 00:01:24 +00:00
|
|
|
unique_vars.length = len;
|
|
|
|
|
return pairs;
|
|
|
|
|
|
2021-01-23 19:37:52 +00:00
|
|
|
function mapShuffled(values, fn) {
|
2021-01-24 21:48:51 +00:00
|
|
|
var declare_only = [];
|
|
|
|
|
var side_effects = [];
|
2021-01-23 19:37:52 +00:00
|
|
|
values.forEach(function(value, index) {
|
|
|
|
|
value = fn(value, index);
|
2021-02-23 14:55:08 +00:00
|
|
|
if (/]:|=/.test(value) ? canThrow && rng(20) == 0 : rng(5)) {
|
2021-01-24 21:48:51 +00:00
|
|
|
declare_only.splice(rng(declare_only.length + 1), 0, value);
|
2021-02-23 14:55:08 +00:00
|
|
|
} else if (canThrow && rng(20) == 0) {
|
2021-01-24 21:48:51 +00:00
|
|
|
side_effects.splice(rng(side_effects.length + 1), 0, value);
|
2021-01-23 19:37:52 +00:00
|
|
|
} else {
|
2021-01-24 21:48:51 +00:00
|
|
|
side_effects.push(value);
|
2021-01-23 19:37:52 +00:00
|
|
|
}
|
|
|
|
|
});
|
2021-01-24 21:48:51 +00:00
|
|
|
return declare_only.concat(side_effects);
|
2021-01-22 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2021-01-07 02:04:09 +00:00
|
|
|
function convertToRest(names) {
|
|
|
|
|
var last = names.length - 1;
|
|
|
|
|
if (last >= 0 && SUPPORT.rest && rng(20) == 0) {
|
|
|
|
|
var name = names[last];
|
|
|
|
|
if (name && name.indexOf("=") < 0) {
|
|
|
|
|
if (/^[[{]/.test(name)) name = "[ " + name + " ]";
|
|
|
|
|
names[last] = "..." + name;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 22:22:55 +00:00
|
|
|
function fill(nameFn, valueFn) {
|
2020-12-06 21:22:40 +00:00
|
|
|
var save_async = async;
|
2020-12-23 22:22:55 +00:00
|
|
|
if (was_async != null) {
|
|
|
|
|
async = false;
|
|
|
|
|
if (save_async || was_async) addAvoidVar("await");
|
|
|
|
|
}
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
|
|
|
|
if (was_generator != null) {
|
|
|
|
|
generator = false;
|
|
|
|
|
if (save_generator || was_generator) addAvoidVar("yield");
|
|
|
|
|
}
|
2020-12-23 22:22:55 +00:00
|
|
|
avoid.forEach(addAvoidVar);
|
2020-12-17 10:23:41 +00:00
|
|
|
var save_vars = nameLenBefore && VAR_NAMES.splice(nameLenBefore);
|
2020-12-23 22:22:55 +00:00
|
|
|
if (nameFn) nameFn();
|
2021-02-07 22:44:20 +00:00
|
|
|
if (was_generator != null) {
|
|
|
|
|
generator = was_generator;
|
|
|
|
|
if (save_generator || was_generator) removeAvoidVar("yield");
|
|
|
|
|
}
|
2020-12-23 22:22:55 +00:00
|
|
|
if (was_async != null) {
|
|
|
|
|
async = was_async;
|
|
|
|
|
if (save_async || was_async) removeAvoidVar("await");
|
|
|
|
|
}
|
|
|
|
|
if (valueFn) valueFn();
|
2020-12-17 10:23:41 +00:00
|
|
|
if (save_vars) [].push.apply(VAR_NAMES, save_vars);
|
2020-12-23 22:22:55 +00:00
|
|
|
avoid.forEach(removeAvoidVar);
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-06 21:22:40 +00:00
|
|
|
async = save_async;
|
2020-12-23 22:22:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createAssignmentValue(recurmax) {
|
|
|
|
|
return nameLenBefore && rng(2) ? createValue() : createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createDefaultValue(recurmax, noDefault) {
|
|
|
|
|
return !noDefault && SUPPORT.default_value && rng(20) == 0 ? " = " + createAssignmentValue(recurmax) : "";
|
2020-11-17 00:01:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createKey(recurmax, keys) {
|
|
|
|
|
var key;
|
|
|
|
|
do {
|
|
|
|
|
key = createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
} while (keys.indexOf(key) >= 0);
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-17 10:23:41 +00:00
|
|
|
function createName() {
|
|
|
|
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
|
|
|
|
var save_async = async;
|
2021-04-23 23:17:30 +00:00
|
|
|
if (!async) async = was_async;
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
2021-04-23 23:17:30 +00:00
|
|
|
if (!generator) generator = was_generator;
|
2020-12-17 10:23:41 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-17 10:23:41 +00:00
|
|
|
async = save_async;
|
|
|
|
|
unique_vars.length -= 6;
|
|
|
|
|
avoid.push(name);
|
|
|
|
|
unique_vars.push(name);
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 22:22:55 +00:00
|
|
|
function createPairs(recurmax, noDefault) {
|
2020-11-17 00:01:24 +00:00
|
|
|
var names = [], values = [];
|
|
|
|
|
var m = rng(4), n = rng(4);
|
2020-12-17 10:23:41 +00:00
|
|
|
if (!nameLenBefore) m = Math.max(m, n, 1);
|
2020-11-17 00:01:24 +00:00
|
|
|
for (var i = Math.max(m, n); --i >= 0;) {
|
|
|
|
|
if (i < m && i < n) {
|
2020-12-23 22:22:55 +00:00
|
|
|
createDestructured(recurmax, noDefault, names, values);
|
|
|
|
|
} else if (i < m) {
|
|
|
|
|
var name = createName();
|
|
|
|
|
fill(function() {
|
|
|
|
|
names.unshift(name + createDefaultValue(recurmax, noDefault));
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
fill(null, function() {
|
|
|
|
|
values.unshift(createAssignmentValue(recurmax));
|
|
|
|
|
});
|
2020-11-17 00:01:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
names: names,
|
|
|
|
|
values: values,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 22:22:55 +00:00
|
|
|
function createDestructured(recurmax, noDefault, names, values) {
|
2020-11-17 00:01:24 +00:00
|
|
|
switch (rng(20)) {
|
|
|
|
|
case 0:
|
|
|
|
|
if (--recurmax < 0) {
|
|
|
|
|
names.unshift("[]");
|
|
|
|
|
values.unshift('""');
|
|
|
|
|
} else {
|
|
|
|
|
var pairs = createPairs(recurmax);
|
2020-12-23 22:22:55 +00:00
|
|
|
var default_value;
|
|
|
|
|
fill(function() {
|
|
|
|
|
default_value = createDefaultValue(recurmax, noDefault);
|
|
|
|
|
}, function() {
|
|
|
|
|
while (!rng(10)) {
|
|
|
|
|
var index = rng(pairs.names.length + 1);
|
|
|
|
|
pairs.names.splice(index, 0, "");
|
|
|
|
|
if (index < pairs.values.length) {
|
|
|
|
|
pairs.values.splice(index, 0, rng(2) ? createAssignmentValue(recurmax) : "");
|
|
|
|
|
} else switch (rng(5)) {
|
2021-01-07 02:04:09 +00:00
|
|
|
case 0:
|
2020-12-23 22:22:55 +00:00
|
|
|
pairs.values[index] = createAssignmentValue(recurmax);
|
2021-01-07 02:04:09 +00:00
|
|
|
case 1:
|
2020-12-23 22:22:55 +00:00
|
|
|
pairs.values.length = index + 1;
|
|
|
|
|
}
|
2020-12-07 02:07:34 +00:00
|
|
|
}
|
2021-01-07 02:04:09 +00:00
|
|
|
convertToRest(pairs.names);
|
2020-12-23 22:22:55 +00:00
|
|
|
names.unshift("[ " + pairs.names.join(", ") + " ]" + default_value);
|
|
|
|
|
values.unshift("[ " + pairs.values.join(", ") + " ]");
|
|
|
|
|
});
|
2020-11-17 00:01:24 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
if (--recurmax < 0) {
|
|
|
|
|
names.unshift("{}");
|
|
|
|
|
values.unshift('""');
|
|
|
|
|
} else {
|
|
|
|
|
var pairs = createPairs(recurmax);
|
|
|
|
|
var keys = [];
|
|
|
|
|
pairs.names.forEach(function(name, index) {
|
|
|
|
|
if (/^[[{]/.test(name)) {
|
|
|
|
|
var key;
|
|
|
|
|
do {
|
|
|
|
|
key = KEYS[rng(KEYS.length)];
|
|
|
|
|
} while (keys.indexOf(key) >= 0);
|
|
|
|
|
keys[index] = key;
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-12-23 22:22:55 +00:00
|
|
|
fill(function() {
|
2021-01-22 18:00:26 +00:00
|
|
|
var last = pairs.names.length - 1, rest;
|
|
|
|
|
if (last >= 0 && !(last in keys) && SUPPORT.rest_object && rng(20) == 0) {
|
|
|
|
|
rest = pairs.names.pop();
|
|
|
|
|
if (!/=/.test(rest)) rest = "..." + rest;
|
|
|
|
|
}
|
|
|
|
|
var s = mapShuffled(pairs.names, function(name, index) {
|
2021-01-07 02:04:09 +00:00
|
|
|
if (index in keys) return keys[index] + ": " + name;
|
|
|
|
|
return rng(10) == 0 ? name : createKey(recurmax, keys) + ": " + name;
|
2021-01-22 18:00:26 +00:00
|
|
|
});
|
|
|
|
|
if (rest) {
|
|
|
|
|
s.push(rest);
|
|
|
|
|
s = s.join(", ");
|
|
|
|
|
} else {
|
|
|
|
|
s = addTrailingComma(s.join(", "));
|
|
|
|
|
}
|
2021-01-07 02:04:09 +00:00
|
|
|
names.unshift("{ " + s + " }" + createDefaultValue(recurmax, noDefault));
|
2020-12-23 22:22:55 +00:00
|
|
|
}, function() {
|
2021-01-22 18:00:26 +00:00
|
|
|
values.unshift("{ " + addTrailingComma(mapShuffled(pairs.values, function(value, index) {
|
2020-12-23 22:22:55 +00:00
|
|
|
var key = index in keys ? keys[index] : createKey(recurmax, keys);
|
|
|
|
|
return key + ": " + value;
|
|
|
|
|
}).join(", ")) + " }");
|
|
|
|
|
});
|
2020-11-17 00:01:24 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2020-12-23 22:22:55 +00:00
|
|
|
var name = createName();
|
|
|
|
|
fill(function() {
|
|
|
|
|
names.unshift(name + createDefaultValue(recurmax, noDefault));
|
|
|
|
|
}, function() {
|
|
|
|
|
values.unshift(createAssignmentValue(recurmax));
|
|
|
|
|
});
|
2020-11-17 00:01:24 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-14 18:37:53 +00:00
|
|
|
function filterDirective(s) {
|
2019-10-27 06:17:35 +00:00
|
|
|
if (!generate_directive && !s[1] && /\("/.test(s[2])) s[2] = ";" + s[2];
|
2017-05-14 18:37:53 +00:00
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-11 17:18:57 +00:00
|
|
|
function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
2021-02-26 20:56:34 +00:00
|
|
|
++stmtDepth;
|
2020-10-11 17:18:57 +00:00
|
|
|
var block_len = block_vars.length;
|
2021-02-23 14:55:08 +00:00
|
|
|
var class_len = classes.length;
|
2020-12-17 10:23:41 +00:00
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
2020-10-11 17:18:57 +00:00
|
|
|
var consts = [];
|
2020-10-19 00:32:39 +00:00
|
|
|
var lets = [];
|
2020-10-11 17:18:57 +00:00
|
|
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
|
|
|
|
while (!rng(block_vars.length > block_len ? 10 : 100)) {
|
2020-12-17 10:23:41 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
2020-12-11 19:43:12 +00:00
|
|
|
if (SUPPORT.let && rng(2)) {
|
2020-10-19 00:32:39 +00:00
|
|
|
lets.push(name);
|
2020-12-11 19:43:12 +00:00
|
|
|
} else {
|
|
|
|
|
consts.push(name);
|
2020-10-19 00:32:39 +00:00
|
|
|
}
|
2020-10-11 17:18:57 +00:00
|
|
|
block_vars.push(name);
|
|
|
|
|
}
|
|
|
|
|
unique_vars.length -= 6;
|
|
|
|
|
fn(function() {
|
2020-12-23 22:22:55 +00:00
|
|
|
consts.forEach(addAvoidVar);
|
|
|
|
|
lets.forEach(addAvoidVar);
|
2021-02-23 14:55:08 +00:00
|
|
|
var s = [];
|
2021-03-07 20:25:56 +00:00
|
|
|
if (SUPPORT.class) while (rng(200) == 0) {
|
2021-02-23 14:55:08 +00:00
|
|
|
var name = "C" + clazz++;
|
|
|
|
|
classes.push(name);
|
2021-02-26 20:56:34 +00:00
|
|
|
s.push(appendExport(stmtDepth, true) + createClassLiteral(recurmax, stmtDepth, canThrow, name));
|
2021-02-23 14:55:08 +00:00
|
|
|
}
|
2020-10-19 00:32:39 +00:00
|
|
|
if (rng(2)) {
|
2021-02-23 14:55:08 +00:00
|
|
|
s.push(createDefinitions("const", consts), createDefinitions("let", lets));
|
2020-10-19 00:32:39 +00:00
|
|
|
} else {
|
2021-02-23 14:55:08 +00:00
|
|
|
s.push(createDefinitions("let", lets), createDefinitions("const", consts));
|
2020-10-11 17:18:57 +00:00
|
|
|
}
|
2021-02-23 14:55:08 +00:00
|
|
|
s.push("");
|
|
|
|
|
return s.join("\n");
|
2020-10-11 17:18:57 +00:00
|
|
|
});
|
2020-12-17 10:23:41 +00:00
|
|
|
VAR_NAMES.length = nameLenBefore;
|
2021-02-23 14:55:08 +00:00
|
|
|
classes.length = class_len;
|
2020-10-11 17:18:57 +00:00
|
|
|
block_vars.length = block_len;
|
2020-10-19 00:32:39 +00:00
|
|
|
|
|
|
|
|
function createDefinitions(type, names) {
|
|
|
|
|
if (!names.length) return "";
|
2021-02-26 20:56:34 +00:00
|
|
|
var s = appendExport(stmtDepth) + type + " ";
|
2020-12-11 19:43:12 +00:00
|
|
|
switch (SUPPORT.destructuring ? rng(10) : 2) {
|
2020-11-17 00:01:24 +00:00
|
|
|
case 0:
|
|
|
|
|
while (!rng(10)) names.splice(rng(names.length + 1), 0, "");
|
|
|
|
|
s += "[ " + names.join(", ") + " ] = [ " + names.map(function() {
|
|
|
|
|
return rng(10) ? createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) : "";
|
|
|
|
|
}).join(", ") + " ];";
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
var keys = [];
|
|
|
|
|
s += "{ " + names.map(function(name, i) {
|
|
|
|
|
var key = createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
if (!/\[/.test(key)) keys[i] = key;
|
|
|
|
|
return key + ": " + name;
|
|
|
|
|
}).join(", ") + "} = { " + names.map(function(name, i) {
|
|
|
|
|
var key = i in keys ? keys[i] : createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
return key + ": " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
|
|
|
|
}).join(", ") + "};";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2020-11-25 01:33:42 +00:00
|
|
|
s += names.map(function(name) {
|
2020-11-17 00:01:24 +00:00
|
|
|
if (type == "let" && !rng(10)) {
|
2020-12-23 22:22:55 +00:00
|
|
|
removeAvoidVar(name);
|
2020-11-17 00:01:24 +00:00
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
var value = createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
2020-12-23 22:22:55 +00:00
|
|
|
removeAvoidVar(name);
|
2020-11-17 00:01:24 +00:00
|
|
|
return name + " = " + value;
|
|
|
|
|
}).join(", ") + ";";
|
2020-12-17 10:23:41 +00:00
|
|
|
names.length = 0;
|
2020-11-17 00:01:24 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-23 22:22:55 +00:00
|
|
|
names.forEach(removeAvoidVar);
|
2020-10-19 00:32:39 +00:00
|
|
|
return s;
|
|
|
|
|
}
|
2020-10-11 17:18:57 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-17 10:23:41 +00:00
|
|
|
function mayCreateBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
|
|
|
|
if (SUPPORT.const_block) {
|
|
|
|
|
createBlockVariables(recurmax, stmtDepth, canThrow, fn);
|
|
|
|
|
} else {
|
|
|
|
|
fn(function() {
|
|
|
|
|
return "";
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-06 21:22:40 +00:00
|
|
|
function makeFunction(name) {
|
2021-02-23 14:55:08 +00:00
|
|
|
lambda_vars.push(name);
|
2021-02-07 22:44:20 +00:00
|
|
|
if (generator) {
|
|
|
|
|
name = "function* " + name;
|
|
|
|
|
} else {
|
|
|
|
|
name = "function " + name;
|
|
|
|
|
}
|
|
|
|
|
if (async) name = "async " + name;
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function invokeGenerator(was_generator) {
|
|
|
|
|
if (generator && !was_generator) switch (rng(4)) {
|
|
|
|
|
case 0:
|
|
|
|
|
return ".next()";
|
|
|
|
|
case 1:
|
|
|
|
|
return ".next().done";
|
|
|
|
|
case 2:
|
|
|
|
|
return ".next().value";
|
|
|
|
|
}
|
|
|
|
|
return "";
|
2020-12-06 21:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
2017-12-20 15:52:18 +00:00
|
|
|
function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
2019-10-27 06:17:35 +00:00
|
|
|
if (--recurmax < 0) { return ";"; }
|
2017-03-31 09:23:50 +00:00
|
|
|
if (!STMT_COUNT_FROM_GLOBAL) stmtDepth = 0;
|
2021-02-26 20:56:34 +00:00
|
|
|
++stmtDepth;
|
2020-10-11 17:18:57 +00:00
|
|
|
var s = [];
|
2020-11-17 00:01:24 +00:00
|
|
|
var name, args;
|
2020-12-17 10:23:41 +00:00
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
2021-02-23 14:55:08 +00:00
|
|
|
var lambda_len = lambda_vars.length;
|
2020-12-06 21:22:40 +00:00
|
|
|
var save_async = async;
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
2021-03-07 20:25:56 +00:00
|
|
|
async = SUPPORT.async && rng(200) == 0;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = SUPPORT.generator && rng(50) == 0;
|
|
|
|
|
if (async && generator && !SUPPORT.async_generator) {
|
|
|
|
|
if (rng(2)) {
|
|
|
|
|
async = false;
|
|
|
|
|
} else {
|
|
|
|
|
generator = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-11 17:18:57 +00:00
|
|
|
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
|
|
|
|
if (allowDefun || rng(5) > 0) {
|
|
|
|
|
name = "f" + funcs++;
|
|
|
|
|
} else {
|
|
|
|
|
unique_vars.push("a", "b", "c");
|
|
|
|
|
name = createVarName(MANDATORY, !allowDefun);
|
|
|
|
|
unique_vars.length -= 3;
|
|
|
|
|
}
|
2020-11-17 00:01:24 +00:00
|
|
|
var params;
|
2020-12-11 19:43:12 +00:00
|
|
|
if (SUPPORT.destructuring && (!allowDefun || !(name in called)) && rng(2)) {
|
2020-11-17 00:01:24 +00:00
|
|
|
called[name] = false;
|
2021-02-07 22:44:20 +00:00
|
|
|
var pairs = createAssignmentPairs(recurmax, stmtDepth, canThrow, nameLenBefore, save_async, save_generator);
|
2021-01-07 02:04:09 +00:00
|
|
|
params = pairs.names.join(", ");
|
|
|
|
|
if (!pairs.has_rest) params = addTrailingComma(params);
|
2021-02-01 09:20:13 +00:00
|
|
|
args = "(" + addTrailingComma(pairs.values.join(", ")) + ")";
|
2020-11-17 00:01:24 +00:00
|
|
|
} else {
|
2021-02-07 22:44:20 +00:00
|
|
|
params = createParams(save_async, save_generator);
|
2020-11-17 00:01:24 +00:00
|
|
|
}
|
2020-12-06 21:22:40 +00:00
|
|
|
s.push(makeFunction(name) + "(" + params + "){", strictMode());
|
2020-10-11 17:18:57 +00:00
|
|
|
s.push(defns());
|
|
|
|
|
if (rng(5) === 0) {
|
|
|
|
|
// functions with functions. lower the recursion to prevent a mess.
|
2022-08-09 16:20:20 +00:00
|
|
|
s.push(createFunctions(5, Math.ceil(recurmax * 0.7), DEFUN_OK, canThrow, stmtDepth));
|
2020-10-11 17:18:57 +00:00
|
|
|
} else {
|
|
|
|
|
// functions with statements
|
|
|
|
|
s.push(_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
|
|
|
|
}
|
|
|
|
|
s.push("}", "");
|
|
|
|
|
s = filterDirective(s).join("\n");
|
|
|
|
|
});
|
2021-02-07 22:44:20 +00:00
|
|
|
var call_next = invokeGenerator(save_generator);
|
|
|
|
|
generator = save_generator;
|
2020-12-06 21:22:40 +00:00
|
|
|
async = save_async;
|
2021-02-23 14:55:08 +00:00
|
|
|
lambda_vars.length = lambda_len;
|
2020-12-17 10:23:41 +00:00
|
|
|
VAR_NAMES.length = nameLenBefore;
|
2017-03-31 09:23:50 +00:00
|
|
|
|
2021-02-26 20:56:34 +00:00
|
|
|
if (allowDefun) s = appendExport(stmtDepth, true) + s;
|
2017-12-20 15:52:18 +00:00
|
|
|
if (!allowDefun) {
|
|
|
|
|
// avoid "function statements" (decl inside statements)
|
2021-02-26 20:56:34 +00:00
|
|
|
s = appendExport(stmtDepth) + "var " + createVarName(MANDATORY) + " = " + s;
|
2021-02-01 09:20:13 +00:00
|
|
|
s += args || createArgs(recurmax, stmtDepth, canThrow);
|
2021-02-07 22:44:20 +00:00
|
|
|
s += call_next;
|
2020-11-17 00:01:24 +00:00
|
|
|
} else if (!(name in called) || args || rng(3)) {
|
2021-02-26 20:56:34 +00:00
|
|
|
s += appendExport(stmtDepth) + "var " + createVarName(MANDATORY) + " = " + name;
|
2021-02-01 09:20:13 +00:00
|
|
|
s += args || createArgs(recurmax, stmtDepth, canThrow);
|
2021-02-07 22:44:20 +00:00
|
|
|
s += call_next;
|
2017-12-20 15:52:18 +00:00
|
|
|
}
|
2017-03-31 09:23:50 +00:00
|
|
|
|
2019-10-27 06:17:35 +00:00
|
|
|
return s + ";";
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-11 17:18:57 +00:00
|
|
|
function _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
2022-08-11 19:55:54 +00:00
|
|
|
if (--recurmax < 0) return ";";
|
2019-10-27 06:17:35 +00:00
|
|
|
var s = "";
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(n); --i >= 0;) {
|
2019-10-27 06:17:35 +00:00
|
|
|
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "\n";
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-11 17:18:57 +00:00
|
|
|
function createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
|
|
|
|
var s = "";
|
2020-12-17 10:23:41 +00:00
|
|
|
mayCreateBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
2020-10-11 17:18:57 +00:00
|
|
|
s += defns() + "\n";
|
|
|
|
|
s += _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
|
|
|
|
});
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-22 14:15:04 +00:00
|
|
|
function enableLoopControl(flag, defaultValue) {
|
|
|
|
|
return Array.isArray(flag) && flag.indexOf("") < 0 ? flag.concat("") : flag || defaultValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createLabel(canBreak, canContinue) {
|
|
|
|
|
var label;
|
|
|
|
|
if (rng(10) < 3) {
|
|
|
|
|
label = ++labels;
|
|
|
|
|
if (Array.isArray(canBreak)) {
|
|
|
|
|
canBreak = canBreak.slice();
|
|
|
|
|
} else {
|
|
|
|
|
canBreak = canBreak ? [ "" ] : [];
|
|
|
|
|
}
|
|
|
|
|
canBreak.push(label);
|
|
|
|
|
if (Array.isArray(canContinue)) {
|
|
|
|
|
canContinue = canContinue.slice();
|
|
|
|
|
} else {
|
|
|
|
|
canContinue = canContinue ? [ "" ] : [];
|
|
|
|
|
}
|
|
|
|
|
canContinue.push(label);
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
break: canBreak,
|
|
|
|
|
continue: canContinue,
|
|
|
|
|
target: label ? "L" + label + ": " : ""
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getLabel(label) {
|
|
|
|
|
if (!Array.isArray(label)) return "";
|
|
|
|
|
label = label[rng(label.length)];
|
|
|
|
|
return label && " L" + label;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 15:33:58 +00:00
|
|
|
function declareVarName(name, no_var) {
|
|
|
|
|
if (!SUPPORT.let || !no_var && rng(10)) return "var ";
|
|
|
|
|
block_vars.push(name);
|
|
|
|
|
return rng(2) ? "let " : "const ";
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 07:42:46 +00:00
|
|
|
function createImportAlias() {
|
|
|
|
|
if (rng(10)) return "alias" + imports++;
|
|
|
|
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
|
|
|
|
var name = createVarName(MANDATORY);
|
|
|
|
|
block_vars.push(name);
|
|
|
|
|
unique_vars.length -= 6;
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-13 18:10:34 +00:00
|
|
|
function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth, target) {
|
2017-03-31 09:23:50 +00:00
|
|
|
++stmtDepth;
|
|
|
|
|
var loop = ++loops;
|
|
|
|
|
if (--recurmax < 0) {
|
2019-10-27 06:17:35 +00:00
|
|
|
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ";";
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// allow to forcefully generate certain structures at first or second recursion level
|
2017-05-13 18:10:34 +00:00
|
|
|
if (target === undefined) {
|
|
|
|
|
if (stmtDepth === 1 && STMT_FIRST_LEVEL_OVERRIDE >= 0) target = STMT_FIRST_LEVEL_OVERRIDE;
|
|
|
|
|
else if (stmtDepth === 2 && STMT_SECOND_LEVEL_OVERRIDE >= 0) target = STMT_SECOND_LEVEL_OVERRIDE;
|
|
|
|
|
else target = STMTS_TO_USE[rng(STMTS_TO_USE.length)];
|
|
|
|
|
}
|
2017-03-31 09:23:50 +00:00
|
|
|
|
|
|
|
|
switch (target) {
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_BLOCK:
|
2017-04-22 14:15:04 +00:00
|
|
|
var label = createLabel(canBreak);
|
2022-08-09 16:20:20 +00:00
|
|
|
return label.target + "{" + createStatements(5, recurmax, canThrow, label.break, canContinue, cannotReturn, stmtDepth) + "}";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_IF_ELSE:
|
2020-12-17 10:23:41 +00:00
|
|
|
return "if (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + (rng(2) ? " else " + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) : "");
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_DO_WHILE:
|
2017-04-22 14:15:04 +00:00
|
|
|
var label = createLabel(canBreak, canContinue);
|
|
|
|
|
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
|
|
|
|
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
2020-12-10 22:59:21 +00:00
|
|
|
return "{var brake" + loop + " = 5; " + label.target + "do {" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "} while (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " && --brake" + loop + " > 0);}";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_WHILE:
|
2017-04-22 14:15:04 +00:00
|
|
|
var label = createLabel(canBreak, canContinue);
|
|
|
|
|
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
|
|
|
|
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
2020-12-10 22:59:21 +00:00
|
|
|
return "{var brake" + loop + " = 5; " + label.target + "while (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " && --brake" + loop + " > 0)" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_FOR_LOOP:
|
2017-04-22 14:15:04 +00:00
|
|
|
var label = createLabel(canBreak, canContinue);
|
|
|
|
|
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
|
|
|
|
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
2020-12-10 22:59:21 +00:00
|
|
|
return label.target + "for (var brake" + loop + " = 5; " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " && brake" + loop + " > 0; --brake" + loop + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
2021-02-08 20:28:23 +00:00
|
|
|
case STMT_FOR_ENUM:
|
2021-03-02 15:33:58 +00:00
|
|
|
var block_len = block_vars.length;
|
|
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
2017-04-22 14:15:04 +00:00
|
|
|
var label = createLabel(canBreak, canContinue);
|
|
|
|
|
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
|
|
|
|
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
2021-02-08 20:28:23 +00:00
|
|
|
var of = SUPPORT.for_of && rng(20) == 0;
|
2021-04-21 00:33:54 +00:00
|
|
|
var key;
|
|
|
|
|
if (rng(10)) {
|
|
|
|
|
key = "key" + loop;
|
|
|
|
|
} else if (bug_for_of_async && of) {
|
|
|
|
|
addAvoidVar("async");
|
|
|
|
|
key = getVarName(NO_CONST);
|
|
|
|
|
removeAvoidVar("async");
|
|
|
|
|
} else {
|
|
|
|
|
key = getVarName(NO_CONST);
|
|
|
|
|
}
|
2021-02-08 20:28:23 +00:00
|
|
|
var init = "";
|
|
|
|
|
if (!/^key/.test(key)) {
|
|
|
|
|
if (!(of && bug_for_of_var) && rng(10) == 0) init = "var ";
|
|
|
|
|
} else {
|
2021-03-02 15:33:58 +00:00
|
|
|
init = declareVarName(key, of && bug_for_of_var);
|
2021-02-08 20:28:23 +00:00
|
|
|
}
|
2021-02-23 14:55:08 +00:00
|
|
|
if (!SUPPORT.destructuring || of && !(canThrow && rng(20) == 0) || rng(10)) {
|
2021-02-08 20:28:23 +00:00
|
|
|
init += key;
|
|
|
|
|
} else if (rng(5)) {
|
|
|
|
|
init += "[ " + key + " ]";
|
|
|
|
|
} else {
|
|
|
|
|
init += "{ length: " + key + " }";
|
|
|
|
|
}
|
|
|
|
|
var s = "var expr" + loop + " = ";
|
|
|
|
|
if (of) {
|
|
|
|
|
var await = SUPPORT.for_await_of && async && rng(20) == 0;
|
|
|
|
|
if (SUPPORT.generator && rng(20) == 0) {
|
|
|
|
|
var gen = getVarName();
|
2021-02-23 14:55:08 +00:00
|
|
|
if (canThrow && rng(20) == 0) {
|
2021-02-08 20:28:23 +00:00
|
|
|
s += gen + "; ";
|
|
|
|
|
} else {
|
|
|
|
|
s += gen + " && typeof " + gen + "[Symbol.";
|
|
|
|
|
s += await ? "asyncIterator" : "iterator";
|
|
|
|
|
s += '] == "function" ? ' + gen + " : " + createArrayLiteral(recurmax, stmtDepth, canThrow) + "; ";
|
|
|
|
|
}
|
|
|
|
|
} else if (rng(5)) {
|
|
|
|
|
s += createArrayLiteral(recurmax, stmtDepth, canThrow) + "; ";
|
2021-02-23 14:55:08 +00:00
|
|
|
} else if (canThrow && rng(20) == 0) {
|
2021-02-08 20:28:23 +00:00
|
|
|
s += createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; ";
|
|
|
|
|
} else {
|
|
|
|
|
s += '"" + (' + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "); ";
|
|
|
|
|
}
|
|
|
|
|
s += label.target + " for ";
|
2021-03-07 20:25:56 +00:00
|
|
|
if (await) {
|
|
|
|
|
s += "await ";
|
|
|
|
|
has_await = true;
|
|
|
|
|
}
|
2021-02-08 20:28:23 +00:00
|
|
|
s += "(" + init + " of expr" + loop + ") {";
|
|
|
|
|
} else {
|
|
|
|
|
s += createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; ";
|
|
|
|
|
s += label.target + " for (" + init + " in expr" + loop + ") {";
|
|
|
|
|
}
|
2021-03-02 15:33:58 +00:00
|
|
|
if (/^key/.test(key)) VAR_NAMES.push(key);
|
|
|
|
|
if (rng(3)) {
|
|
|
|
|
s += "c = 1 + c; ";
|
2021-03-03 07:42:46 +00:00
|
|
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
|
|
|
|
var name;
|
|
|
|
|
do {
|
|
|
|
|
name = createVarName(MANDATORY);
|
|
|
|
|
} while (name == key);
|
|
|
|
|
unique_vars.length -= 6;
|
2021-03-02 15:33:58 +00:00
|
|
|
s += declareVarName(name) + name + " = expr" + loop + "[" + key + "]; ";
|
|
|
|
|
}
|
2021-02-08 20:28:23 +00:00
|
|
|
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
2021-03-02 15:33:58 +00:00
|
|
|
VAR_NAMES.length = nameLenBefore;
|
|
|
|
|
block_vars.length = block_len;
|
2021-02-08 20:28:23 +00:00
|
|
|
return "{" + s + "}";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_SEMI:
|
2019-10-27 06:17:35 +00:00
|
|
|
return use_strict && rng(20) === 0 ? '"use strict";' : ";";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_EXPR:
|
2021-02-28 18:27:41 +00:00
|
|
|
if (SUPPORT.destructuring && stmtDepth == 1 && !export_default && rng(20) == 0) {
|
2021-02-26 20:56:34 +00:00
|
|
|
export_default = true;
|
|
|
|
|
return "export default " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ";";
|
|
|
|
|
}
|
2019-10-27 06:17:35 +00:00
|
|
|
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ";";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_SWITCH:
|
|
|
|
|
// note: case args are actual expressions
|
|
|
|
|
// note: default does not _need_ to be last
|
2019-10-27 06:17:35 +00:00
|
|
|
return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_VAR:
|
2021-02-28 18:27:41 +00:00
|
|
|
if (SUPPORT.destructuring && stmtDepth == 1 && rng(5) == 0) {
|
2021-03-03 07:42:46 +00:00
|
|
|
var s = rng(2) ? " " + createImportAlias() : "";
|
2021-02-28 18:27:41 +00:00
|
|
|
if (rng(10)) {
|
|
|
|
|
if (s) s += ",";
|
|
|
|
|
if (rng(2)) {
|
2021-03-03 07:42:46 +00:00
|
|
|
s += " * as " + createImportAlias();
|
2021-02-28 18:27:41 +00:00
|
|
|
} else {
|
|
|
|
|
var names = [];
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(3); --i >= 0;) {
|
2021-03-03 07:42:46 +00:00
|
|
|
var name = createImportAlias();
|
2021-02-28 18:27:41 +00:00
|
|
|
names.push(rng(2) ? getDotKey() + " as " + name : name);
|
|
|
|
|
}
|
|
|
|
|
s += " { " + names.join(", ") + " }";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (s) s += " from";
|
|
|
|
|
return "import" + s + ' "path/to/module.js";';
|
|
|
|
|
} else if (SUPPORT.destructuring && rng(20) == 0) {
|
2020-12-17 10:23:41 +00:00
|
|
|
var pairs = createAssignmentPairs(recurmax, stmtDepth, canThrow);
|
2021-02-26 20:56:34 +00:00
|
|
|
return appendExport(stmtDepth) + "var " + pairs.names.map(function(name, index) {
|
2020-11-17 00:01:24 +00:00
|
|
|
return index in pairs.values ? name + " = " + pairs.values[index] : name;
|
|
|
|
|
}).join(", ") + ";";
|
|
|
|
|
} else switch (rng(3)) {
|
2017-03-31 21:47:11 +00:00
|
|
|
case 0:
|
2019-10-27 06:17:35 +00:00
|
|
|
unique_vars.push("c");
|
2017-03-31 21:47:11 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
2017-05-14 18:37:53 +00:00
|
|
|
unique_vars.pop();
|
2021-02-26 20:56:34 +00:00
|
|
|
return appendExport(stmtDepth) + "var " + name + ";";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 1:
|
|
|
|
|
// initializer can only have one expression
|
2019-10-27 06:17:35 +00:00
|
|
|
unique_vars.push("c");
|
2017-03-31 21:47:11 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
2017-05-14 18:37:53 +00:00
|
|
|
unique_vars.pop();
|
2021-02-26 20:56:34 +00:00
|
|
|
return appendExport(stmtDepth) + "var " + name + " = " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ";";
|
2017-03-31 21:47:11 +00:00
|
|
|
default:
|
|
|
|
|
// initializer can only have one expression
|
2019-10-27 06:17:35 +00:00
|
|
|
unique_vars.push("c");
|
2017-03-31 21:47:11 +00:00
|
|
|
var n1 = createVarName(MANDATORY);
|
|
|
|
|
var n2 = createVarName(MANDATORY);
|
2017-05-14 18:37:53 +00:00
|
|
|
unique_vars.pop();
|
2021-02-26 20:56:34 +00:00
|
|
|
return appendExport(stmtDepth) + "var " + n1 + " = " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ", " + n2 + " = " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ";";
|
2017-03-31 21:47:11 +00:00
|
|
|
}
|
|
|
|
|
case STMT_RETURN_ETC:
|
2017-04-08 17:36:38 +00:00
|
|
|
switch (rng(8)) {
|
|
|
|
|
case 0:
|
2017-03-31 21:47:11 +00:00
|
|
|
case 1:
|
2017-04-08 17:36:38 +00:00
|
|
|
case 2:
|
|
|
|
|
case 3:
|
2019-10-27 06:17:35 +00:00
|
|
|
if (canBreak && rng(5) === 0) return "break" + getLabel(canBreak) + ";";
|
|
|
|
|
if (canContinue && rng(5) === 0) return "continue" + getLabel(canContinue) + ";";
|
|
|
|
|
if (cannotReturn) return createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ";";
|
|
|
|
|
if (rng(3) == 0) return "/*3*/return;";
|
|
|
|
|
return "return " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ";";
|
2017-04-08 17:36:38 +00:00
|
|
|
case 4:
|
2017-03-31 21:47:11 +00:00
|
|
|
// this is actually more like a parser test, but perhaps it hits some dead code elimination traps
|
|
|
|
|
// must wrap in curlies to prevent orphaned `else` statement
|
|
|
|
|
// note: you can't `throw` without an expression so don't put a `throw` option in this case
|
2019-10-27 06:17:35 +00:00
|
|
|
if (cannotReturn) return createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ";";
|
|
|
|
|
return "{ /*2*/ return\n" + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + "}";
|
2017-04-08 17:36:38 +00:00
|
|
|
default:
|
|
|
|
|
// must wrap in curlies to prevent orphaned `else` statement
|
2019-10-27 06:17:35 +00:00
|
|
|
if (canThrow && rng(5) === 0) return "{ throw " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + "}";
|
|
|
|
|
if (cannotReturn) return createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ";";
|
|
|
|
|
return "{ return " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + "}";
|
2017-03-31 21:47:11 +00:00
|
|
|
}
|
|
|
|
|
case STMT_FUNC_EXPR:
|
|
|
|
|
// "In non-strict mode code, functions can only be declared at top level, inside a block, or ..."
|
2022-10-05 18:06:21 +00:00
|
|
|
// (don't make func decls in `if`; it's only a parser thing because you can't call them without a block)
|
2019-10-27 06:17:35 +00:00
|
|
|
return "{" + createFunction(recurmax, NO_DEFUN, canThrow, stmtDepth) + "}";
|
2017-03-31 21:47:11 +00:00
|
|
|
case STMT_TRY:
|
|
|
|
|
// catch var could cause some problems
|
|
|
|
|
// note: the "blocks" are syntactically mandatory for try/catch/finally
|
|
|
|
|
var n = rng(3); // 0=only catch, 1=only finally, 2=catch+finally
|
2019-10-27 06:17:35 +00:00
|
|
|
var s = "try {" + createStatement(recurmax, n === 1 ? CANNOT_THROW : CAN_THROW, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
2017-03-31 21:47:11 +00:00
|
|
|
if (n !== 1) {
|
|
|
|
|
// the catch var should only be accessible in the catch clause...
|
|
|
|
|
// we have to do go through some trouble here to prevent leaking it
|
2020-12-17 10:23:41 +00:00
|
|
|
mayCreateBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
2020-12-19 04:28:38 +00:00
|
|
|
var block_len = block_vars.length;
|
|
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
|
|
|
|
var unique_len = unique_vars.length;
|
2020-12-19 18:31:09 +00:00
|
|
|
if (SUPPORT.catch_omit_var && !rng(20)) {
|
2020-12-11 19:43:12 +00:00
|
|
|
s += " catch { ";
|
2020-12-19 18:31:09 +00:00
|
|
|
} else if (canThrow && SUPPORT.destructuring && !rng(20)) {
|
|
|
|
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
2020-12-19 04:28:38 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
|
|
|
|
block_vars.push(name);
|
|
|
|
|
var message = createVarName(MANDATORY);
|
|
|
|
|
block_vars.push(message);
|
2020-12-19 18:31:09 +00:00
|
|
|
unique_vars.length -= 6;
|
2020-12-19 04:28:38 +00:00
|
|
|
if (SUPPORT.computed_key && rng(10) == 0) {
|
|
|
|
|
s += " catch ({ message: " + message + ", ";
|
2020-12-23 22:22:55 +00:00
|
|
|
addAvoidVar(name);
|
2020-12-19 04:28:38 +00:00
|
|
|
s += "[" + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + "]: " + name;
|
2020-12-23 22:22:55 +00:00
|
|
|
removeAvoidVar(name);
|
2020-12-19 04:28:38 +00:00
|
|
|
s += " }) { ";
|
|
|
|
|
} else {
|
|
|
|
|
s += " catch ({ name: " + name + ", message: " + message + " }) { ";
|
|
|
|
|
}
|
2020-12-19 18:31:09 +00:00
|
|
|
} else {
|
2020-12-19 04:28:38 +00:00
|
|
|
var name = createVarName(MANDATORY);
|
|
|
|
|
if (!catch_redef) unique_vars.push(name);
|
|
|
|
|
s += " catch (" + name + ") { ";
|
2020-12-11 19:43:12 +00:00
|
|
|
}
|
2020-12-19 04:28:38 +00:00
|
|
|
var catches = VAR_NAMES.length - nameLenBefore;
|
2020-10-11 17:18:57 +00:00
|
|
|
s += defns() + "\n";
|
|
|
|
|
s += _createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
|
|
|
|
s += " }";
|
2020-12-19 04:28:38 +00:00
|
|
|
// remove catch variables
|
|
|
|
|
block_vars.length = block_len;
|
|
|
|
|
if (catches > 0) VAR_NAMES.splice(nameLenBefore, catches);
|
|
|
|
|
unique_vars.length = unique_len;
|
2020-10-11 17:18:57 +00:00
|
|
|
});
|
2017-03-31 21:47:11 +00:00
|
|
|
}
|
2022-06-06 04:01:15 +00:00
|
|
|
if (n !== 0) s += [
|
|
|
|
|
" finally { ",
|
2022-08-09 16:20:20 +00:00
|
|
|
createStatements(5, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
2022-06-06 04:01:15 +00:00
|
|
|
" }",
|
|
|
|
|
].join("");
|
2017-03-31 21:47:11 +00:00
|
|
|
return s;
|
|
|
|
|
case STMT_C:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "c = c + 1;";
|
2017-03-31 21:47:11 +00:00
|
|
|
default:
|
2019-10-27 06:17:35 +00:00
|
|
|
throw "no";
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-31 21:47:11 +00:00
|
|
|
function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
2017-03-31 09:23:50 +00:00
|
|
|
var hadDefault = false;
|
2021-04-30 03:40:47 +00:00
|
|
|
var s = [ "" ];
|
2017-04-22 14:15:04 +00:00
|
|
|
canBreak = enableLoopControl(canBreak, CAN_BREAK);
|
2017-03-31 09:23:50 +00:00
|
|
|
while (n-- > 0) {
|
|
|
|
|
//hadDefault = n > 0; // disables weird `default` clause positioning (use when handling destabilizes)
|
|
|
|
|
if (hadDefault || rng(5) > 0) {
|
2017-04-22 14:15:04 +00:00
|
|
|
s.push(
|
2019-10-27 06:17:35 +00:00
|
|
|
"case " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ":",
|
2022-08-09 16:20:20 +00:00
|
|
|
_createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
2019-10-27 06:17:35 +00:00
|
|
|
rng(10) > 0 ? " break;" : "/* fall-through */",
|
|
|
|
|
""
|
2017-04-22 14:15:04 +00:00
|
|
|
);
|
2017-03-31 09:23:50 +00:00
|
|
|
} else {
|
|
|
|
|
hadDefault = true;
|
2017-04-22 14:15:04 +00:00
|
|
|
s.push(
|
2019-10-27 06:17:35 +00:00
|
|
|
"default:",
|
2022-08-09 16:20:20 +00:00
|
|
|
_createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
2019-10-27 06:17:35 +00:00
|
|
|
""
|
2017-04-22 14:15:04 +00:00
|
|
|
);
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
}
|
2019-10-27 06:17:35 +00:00
|
|
|
return s.join("\n");
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
}
|
|
|
|
|
|
2017-03-31 09:23:50 +00:00
|
|
|
function createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|
|
|
|
if (--recurmax < 0) {
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(c = 1 + c, " + createNestedBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")"; // note: should return a simple non-recursing expression value!
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
// since `a` and `b` are our canaries we want them more frequently than other expressions (1/3rd chance of a canary)
|
2017-04-07 10:47:30 +00:00
|
|
|
switch (rng(6)) {
|
2017-03-31 21:47:11 +00:00
|
|
|
case 0:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(a++ + (" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + "))";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 1:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "((--b) + (" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + "))";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 2:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "((c = c + 1) + (" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + "))"; // c only gets incremented
|
2017-04-07 10:47:30 +00:00
|
|
|
default:
|
2020-12-06 21:22:40 +00:00
|
|
|
var expr = "(" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + ")";
|
2021-03-07 20:25:56 +00:00
|
|
|
if (async && rng(50) == 0) {
|
|
|
|
|
has_await = true;
|
|
|
|
|
return "(await" + expr + ")";
|
|
|
|
|
}
|
2021-02-07 22:44:20 +00:00
|
|
|
if (generator && rng(50) == 0) return "(yield" + (canThrow && rng(20) == 0 ? "*" : "") + expr + ")";
|
|
|
|
|
return expr;
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-10-27 06:17:35 +00:00
|
|
|
|
2017-04-07 10:47:30 +00:00
|
|
|
function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|
|
|
|
var p = 0;
|
|
|
|
|
switch (rng(_createExpression.N)) {
|
|
|
|
|
case p++:
|
2021-02-07 22:44:20 +00:00
|
|
|
if (generator && rng(50) == 0) return "yield";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2020-12-17 10:23:41 +00:00
|
|
|
return createUnaryPrefix() + (rng(2) ? "a" : "b");
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2020-12-17 10:23:41 +00:00
|
|
|
return (rng(2) ? "a" : "b") + createUnaryPostfix();
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2017-03-31 21:47:11 +00:00
|
|
|
// parens needed because assignments aren't valid unless they're the left-most op(s) in an expression
|
2019-10-27 06:17:35 +00:00
|
|
|
return "b " + createAssignment() + " a";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2019-10-27 06:17:35 +00:00
|
|
|
return rng(2) + " === 1 ? a : b";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2021-02-01 09:20:13 +00:00
|
|
|
if (SUPPORT.template && rng(20) == 0) {
|
|
|
|
|
var tmpl = createTemplateLiteral(recurmax, stmtDepth, canThrow);
|
|
|
|
|
if (rng(10) == 0) tmpl = "String.raw" + tmpl;
|
|
|
|
|
return tmpl;
|
|
|
|
|
}
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2017-03-31 21:47:11 +00:00
|
|
|
return createValue();
|
2017-11-04 08:29:42 +00:00
|
|
|
case p++:
|
2021-03-03 07:42:46 +00:00
|
|
|
if (SUPPORT.destructuring && rng(20) == 0) {
|
|
|
|
|
var name = "alias" + rng(imports + 2);
|
|
|
|
|
return canThrow && rng(20) == 0 ? name : "typeof " + name + ' != "undefined" && ' + name;
|
|
|
|
|
}
|
2017-11-04 08:29:42 +00:00
|
|
|
case p++:
|
|
|
|
|
return getVarName();
|
2017-12-28 07:36:55 +00:00
|
|
|
case p++:
|
2020-12-11 19:43:12 +00:00
|
|
|
switch (SUPPORT.destructuring ? rng(20) : 2) {
|
2020-11-17 00:01:24 +00:00
|
|
|
case 0:
|
|
|
|
|
return [
|
|
|
|
|
"[ ",
|
2021-01-19 23:27:32 +00:00
|
|
|
new Array(rng(3)).join(),
|
2021-02-23 14:55:08 +00:00
|
|
|
getVarName(NO_CONST, NO_LAMBDA),
|
2021-01-19 23:27:32 +00:00
|
|
|
new Array(rng(3)).join(),
|
2020-11-17 00:01:24 +00:00
|
|
|
" ] = ",
|
|
|
|
|
createArrayLiteral(recurmax, stmtDepth, canThrow),
|
|
|
|
|
].join("");
|
|
|
|
|
case 1:
|
|
|
|
|
return [
|
|
|
|
|
"{ ",
|
|
|
|
|
rng(2) ? "" : createObjectKey(recurmax, stmtDepth, canThrow) + ": ",
|
2021-02-23 14:55:08 +00:00
|
|
|
getVarName(NO_CONST, NO_LAMBDA),
|
2020-11-17 00:01:24 +00:00
|
|
|
" } = ",
|
|
|
|
|
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow),
|
|
|
|
|
" || {}",
|
|
|
|
|
].join("");
|
|
|
|
|
default:
|
2021-02-23 14:55:08 +00:00
|
|
|
return getVarName(NO_CONST, NO_LAMBDA) + createAssignment() + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
2020-11-17 00:01:24 +00:00
|
|
|
}
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
|
|
|
|
case p++:
|
2020-12-10 22:59:21 +00:00
|
|
|
return createExpression(recurmax, noComma, stmtDepth, canThrow) + " ? " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + " : " + createExpression(recurmax, noComma, stmtDepth, canThrow);
|
2017-04-23 12:05:22 +00:00
|
|
|
case p++:
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2017-03-31 21:47:11 +00:00
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
2021-02-23 14:55:08 +00:00
|
|
|
var lambda_len = lambda_vars.length;
|
2020-12-06 21:22:40 +00:00
|
|
|
var save_async = async;
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
2021-03-07 20:25:56 +00:00
|
|
|
async = SUPPORT.async && rng(200) == 0;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = SUPPORT.generator && rng(50) == 0;
|
|
|
|
|
if (async && generator && !SUPPORT.async_generator) {
|
|
|
|
|
if (rng(2)) {
|
|
|
|
|
async = false;
|
|
|
|
|
} else {
|
|
|
|
|
generator = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-23 14:55:08 +00:00
|
|
|
unique_vars.push("a", "b", "c");
|
2017-03-31 21:47:11 +00:00
|
|
|
var name = createVarName(MAYBE); // note: this name is only accessible from _within_ the function. and immutable at that.
|
2021-02-23 14:55:08 +00:00
|
|
|
unique_vars.length -= 3;
|
2017-04-23 12:05:22 +00:00
|
|
|
var s = [];
|
|
|
|
|
switch (rng(5)) {
|
2017-03-31 21:47:11 +00:00
|
|
|
case 0:
|
2021-02-07 22:44:20 +00:00
|
|
|
if (SUPPORT.arrow && !name && !generator && rng(2)) {
|
2020-12-17 10:23:41 +00:00
|
|
|
var args, suffix;
|
|
|
|
|
(rng(2) ? createBlockVariables : function() {
|
|
|
|
|
arguments[3]();
|
|
|
|
|
})(recurmax, stmtDepth, canThrow, function(defns) {
|
|
|
|
|
var params;
|
|
|
|
|
if (SUPPORT.destructuring && rng(2)) {
|
2021-02-07 22:44:20 +00:00
|
|
|
var pairs = createAssignmentPairs(recurmax, stmtDepth, canThrow, nameLenBefore, save_async, save_generator);
|
2021-01-07 02:04:09 +00:00
|
|
|
params = pairs.names.join(", ");
|
|
|
|
|
if (!pairs.has_rest) params = addTrailingComma(params);
|
2021-02-01 09:20:13 +00:00
|
|
|
args = "(" + addTrailingComma(pairs.values.join(", ")) + ")";
|
2020-12-17 10:23:41 +00:00
|
|
|
} else {
|
2021-02-07 22:44:20 +00:00
|
|
|
params = createParams(save_async, save_generator, NO_DUPLICATE);
|
2020-12-17 10:23:41 +00:00
|
|
|
}
|
2021-01-10 03:34:26 +00:00
|
|
|
params = (async ? "async (" : "(") + params + ") => ";
|
2020-12-17 10:23:41 +00:00
|
|
|
if (defns) {
|
|
|
|
|
s.push(
|
2021-01-10 03:34:26 +00:00
|
|
|
"(" + params + "{",
|
2020-12-17 10:23:41 +00:00
|
|
|
strictMode(),
|
|
|
|
|
defns(),
|
2022-08-09 16:20:20 +00:00
|
|
|
_createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth)
|
2020-12-17 10:23:41 +00:00
|
|
|
);
|
|
|
|
|
suffix = "})";
|
|
|
|
|
} else {
|
2021-01-10 03:34:26 +00:00
|
|
|
s.push("(" + params);
|
2020-12-18 04:20:43 +00:00
|
|
|
switch (rng(10)) {
|
2020-12-17 10:23:41 +00:00
|
|
|
case 0:
|
2021-02-23 14:55:08 +00:00
|
|
|
if (!in_class) {
|
|
|
|
|
s.push('(typeof arguments != "undefined" && arguments && arguments[' + rng(3) + "])");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-17 10:23:41 +00:00
|
|
|
case 1:
|
|
|
|
|
s.push("(this && this." + getDotKey() + ")");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
s.push(createExpression(recurmax, NO_COMMA, stmtDepth, canThrow));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
suffix = ")";
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-17 10:23:41 +00:00
|
|
|
async = save_async;
|
2021-02-23 14:55:08 +00:00
|
|
|
lambda_vars.length = lambda_len;
|
2020-12-17 10:23:41 +00:00
|
|
|
VAR_NAMES.length = nameLenBefore;
|
|
|
|
|
if (!args && rng(2)) args = createArgs(recurmax, stmtDepth, canThrow);
|
2021-02-01 09:20:13 +00:00
|
|
|
if (args) suffix += args;
|
2020-12-17 10:23:41 +00:00
|
|
|
s.push(suffix);
|
|
|
|
|
} else {
|
|
|
|
|
s.push(
|
|
|
|
|
"(" + makeFunction(name) + "(){",
|
|
|
|
|
strictMode(),
|
2022-08-09 16:20:20 +00:00
|
|
|
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
2021-02-07 22:44:20 +00:00
|
|
|
rng(2) ? "})" : "})()" + invokeGenerator(save_generator)
|
2020-12-17 10:23:41 +00:00
|
|
|
);
|
|
|
|
|
}
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
|
|
|
|
case 1:
|
2017-04-23 12:05:22 +00:00
|
|
|
s.push(
|
2020-12-06 21:22:40 +00:00
|
|
|
"+" + makeFunction(name) + "(){",
|
2017-04-23 12:05:22 +00:00
|
|
|
strictMode(),
|
2022-08-09 16:20:20 +00:00
|
|
|
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
2021-02-07 22:44:20 +00:00
|
|
|
"}()" + invokeGenerator(save_generator)
|
2017-04-23 12:05:22 +00:00
|
|
|
);
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
|
|
|
|
case 2:
|
2017-04-23 12:05:22 +00:00
|
|
|
s.push(
|
2020-12-06 21:22:40 +00:00
|
|
|
"!" + makeFunction(name) + "(){",
|
2017-04-23 12:05:22 +00:00
|
|
|
strictMode(),
|
2022-08-09 16:20:20 +00:00
|
|
|
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
2021-02-07 22:44:20 +00:00
|
|
|
"}()" + invokeGenerator(save_generator)
|
2017-04-23 12:05:22 +00:00
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
s.push(
|
2020-12-06 21:22:40 +00:00
|
|
|
"void " + makeFunction(name) + "(){",
|
2017-04-23 12:05:22 +00:00
|
|
|
strictMode(),
|
2022-08-09 16:20:20 +00:00
|
|
|
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
2021-02-07 22:44:20 +00:00
|
|
|
"}()" + invokeGenerator(save_generator)
|
2017-04-23 12:05:22 +00:00
|
|
|
);
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
|
|
|
|
default:
|
2020-12-06 21:22:40 +00:00
|
|
|
async = false;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = false;
|
2021-02-01 09:20:13 +00:00
|
|
|
var instantiate = rng(4) ? "new " : "";
|
2020-10-11 17:18:57 +00:00
|
|
|
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
|
|
|
|
s.push(
|
2021-02-23 14:55:08 +00:00
|
|
|
instantiate + makeFunction(name) + "(" + createParams(save_async, save_generator) + "){",
|
2021-03-16 06:34:36 +00:00
|
|
|
strictMode()
|
2020-10-11 17:18:57 +00:00
|
|
|
);
|
2021-03-16 06:34:36 +00:00
|
|
|
var add_new_target = SUPPORT.new_target && VALUES.indexOf("new.target") < 0;
|
|
|
|
|
if (add_new_target) VALUES.push("new.target");
|
|
|
|
|
s.push(defns());
|
2022-08-11 19:55:54 +00:00
|
|
|
if (instantiate) for (var i = get_num(3); --i >= 0;) {
|
2021-02-23 14:55:08 +00:00
|
|
|
s.push((in_class ? "if (this) " : "") + createThisAssignment(recurmax, stmtDepth, canThrow));
|
2020-10-11 17:18:57 +00:00
|
|
|
}
|
2022-08-09 16:20:20 +00:00
|
|
|
s.push(_createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
2021-03-16 06:34:36 +00:00
|
|
|
if (add_new_target) VALUES.splice(VALUES.indexOf("new.target"), 1);
|
2020-10-11 17:18:57 +00:00
|
|
|
});
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-07 02:07:34 +00:00
|
|
|
async = save_async;
|
2021-02-23 14:55:08 +00:00
|
|
|
lambda_vars.length = lambda_len;
|
2020-12-07 02:07:34 +00:00
|
|
|
VAR_NAMES.length = nameLenBefore;
|
2021-02-01 09:20:13 +00:00
|
|
|
s.push(rng(2) ? "}" : "}" + createArgs(recurmax, stmtDepth, canThrow, instantiate));
|
2017-03-31 21:47:11 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-06 21:22:40 +00:00
|
|
|
async = save_async;
|
2021-02-23 14:55:08 +00:00
|
|
|
lambda_vars.length = lambda_len;
|
2017-03-31 21:47:11 +00:00
|
|
|
VAR_NAMES.length = nameLenBefore;
|
2019-10-27 06:17:35 +00:00
|
|
|
return filterDirective(s).join("\n");
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2017-04-01 21:11:29 +00:00
|
|
|
return createTypeofExpr(recurmax, stmtDepth, canThrow);
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2017-03-31 21:47:11 +00:00
|
|
|
// more like a parser test but perhaps comment nodes mess up the analysis?
|
|
|
|
|
// note: parens not needed for post-fix (since that's the default when ambiguous)
|
|
|
|
|
// for prefix ops we need parens to prevent accidental syntax errors.
|
|
|
|
|
switch (rng(6)) {
|
|
|
|
|
case 0:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "a/* ignore */++";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 1:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "b/* ignore */--";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 2:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "++/* ignore */a";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 3:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "--/* ignore */b";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 4:
|
|
|
|
|
// only groups that wrap a single variable return a "Reference", so this is still valid.
|
|
|
|
|
// may just be a parser edge case that is invisible to uglify...
|
2019-10-27 06:17:35 +00:00
|
|
|
return "--(b)";
|
2017-03-31 21:47:11 +00:00
|
|
|
case 5:
|
|
|
|
|
// classic 0.3-0.1 case; 1-0.1-0.1-0.1 is not 0.7 :)
|
2019-10-27 06:17:35 +00:00
|
|
|
return "b + 1 - 0.1 - 0.1 - 0.1";
|
2017-03-31 21:47:11 +00:00
|
|
|
default:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "--/* ignore */b";
|
2017-03-31 21:47:11 +00:00
|
|
|
}
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
|
|
|
|
return createNestedBinaryExpr(recurmax, noComma, stmtDepth, canThrow);
|
|
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2019-10-27 06:17:35 +00:00
|
|
|
return createUnarySafePrefix() + "(" + createNestedBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2020-12-10 22:59:21 +00:00
|
|
|
return " (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " || a || 3).toString() ";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2020-12-10 22:59:21 +00:00
|
|
|
return " /[abc4]/.test((" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " || b || 5).toString()) ";
|
2020-02-18 19:35:37 +00:00
|
|
|
case p++:
|
2020-12-10 22:59:21 +00:00
|
|
|
return " /[abc4]/g.exec((" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " || b || 5).toString()) ";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2020-12-10 22:59:21 +00:00
|
|
|
return " (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " || " + rng(10) + ").toString()[" +
|
2017-04-02 20:00:33 +00:00
|
|
|
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "] ";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2017-05-13 18:10:34 +00:00
|
|
|
return createArrayLiteral(recurmax, stmtDepth, canThrow);
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2017-05-13 18:10:34 +00:00
|
|
|
return createObjectLiteral(recurmax, stmtDepth, canThrow);
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2019-10-27 06:17:35 +00:00
|
|
|
return createArrayLiteral(recurmax, stmtDepth, canThrow) + "[" +
|
|
|
|
|
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2019-10-27 06:17:35 +00:00
|
|
|
return createObjectLiteral(recurmax, stmtDepth, canThrow) + "[" +
|
|
|
|
|
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2019-10-27 06:17:35 +00:00
|
|
|
return createArrayLiteral(recurmax, stmtDepth, canThrow) + "." + getDotKey();
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
2019-10-27 06:17:35 +00:00
|
|
|
return createObjectLiteral(recurmax, stmtDepth, canThrow) + "." + getDotKey();
|
2020-06-13 18:50:26 +00:00
|
|
|
case p++:
|
|
|
|
|
return createValue() + " in " + createArrayLiteral(recurmax, stmtDepth, canThrow);
|
|
|
|
|
case p++:
|
|
|
|
|
return createValue() + " in " + createObjectLiteral(recurmax, stmtDepth, canThrow);
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
var name = getVarName();
|
2021-05-03 02:08:29 +00:00
|
|
|
var prop = "[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
|
|
|
|
if (SUPPORT.optional_chaining && rng(50) == 0) return name + "?." + prop;
|
|
|
|
|
if (canThrow && rng(20) == 0) return name + prop;
|
|
|
|
|
return name + " && " + name + prop;
|
2017-04-07 10:47:30 +00:00
|
|
|
case p++:
|
|
|
|
|
var name = getVarName();
|
2021-05-03 02:08:29 +00:00
|
|
|
var prop = getDotKey();
|
|
|
|
|
if (SUPPORT.optional_chaining && rng(50) == 0) return name + "?." + prop;
|
|
|
|
|
if (canThrow && rng(20) == 0) return name + "." + prop;
|
|
|
|
|
return name + " && " + name + "." + prop;
|
2020-04-17 23:12:13 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
|
|
|
|
var name = getVarName();
|
2021-03-03 07:42:46 +00:00
|
|
|
var fn = name + "." + getDotKey();
|
2021-03-15 13:54:05 +00:00
|
|
|
var s = "typeof " + fn + ' == "function" && --_calls_ >= 0 && ';
|
|
|
|
|
s += rng(5) ? fn : "(" + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ", " + fn + ")";
|
|
|
|
|
s += createArgs(recurmax, stmtDepth, canThrow);
|
2021-03-03 07:42:46 +00:00
|
|
|
return mayDefer(canThrow && rng(20) == 0 ? s : name + " && " + s);
|
2017-12-20 15:52:18 +00:00
|
|
|
case p++:
|
2021-03-07 20:25:56 +00:00
|
|
|
if (SUPPORT.class) {
|
|
|
|
|
if (classes.length && rng(20) == 0) {
|
|
|
|
|
return "--_calls_ >= 0 && new " + classes[rng(classes.length)] + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE);
|
|
|
|
|
}
|
|
|
|
|
if (rng(200) == 0) {
|
|
|
|
|
var s = "--_calls_ >= 0 && new ";
|
|
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
|
|
|
|
var class_len = classes.length;
|
|
|
|
|
var name;
|
|
|
|
|
if (canThrow && rng(20) == 0) {
|
|
|
|
|
in_class++;
|
|
|
|
|
name = createVarName(MAYBE);
|
|
|
|
|
in_class--;
|
|
|
|
|
} else if (rng(2)) {
|
|
|
|
|
name = "C" + clazz++;
|
|
|
|
|
classes.push(name);
|
|
|
|
|
}
|
|
|
|
|
s += createClassLiteral(recurmax, stmtDepth, canThrow, name);
|
|
|
|
|
classes.length = class_len;
|
|
|
|
|
VAR_NAMES.length = nameLenBefore;
|
|
|
|
|
s += createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE);
|
|
|
|
|
return s;
|
2021-02-23 14:55:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2017-12-20 15:52:18 +00:00
|
|
|
case p++:
|
|
|
|
|
case p++:
|
|
|
|
|
case p++:
|
2020-11-17 00:01:24 +00:00
|
|
|
var name;
|
|
|
|
|
do {
|
|
|
|
|
name = rng(3) == 0 ? getVarName() : "f" + rng(funcs + 2);
|
|
|
|
|
} while (name in called && !called[name]);
|
2017-12-20 15:52:18 +00:00
|
|
|
called[name] = true;
|
2021-05-03 02:08:29 +00:00
|
|
|
var args = createArgs(recurmax, stmtDepth, canThrow);
|
|
|
|
|
var call = "typeof " + name + ' == "function" && --_calls_ >= 0 && ' + name + args;
|
|
|
|
|
if (canThrow) {
|
|
|
|
|
if (SUPPORT.optional_chaining && args[0] != "`" && rng(50) == 0) {
|
2021-05-03 11:11:53 +00:00
|
|
|
call = "--_calls_ >= 0 && " + name + "?." + args;
|
2021-05-03 02:08:29 +00:00
|
|
|
} else if (rng(20) == 0) {
|
2021-05-03 11:11:53 +00:00
|
|
|
call = "--_calls_ >= 0 && " + name + args;
|
2021-05-03 02:08:29 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return mayDefer(call);
|
2017-04-02 20:00:33 +00:00
|
|
|
}
|
2017-04-07 10:47:30 +00:00
|
|
|
_createExpression.N = p;
|
|
|
|
|
return _createExpression(recurmax, noComma, stmtDepth, canThrow);
|
2017-04-02 20:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
2017-05-13 18:10:34 +00:00
|
|
|
function createArrayLiteral(recurmax, stmtDepth, canThrow) {
|
2017-04-02 20:00:33 +00:00
|
|
|
recurmax--;
|
2020-12-05 21:19:31 +00:00
|
|
|
var arr = [];
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(5); --i >= 0;) switch (SUPPORT.spread ? rng(50) : 3 + rng(47)) {
|
2020-12-05 21:19:31 +00:00
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
var name = getVarName();
|
2021-02-23 14:55:08 +00:00
|
|
|
if (canThrow && rng(20) == 0) {
|
2020-12-05 21:19:31 +00:00
|
|
|
arr.push("..." + name);
|
|
|
|
|
} else {
|
|
|
|
|
arr.push('...("" + ' + name + ")");
|
|
|
|
|
}
|
|
|
|
|
break;
|
2020-12-11 19:43:12 +00:00
|
|
|
case 2:
|
2020-12-05 21:19:31 +00:00
|
|
|
arr.push("..." + createArrayLiteral(recurmax, stmtDepth, canThrow));
|
|
|
|
|
break;
|
2020-12-11 19:43:12 +00:00
|
|
|
case 3:
|
|
|
|
|
case 4:
|
|
|
|
|
// in rare cases produce an array hole element
|
|
|
|
|
arr.push("");
|
|
|
|
|
break;
|
2020-12-05 21:19:31 +00:00
|
|
|
default:
|
|
|
|
|
arr.push(createExpression(recurmax, COMMA_OK, stmtDepth, canThrow));
|
|
|
|
|
break;
|
2017-04-02 20:00:33 +00:00
|
|
|
}
|
2020-12-05 21:19:31 +00:00
|
|
|
return "[" + arr.join(", ") + "]";
|
2017-04-02 20:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-01 02:36:45 +00:00
|
|
|
function createTemplateLiteral(recurmax, stmtDepth, canThrow) {
|
|
|
|
|
recurmax--;
|
|
|
|
|
var s = [];
|
|
|
|
|
addText();
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(5); --i >= 0;) {
|
2021-02-01 02:36:45 +00:00
|
|
|
s.push("${", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "}");
|
|
|
|
|
addText();
|
|
|
|
|
}
|
2021-02-01 09:20:13 +00:00
|
|
|
return "`" + s.join(rng(5) ? "" : "\n") + "`";
|
2021-02-01 02:36:45 +00:00
|
|
|
|
|
|
|
|
function addText() {
|
|
|
|
|
while (rng(5) == 0) s.push([
|
|
|
|
|
" ",
|
|
|
|
|
"$",
|
|
|
|
|
"}",
|
|
|
|
|
"\\`",
|
|
|
|
|
"\\\\",
|
|
|
|
|
"tmpl",
|
|
|
|
|
][rng(6)]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-02 20:00:33 +00:00
|
|
|
var SAFE_KEYS = [
|
|
|
|
|
"a",
|
|
|
|
|
"b",
|
|
|
|
|
"c",
|
2021-03-03 07:42:46 +00:00
|
|
|
"foo",
|
2017-04-02 20:00:33 +00:00
|
|
|
"NaN",
|
2021-03-03 07:42:46 +00:00
|
|
|
"null",
|
2017-04-02 20:00:33 +00:00
|
|
|
"Infinity",
|
2021-03-03 07:42:46 +00:00
|
|
|
"undefined",
|
|
|
|
|
"async",
|
2021-02-07 22:44:20 +00:00
|
|
|
"done",
|
2021-03-03 07:42:46 +00:00
|
|
|
"get",
|
2017-04-02 20:00:33 +00:00
|
|
|
"in",
|
2021-02-07 22:44:20 +00:00
|
|
|
"length",
|
|
|
|
|
"next",
|
2021-03-03 07:42:46 +00:00
|
|
|
"set",
|
|
|
|
|
"static",
|
2021-02-07 22:44:20 +00:00
|
|
|
"then",
|
|
|
|
|
"value",
|
2017-04-02 20:00:33 +00:00
|
|
|
"var",
|
|
|
|
|
];
|
|
|
|
|
var KEYS = [
|
|
|
|
|
"''",
|
|
|
|
|
'"\t"',
|
|
|
|
|
'"-2"',
|
|
|
|
|
"0",
|
|
|
|
|
"1.5",
|
|
|
|
|
"3",
|
|
|
|
|
].concat(SAFE_KEYS);
|
2021-04-30 03:40:47 +00:00
|
|
|
SAFE_KEYS = SAFE_KEYS.concat(SAFE_KEYS);
|
|
|
|
|
SAFE_KEYS = SAFE_KEYS.concat(SAFE_KEYS);
|
|
|
|
|
SAFE_KEYS = SAFE_KEYS.concat(SAFE_KEYS);
|
|
|
|
|
SAFE_KEYS.push("__proto__");
|
2017-04-02 20:00:33 +00:00
|
|
|
|
2017-05-13 18:10:34 +00:00
|
|
|
function getDotKey(assign) {
|
|
|
|
|
var key;
|
|
|
|
|
do {
|
|
|
|
|
key = SAFE_KEYS[rng(SAFE_KEYS.length)];
|
|
|
|
|
} while (assign && key == "length");
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-08 15:38:32 +00:00
|
|
|
function createObjectKey(recurmax, stmtDepth, canThrow) {
|
2020-12-11 19:43:12 +00:00
|
|
|
if (SUPPORT.computed_key && rng(10) == 0) {
|
|
|
|
|
return "[" + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + "]";
|
|
|
|
|
}
|
|
|
|
|
return KEYS[rng(KEYS.length)];
|
2020-11-08 15:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-23 14:55:08 +00:00
|
|
|
function createSuperAssignment(recurmax, stmtDepth, canThrow) {
|
|
|
|
|
var s = rng(2) ? "super." + getDotKey() : "super[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
|
|
|
|
return getVarName(NO_CONST, NO_LAMBDA) + createAssignment() + s + ";";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createThisAssignment(recurmax, stmtDepth, canThrow) {
|
|
|
|
|
var s = rng(2) ? "this." + getDotKey(true) : "this[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]";
|
|
|
|
|
return s + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ";";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz) {
|
2020-12-17 10:23:41 +00:00
|
|
|
var nameLenBefore = VAR_NAMES.length;
|
|
|
|
|
var save_async = async;
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
2017-05-13 18:10:34 +00:00
|
|
|
var s;
|
2021-02-23 14:55:08 +00:00
|
|
|
var name;
|
|
|
|
|
if (internal) {
|
|
|
|
|
name = internal;
|
|
|
|
|
} else if (isClazz) {
|
|
|
|
|
var clazzName = classes.pop();
|
|
|
|
|
name = createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
classes.push(clazzName);
|
|
|
|
|
} else {
|
|
|
|
|
name = createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
}
|
2021-01-20 13:03:33 +00:00
|
|
|
var fn;
|
2021-02-23 14:55:08 +00:00
|
|
|
switch (internal ? 2 : rng(SUPPORT.computed_key ? 3 : 2)) {
|
2021-01-20 13:03:33 +00:00
|
|
|
case 0:
|
|
|
|
|
async = false;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = false;
|
2021-01-20 13:03:33 +00:00
|
|
|
fn = function(defns) {
|
2020-10-13 16:09:17 +00:00
|
|
|
s = [
|
2020-12-20 00:19:04 +00:00
|
|
|
"get " + name + "(){",
|
2020-10-13 16:09:17 +00:00
|
|
|
strictMode(),
|
|
|
|
|
defns(),
|
|
|
|
|
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
|
|
|
|
createStatement(recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth, STMT_RETURN_ETC),
|
2021-02-23 14:55:08 +00:00
|
|
|
"}",
|
2020-10-13 16:09:17 +00:00
|
|
|
];
|
2021-01-20 13:03:33 +00:00
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
var prop;
|
|
|
|
|
do {
|
|
|
|
|
prop = getDotKey();
|
|
|
|
|
} while (name == prop);
|
|
|
|
|
async = false;
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = false;
|
2021-01-20 13:03:33 +00:00
|
|
|
fn = function(defns) {
|
2020-10-11 17:18:57 +00:00
|
|
|
s = [
|
2020-12-21 07:32:50 +00:00
|
|
|
"set " + name + "(" + createVarName(MANDATORY) + "){",
|
2020-10-11 17:18:57 +00:00
|
|
|
strictMode(),
|
|
|
|
|
defns(),
|
|
|
|
|
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
2020-12-21 07:32:50 +00:00
|
|
|
"this." + prop + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ";",
|
2021-02-23 14:55:08 +00:00
|
|
|
"}",
|
2020-10-11 17:18:57 +00:00
|
|
|
];
|
2021-01-20 13:03:33 +00:00
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2021-02-23 14:55:08 +00:00
|
|
|
if (/^(constructor|super)$/.test(internal)) {
|
|
|
|
|
async = false;
|
|
|
|
|
generator = false;
|
|
|
|
|
name = "constructor";
|
|
|
|
|
} else {
|
2021-03-07 20:25:56 +00:00
|
|
|
async = SUPPORT.async && rng(200) == 0;
|
2021-02-23 14:55:08 +00:00
|
|
|
generator = SUPPORT.generator && rng(50) == 0;
|
|
|
|
|
if (async && generator && !SUPPORT.async_generator) {
|
|
|
|
|
if (rng(2)) {
|
|
|
|
|
async = false;
|
|
|
|
|
} else {
|
|
|
|
|
generator = false;
|
|
|
|
|
}
|
2021-02-07 22:44:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-01-20 13:03:33 +00:00
|
|
|
fn = function(defns) {
|
2021-02-07 22:44:20 +00:00
|
|
|
if (generator) name = "*" + name;
|
|
|
|
|
if (async) name = "async "+ name;
|
2021-05-13 11:57:36 +00:00
|
|
|
var save_allow = allow_this;
|
|
|
|
|
if (internal == "super") allow_this = false;
|
2020-11-08 05:17:53 +00:00
|
|
|
s = [
|
2021-02-07 22:44:20 +00:00
|
|
|
name + "(" + createParams(save_async, save_generator, NO_DUPLICATE) + "){",
|
2020-11-08 05:17:53 +00:00
|
|
|
strictMode(),
|
|
|
|
|
defns(),
|
2021-02-23 14:55:08 +00:00
|
|
|
];
|
|
|
|
|
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth));
|
|
|
|
|
if (internal == "super") s.push("super" + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE) + ";");
|
2021-05-13 11:57:36 +00:00
|
|
|
allow_this = save_allow;
|
2022-08-11 19:55:54 +00:00
|
|
|
if (/^(constructor|super)$/.test(internal) || rng(10) == 0) for (var i = get_num(3); --i >= 0;) {
|
2021-02-23 14:55:08 +00:00
|
|
|
s.push(rng(2) ? createSuperAssignment(recurmax, stmtDepth, canThrow) : createThisAssignment(recurmax, stmtDepth, canThrow));
|
|
|
|
|
}
|
|
|
|
|
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}");
|
2021-01-20 13:03:33 +00:00
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
createBlockVariables(recurmax, stmtDepth, canThrow, fn);
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2020-12-17 10:23:41 +00:00
|
|
|
async = save_async;
|
|
|
|
|
VAR_NAMES.length = nameLenBefore;
|
2019-10-27 06:17:35 +00:00
|
|
|
return filterDirective(s).join("\n");
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
2017-05-13 18:10:34 +00:00
|
|
|
function createObjectLiteral(recurmax, stmtDepth, canThrow) {
|
2017-04-02 20:00:33 +00:00
|
|
|
recurmax--;
|
2021-04-30 03:40:47 +00:00
|
|
|
var obj = [ "({" ];
|
2020-12-11 19:43:12 +00:00
|
|
|
var offset = SUPPORT.spread_object ? 0 : SUPPORT.computed_key ? 2 : 4;
|
2021-04-30 03:40:47 +00:00
|
|
|
var has_proto = false;
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(5); --i >= 0;) switch (offset + rng(50 - offset)) {
|
2020-11-08 02:44:44 +00:00
|
|
|
case 0:
|
2020-12-11 19:43:12 +00:00
|
|
|
obj.push("..." + getVarName() + ",");
|
|
|
|
|
break;
|
2020-11-08 02:44:44 +00:00
|
|
|
case 1:
|
2020-12-11 19:43:12 +00:00
|
|
|
obj.push("..." + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ",");
|
2020-11-08 02:44:44 +00:00
|
|
|
break;
|
2020-12-05 21:19:31 +00:00
|
|
|
case 2:
|
|
|
|
|
case 3:
|
2020-12-11 19:43:12 +00:00
|
|
|
obj.push(getVarName() + ",");
|
2020-12-05 21:19:31 +00:00
|
|
|
break;
|
|
|
|
|
case 4:
|
2021-02-23 14:55:08 +00:00
|
|
|
obj.push(createObjectFunction(recurmax, stmtDepth, canThrow) + ",");
|
2020-12-05 21:19:31 +00:00
|
|
|
break;
|
2020-11-08 02:44:44 +00:00
|
|
|
default:
|
2021-04-30 03:40:47 +00:00
|
|
|
if (has_proto || rng(200)) {
|
|
|
|
|
obj.push(createObjectKey(recurmax, stmtDepth, canThrow) + ": " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ",");
|
|
|
|
|
} else {
|
|
|
|
|
obj.push("__proto__: " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " || {},");
|
|
|
|
|
has_proto = true;
|
|
|
|
|
}
|
2020-11-08 02:44:44 +00:00
|
|
|
break;
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
2019-10-27 06:17:35 +00:00
|
|
|
obj.push("})");
|
|
|
|
|
return obj.join("\n");
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-23 14:55:08 +00:00
|
|
|
function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
|
|
|
|
recurmax--;
|
|
|
|
|
var save_async = async;
|
|
|
|
|
var save_generator = generator;
|
|
|
|
|
in_class++;
|
|
|
|
|
var s = "class", constructor = "constructor";
|
|
|
|
|
var isClazz = /^C/.test(name);
|
|
|
|
|
if (name) s += " " + name;
|
|
|
|
|
if (rng(10) == 0) {
|
|
|
|
|
constructor = "super";
|
|
|
|
|
s += " extends ";
|
|
|
|
|
var p = getVarName();
|
|
|
|
|
if (canThrow && rng(20) == 0) {
|
|
|
|
|
s += p;
|
|
|
|
|
} else {
|
2022-05-16 03:11:10 +00:00
|
|
|
s += "(typeof " + p + ' == "function" && typeof ' + p + '.prototype == "object" && ' + p + ".constructor === Function ? " + p + " : function() {})";
|
2021-02-23 14:55:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s += " {\n";
|
|
|
|
|
var declared = [];
|
2022-08-11 19:55:54 +00:00
|
|
|
for (var i = get_num(5); --i >= 0;) {
|
2021-02-23 14:55:08 +00:00
|
|
|
var fixed = false;
|
|
|
|
|
if (rng(5) == 0) {
|
|
|
|
|
fixed = true;
|
|
|
|
|
s += "static ";
|
|
|
|
|
}
|
|
|
|
|
var internal = null;
|
|
|
|
|
if (SUPPORT.class_private && rng(10) == 0) {
|
|
|
|
|
do {
|
|
|
|
|
internal = "#" + getDotKey();
|
|
|
|
|
} while (declared.indexOf(internal) >= 0);
|
|
|
|
|
declared.push(internal);
|
|
|
|
|
}
|
|
|
|
|
if (SUPPORT.class_field && rng(2)) {
|
2022-04-25 13:33:31 +00:00
|
|
|
if (internal) {
|
|
|
|
|
s += internal;
|
2022-05-19 16:00:24 +00:00
|
|
|
} else if (fixed && bug_class_static_nontrivial) {
|
2022-04-25 13:33:31 +00:00
|
|
|
s += getDotKey();
|
|
|
|
|
} else {
|
|
|
|
|
s += createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
}
|
2021-02-23 14:55:08 +00:00
|
|
|
if (rng(5)) {
|
2022-05-19 16:00:24 +00:00
|
|
|
async = false;
|
2021-02-23 14:55:08 +00:00
|
|
|
generator = false;
|
|
|
|
|
s += " = " + createExpression(recurmax, NO_COMMA, stmtDepth, fixed ? canThrow : CANNOT_THROW);
|
|
|
|
|
generator = save_generator;
|
|
|
|
|
async = save_async;
|
|
|
|
|
}
|
|
|
|
|
s += ";\n";
|
2022-06-06 04:01:15 +00:00
|
|
|
} else if (SUPPORT.class_static_init && fixed && !internal && rng(10) == 0) {
|
|
|
|
|
async = false;
|
|
|
|
|
generator = false;
|
|
|
|
|
s += [
|
|
|
|
|
"{ ",
|
2022-08-09 16:20:20 +00:00
|
|
|
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth),
|
2022-06-06 04:01:15 +00:00
|
|
|
" }\n",
|
|
|
|
|
].join("");
|
|
|
|
|
generator = save_generator;
|
|
|
|
|
async = save_async;
|
2021-02-23 14:55:08 +00:00
|
|
|
} else {
|
|
|
|
|
if (!fixed && !internal && constructor && rng(10) == 0) {
|
|
|
|
|
internal = constructor;
|
|
|
|
|
constructor = null;
|
|
|
|
|
}
|
|
|
|
|
s += createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz) + "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
in_class--;
|
|
|
|
|
generator = save_generator;
|
|
|
|
|
async = save_async;
|
|
|
|
|
return s + "}";
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-07 10:47:30 +00:00
|
|
|
function createNestedBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
2017-03-31 09:23:50 +00:00
|
|
|
recurmax = 3; // note that this generates 2^recurmax expression parts... make sure to cap it
|
2017-04-07 10:47:30 +00:00
|
|
|
return _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow);
|
|
|
|
|
}
|
|
|
|
|
function _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(" + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow)
|
2020-06-07 21:23:23 +00:00
|
|
|
+ createBinaryOp(noComma, canThrow) + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
2017-04-07 10:47:30 +00:00
|
|
|
function _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
2017-03-31 09:23:50 +00:00
|
|
|
// intentionally generate more hardcore ops
|
|
|
|
|
if (--recurmax < 0) return createValue();
|
2017-04-23 12:05:22 +00:00
|
|
|
var assignee, expr;
|
2017-04-07 10:47:30 +00:00
|
|
|
switch (rng(30)) {
|
|
|
|
|
case 0:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(c = c + 1, " + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
2017-04-07 10:47:30 +00:00
|
|
|
case 1:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(" + createUnarySafePrefix() + "(" + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + "))";
|
2017-04-07 10:47:30 +00:00
|
|
|
case 2:
|
2021-02-23 14:55:08 +00:00
|
|
|
assignee = getVarName(NO_CONST, NO_LAMBDA);
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(" + assignee + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
2017-04-07 10:47:30 +00:00
|
|
|
case 3:
|
2017-04-23 12:05:22 +00:00
|
|
|
assignee = getVarName();
|
2020-12-11 19:43:12 +00:00
|
|
|
switch (SUPPORT.destructuring ? rng(20) : 2) {
|
2020-11-17 00:01:24 +00:00
|
|
|
case 0:
|
|
|
|
|
expr = [
|
|
|
|
|
"([ ",
|
|
|
|
|
assignee,
|
|
|
|
|
"[", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "]",
|
|
|
|
|
" ] = [ ",
|
|
|
|
|
_createBinaryExpr(recurmax, noComma, stmtDepth, canThrow),
|
|
|
|
|
" ])",
|
|
|
|
|
].join("");
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
var key1 = createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
var key2 = /^\[/.test(key1) ? createObjectKey(recurmax, stmtDepth, canThrow) : key1;
|
|
|
|
|
expr = [
|
|
|
|
|
"({ ",
|
|
|
|
|
key1, ": ", assignee,
|
|
|
|
|
"[", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "]",
|
|
|
|
|
" } = { ",
|
|
|
|
|
key2, ": ", _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow),
|
|
|
|
|
" })",
|
|
|
|
|
].join("");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
expr = [
|
|
|
|
|
"(",
|
|
|
|
|
assignee,
|
|
|
|
|
"[", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "]",
|
|
|
|
|
createAssignment(),
|
|
|
|
|
_createBinaryExpr(recurmax, noComma, stmtDepth, canThrow),
|
|
|
|
|
")",
|
|
|
|
|
].join("");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-02-23 14:55:08 +00:00
|
|
|
if (in_class) return "(Object.isExtensible(" + assignee + ") && " + expr + ")";
|
|
|
|
|
return canThrow && rng(20) == 0 ? expr : "(" + assignee + " && " + expr + ")";
|
2017-04-07 10:47:30 +00:00
|
|
|
case 4:
|
2017-04-23 12:05:22 +00:00
|
|
|
assignee = getVarName();
|
2020-12-11 19:43:12 +00:00
|
|
|
switch (SUPPORT.destructuring ? rng(20) : 2) {
|
2020-11-17 00:01:24 +00:00
|
|
|
case 0:
|
|
|
|
|
expr = [
|
|
|
|
|
"([ ",
|
|
|
|
|
assignee,
|
|
|
|
|
".", getDotKey(true),
|
|
|
|
|
" ] = [ ",
|
|
|
|
|
_createBinaryExpr(recurmax, noComma, stmtDepth, canThrow),
|
|
|
|
|
" ])",
|
|
|
|
|
].join("");
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
var key1 = createObjectKey(recurmax, stmtDepth, canThrow);
|
|
|
|
|
var key2 = /^\[/.test(key1) ? createObjectKey(recurmax, stmtDepth, canThrow) : key1;
|
|
|
|
|
expr = [
|
|
|
|
|
"({ ",
|
|
|
|
|
key1, ": ", assignee,
|
|
|
|
|
".", getDotKey(true),
|
|
|
|
|
" } = { ",
|
|
|
|
|
key2, ": ", _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow),
|
|
|
|
|
" })",
|
|
|
|
|
].join("");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
expr = [
|
|
|
|
|
"(",
|
|
|
|
|
assignee,
|
|
|
|
|
".", getDotKey(true),
|
|
|
|
|
createAssignment(),
|
|
|
|
|
_createBinaryExpr(recurmax, noComma, stmtDepth, canThrow),
|
|
|
|
|
")",
|
|
|
|
|
].join("");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-02-23 14:55:08 +00:00
|
|
|
if (in_class) return "(Object.isExtensible(" + assignee + ") && " + expr + ")";
|
|
|
|
|
return canThrow && rng(20) == 0 ? expr : "(" + assignee + " && " + expr + ")";
|
2017-04-07 10:47:30 +00:00
|
|
|
default:
|
|
|
|
|
return _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow);
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-01 21:11:29 +00:00
|
|
|
function createTypeofExpr(recurmax, stmtDepth, canThrow) {
|
2017-04-01 18:08:46 +00:00
|
|
|
switch (rng(8)) {
|
2017-03-31 21:47:11 +00:00
|
|
|
case 0:
|
2021-01-12 20:29:39 +00:00
|
|
|
return "(typeof " + createVar() + ' === "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
2017-03-31 21:47:11 +00:00
|
|
|
case 1:
|
2021-01-12 20:29:39 +00:00
|
|
|
return "(typeof " + createVar() + ' !== "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
2017-03-31 21:47:11 +00:00
|
|
|
case 2:
|
2021-01-12 20:29:39 +00:00
|
|
|
return "(typeof " + createVar() + ' == "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
2017-03-31 21:47:11 +00:00
|
|
|
case 3:
|
2021-01-12 20:29:39 +00:00
|
|
|
return "(typeof " + createVar() + ' != "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
2017-03-31 21:47:11 +00:00
|
|
|
case 4:
|
2021-01-12 20:29:39 +00:00
|
|
|
return "(typeof " + createVar() + ")";
|
2017-04-01 21:11:29 +00:00
|
|
|
default:
|
2019-10-27 06:17:35 +00:00
|
|
|
return "(typeof " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")";
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
2021-01-12 20:29:39 +00:00
|
|
|
|
|
|
|
|
function createVar() {
|
|
|
|
|
var save_async = async;
|
2021-02-07 22:44:20 +00:00
|
|
|
var save_generator = generator;
|
2021-01-12 20:29:39 +00:00
|
|
|
if (!async && avoid_vars.indexOf("await") >= 0) async = true;
|
2021-02-07 22:44:20 +00:00
|
|
|
if (!generator && avoid_vars.indexOf("yield") >= 0) generator = true;
|
2021-01-12 20:29:39 +00:00
|
|
|
var name = createVarName(MANDATORY, DONT_STORE);
|
2021-02-07 22:44:20 +00:00
|
|
|
generator = save_generator;
|
2021-01-12 20:29:39 +00:00
|
|
|
async = save_async;
|
|
|
|
|
return name;
|
|
|
|
|
}
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
function createValue() {
|
2021-03-16 12:58:51 +00:00
|
|
|
var v;
|
|
|
|
|
do {
|
|
|
|
|
v = VALUES[rng(VALUES.length)];
|
2021-05-13 11:57:36 +00:00
|
|
|
} while (v == "new.target" && rng(200) || !allow_this && v == "this");
|
2021-03-16 12:58:51 +00:00
|
|
|
return v;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-07 21:23:23 +00:00
|
|
|
function createBinaryOp(noComma, canThrow) {
|
|
|
|
|
var op;
|
|
|
|
|
do {
|
|
|
|
|
op = BINARY_OPS[rng(BINARY_OPS.length)];
|
2022-06-12 02:01:54 +00:00
|
|
|
} while (noComma && op == "," || !canThrow && /^ in/.test(op));
|
2020-06-07 21:23:23 +00:00
|
|
|
return op;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 17:46:12 +00:00
|
|
|
function createAssignment() {
|
2017-03-31 09:23:50 +00:00
|
|
|
return ASSIGNMENTS[rng(ASSIGNMENTS.length)];
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2017-04-07 10:47:30 +00:00
|
|
|
function createUnarySafePrefix() {
|
2021-02-23 14:55:08 +00:00
|
|
|
var prefix;
|
|
|
|
|
do {
|
|
|
|
|
prefix = UNARY_SAFE[rng(UNARY_SAFE.length)];
|
|
|
|
|
} while (prefix == "delete " && in_class);
|
|
|
|
|
return prefix;
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createUnaryPrefix() {
|
2021-02-23 14:55:08 +00:00
|
|
|
var prefix;
|
|
|
|
|
do {
|
|
|
|
|
prefix = UNARY_PREFIX[rng(UNARY_PREFIX.length)];
|
|
|
|
|
} while (prefix == "delete " && in_class);
|
|
|
|
|
return prefix;
|
2017-04-07 10:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createUnaryPostfix() {
|
|
|
|
|
return UNARY_POSTFIX[rng(UNARY_POSTFIX.length)];
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 22:22:55 +00:00
|
|
|
function addAvoidVar(name) {
|
|
|
|
|
avoid_vars.push(name);
|
2020-11-25 01:33:42 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-23 22:22:55 +00:00
|
|
|
function removeAvoidVar(name) {
|
|
|
|
|
var index = avoid_vars.lastIndexOf(name);
|
|
|
|
|
if (index >= 0) avoid_vars.splice(index, 1);
|
2020-11-25 01:33:42 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-23 14:55:08 +00:00
|
|
|
function isBannedKeyword(name) {
|
|
|
|
|
switch (name) {
|
|
|
|
|
case "arguments":
|
2021-10-20 18:14:29 +00:00
|
|
|
case "let":
|
2021-02-23 14:55:08 +00:00
|
|
|
return in_class;
|
|
|
|
|
case "await":
|
2022-05-19 16:00:24 +00:00
|
|
|
return async || in_class && bug_class_static_await;
|
2021-02-23 14:55:08 +00:00
|
|
|
case "yield":
|
|
|
|
|
return generator || in_class;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getVarName(noConst, noLambda) {
|
2017-04-07 10:47:30 +00:00
|
|
|
// try to get a generated name reachable from current scope. default to just `a`
|
2020-11-25 01:33:42 +00:00
|
|
|
var name, tries = 10;
|
|
|
|
|
do {
|
|
|
|
|
if (--tries < 0) return "a";
|
|
|
|
|
name = VAR_NAMES[INITIAL_NAMES_LEN + rng(VAR_NAMES.length - INITIAL_NAMES_LEN)];
|
2021-02-07 22:44:20 +00:00
|
|
|
} while (!name
|
|
|
|
|
|| avoid_vars.indexOf(name) >= 0
|
2021-02-23 14:55:08 +00:00
|
|
|
|| noConst && (block_vars.indexOf(name) >= 0
|
|
|
|
|
|| in_class && [
|
|
|
|
|
"Infinity",
|
|
|
|
|
"NaN",
|
|
|
|
|
"undefined",
|
|
|
|
|
].indexOf(name) >= 0)
|
|
|
|
|
|| noLambda && lambda_vars.indexOf(name) >= 0
|
|
|
|
|
|| isBannedKeyword(name));
|
2020-11-25 01:33:42 +00:00
|
|
|
return name;
|
Improve fuzzer. :) (#1665)
@qfox Put value constants in a global constant 74c0fb9
@qfox And the other string based values as well a5033c5
@qfox Be more strict about parameters, allow max to be optional 9c7ce70
@qfox Support a `V` (capital) flag to only log out at intervals 2d822c7
@qfox Fewer magic variables a6a9a7c
@qfox Fix decrement such that a function is created when n=1 7e4b017
@qfox Add more values 64e596e
@qfox Make `b` appear more often d33191a
@qfox Add functions that contain (only..) functions 29a86e3
@qfox Allow the block statement to contain multiple statements 7570484
@qfox Make the interval count a constant d587ad8
@qfox Enable mangling, disable post-processing … 4dc8d35
@qfox Add more simple value that may trigger syntactic errors 8496d58
@qfox Add `else` to some `if` statements a4aed65
@qfox Move iife to expr generator, fix missing recursion arg e453159
@qfox Improve output on error where it wasnt printing the last code properly 4565a1a
@qfox Add switch statement to generator ceafa76
@qfox Add var statement, support optional comma for expr generator b83921b
@qfox Expression generator should use a simple value instead of `0` as recu… … 9d1a5c7
@qfox const -> var to keep things es5... 0143099
@qfox Add more simple values that may trigger edge cases 5e124f1
@qfox Add central name generator, take special care for global functions aeb7682
@qfox Add some `return` and function declaration cases to statement generator 6c9c3cc
@qfox Exclude switches from generator for now 91124b2
Put value constants in a global constant
And the other string based values as well
Be more strict about parameters, allow max to be optional
Support a `V` (capital) flag to only log out at intervals
Fewer magic variables
Fix decrement such that a function is created when n=1
Add more values
Make `b` appear more often
Add functions that contain (only..) functions
Allow the block statement to contain multiple statements
Make the interval count a constant
Enable mangling, disable post-processing
Mangling is kind of the whole point...
Similarly, to beautify the minified code afterwards may supress bugs so it's probably best not to beautify the code prematurely. And there's no point anyways since you won't see it most of the time and only care about the main input anyways.
Add more simple value that may trigger syntactic errors
Add `else` to some `if` statements
Move iife to expr generator, fix missing recursion arg
Improve output on error where it wasnt printing the last code properly
Add switch statement to generator
Add var statement, support optional comma for expr generator
Expression generator should use a simple value instead of `0` as recursion default
const -> var to keep things es5...
Add more simple values that may trigger edge cases
Add central name generator, take special care for global functions
Add some `return` and function declaration cases to statement generator
Exclude switches from generator for now
Enable switch generation because #1667 was merged
Add typeof generator
Add some elision tests
Add a new edge case that returns an object explicitly
Add all binary ops to try and cover more paths
Forgot four binops and added `Math` to var name pool
Harden the incremental pre/postfix tests
Improve switch generator, allow `default` to appear at any clause index
Add try/catch/finally generation
Prevent function statements being generated
Add edge case with decremental op and a group
Disable switch generation until #1679 and #1680 are solved
Only allow `default` clause as last clause for now
Tentatively enable `throw`, `break` and `continue` statements when in valid contexts
2017-03-26 04:04:50 +00:00
|
|
|
}
|
|
|
|
|
|
2017-03-31 21:47:11 +00:00
|
|
|
function createVarName(maybe, dontStore) {
|
2017-04-07 10:47:30 +00:00
|
|
|
if (!maybe || rng(2)) {
|
|
|
|
|
var suffix = rng(3);
|
2021-01-24 15:37:57 +00:00
|
|
|
var name, tries = 10;
|
2017-05-14 18:37:53 +00:00
|
|
|
do {
|
|
|
|
|
name = VAR_NAMES[rng(VAR_NAMES.length)];
|
2021-01-24 15:37:57 +00:00
|
|
|
if (--tries < 0) suffix++;
|
2019-10-27 06:17:35 +00:00
|
|
|
if (suffix) name += "_" + suffix;
|
2021-02-07 22:44:20 +00:00
|
|
|
} while (unique_vars.indexOf(name) >= 0
|
|
|
|
|
|| block_vars.indexOf(name) >= 0
|
2021-02-23 14:55:08 +00:00
|
|
|
|| isBannedKeyword(name));
|
2020-12-17 10:23:41 +00:00
|
|
|
if (!dontStore) VAR_NAMES.push(name);
|
2017-03-31 09:23:50 +00:00
|
|
|
return name;
|
|
|
|
|
}
|
2019-10-27 06:17:35 +00:00
|
|
|
return "";
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2017-05-14 18:37:53 +00:00
|
|
|
if (require.main !== module) {
|
2022-07-10 23:18:25 +00:00
|
|
|
exports.createTopLevelCode = function() {
|
|
|
|
|
var code = createTopLevelCode();
|
|
|
|
|
exports.module = async && has_await;
|
|
|
|
|
return code;
|
|
|
|
|
};
|
2017-05-14 18:37:53 +00:00
|
|
|
exports.num_iterations = num_iterations;
|
2021-04-25 20:23:52 +00:00
|
|
|
exports.verbose = verbose;
|
2017-05-14 18:37:53 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-20 18:07:23 +00:00
|
|
|
function run_code(code, toplevel, timeout) {
|
2022-06-07 15:28:06 +00:00
|
|
|
if (async && has_await) code = [
|
|
|
|
|
'"use strict";',
|
2022-06-30 07:34:45 +00:00
|
|
|
"(async()=>{",
|
2022-06-07 15:28:06 +00:00
|
|
|
code,
|
2022-06-30 07:34:45 +00:00
|
|
|
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
2022-06-07 15:28:06 +00:00
|
|
|
].join("\n");
|
2021-10-20 18:07:23 +00:00
|
|
|
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
2021-02-26 20:56:34 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-16 22:29:02 +00:00
|
|
|
function writeln(stream, msg) {
|
|
|
|
|
if (typeof msg != "undefined") {
|
|
|
|
|
stream.write(typeof msg == "string" ? msg : msg.stack || "" + msg);
|
|
|
|
|
}
|
|
|
|
|
stream.write("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-09 07:56:28 +00:00
|
|
|
function println(msg) {
|
2019-10-16 22:29:02 +00:00
|
|
|
writeln(process.stdout, msg);
|
2017-06-09 07:56:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function errorln(msg) {
|
2019-10-16 22:29:02 +00:00
|
|
|
writeln(process.stderr, msg);
|
2017-06-09 07:56:28 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-13 06:26:45 +00:00
|
|
|
function try_beautify(code, toplevel, result, printfn, options) {
|
2022-06-08 19:01:00 +00:00
|
|
|
var o = JSON.parse(beautify_options);
|
|
|
|
|
if (async && has_await) o.module = true;
|
|
|
|
|
var beautified = UglifyJS.minify(code, o);
|
2017-05-09 07:58:46 +00:00
|
|
|
if (beautified.error) {
|
2017-06-09 07:56:28 +00:00
|
|
|
printfn("// !!! beautify failed !!!");
|
2019-10-07 06:36:00 +00:00
|
|
|
printfn(beautified.error);
|
2020-12-13 06:26:45 +00:00
|
|
|
beautified = null;
|
2021-02-26 20:56:34 +00:00
|
|
|
} else if (!sandbox.same_stdout(run_code(beautified.code, toplevel), result)) {
|
2020-12-13 06:26:45 +00:00
|
|
|
beautified = null;
|
|
|
|
|
} else if (options) {
|
|
|
|
|
var uglified = UglifyJS.minify(beautified.code, JSON.parse(options));
|
|
|
|
|
var expected, actual;
|
2022-04-18 05:03:01 +00:00
|
|
|
if (sandbox.is_error(uglify_code) || uglified.error) {
|
2020-12-13 06:26:45 +00:00
|
|
|
expected = uglify_code;
|
|
|
|
|
actual = uglified.error;
|
|
|
|
|
} else {
|
|
|
|
|
expected = uglify_result;
|
2021-02-26 20:56:34 +00:00
|
|
|
actual = run_code(uglified.code, toplevel);
|
2020-12-13 06:26:45 +00:00
|
|
|
}
|
|
|
|
|
if (!sandbox.same_stdout(expected, actual)) {
|
|
|
|
|
beautified = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (beautified) {
|
2017-06-09 07:56:28 +00:00
|
|
|
printfn("// (beautified)");
|
|
|
|
|
printfn(beautified.code);
|
2020-12-13 06:26:45 +00:00
|
|
|
} else {
|
|
|
|
|
printfn("//");
|
|
|
|
|
printfn(code);
|
2017-03-31 21:47:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-28 10:21:44 +00:00
|
|
|
var default_options = UglifyJS.default_options();
|
2017-04-01 18:10:50 +00:00
|
|
|
|
|
|
|
|
function log_suspects(minify_options, component) {
|
|
|
|
|
var options = component in minify_options ? minify_options[component] : true;
|
|
|
|
|
if (!options) return;
|
2017-05-28 10:21:44 +00:00
|
|
|
if (typeof options != "object") options = {};
|
|
|
|
|
var defs = default_options[component];
|
2020-05-17 13:35:17 +00:00
|
|
|
var toplevel = sandbox.has_toplevel(minify_options);
|
2017-05-28 10:21:44 +00:00
|
|
|
var suspects = Object.keys(defs).filter(function(name) {
|
2022-02-01 04:17:47 +00:00
|
|
|
var flip = component == "compress" && name == "keep_fargs";
|
2020-05-08 07:03:48 +00:00
|
|
|
if (flip !== (name in options ? options : defs)[name]) {
|
2017-04-01 18:10:50 +00:00
|
|
|
var m = JSON.parse(JSON.stringify(minify_options));
|
|
|
|
|
var o = JSON.parse(JSON.stringify(options));
|
2018-01-18 06:08:05 +00:00
|
|
|
o[name] = flip;
|
2017-04-01 18:10:50 +00:00
|
|
|
m[component] = o;
|
2020-05-20 20:00:38 +00:00
|
|
|
m.validate = true;
|
2017-05-09 07:58:46 +00:00
|
|
|
var result = UglifyJS.minify(original_code, m);
|
2022-04-18 05:03:01 +00:00
|
|
|
if (sandbox.is_error(uglify_code)) {
|
2020-05-20 20:00:38 +00:00
|
|
|
return !sandbox.same_stdout(uglify_code, result.error);
|
|
|
|
|
} else if (result.error) {
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln("Error testing options." + component + "." + name);
|
2019-10-07 06:36:00 +00:00
|
|
|
errorln(result.error);
|
2017-05-09 07:58:46 +00:00
|
|
|
} else {
|
2021-02-26 20:56:34 +00:00
|
|
|
var r = run_code(result.code, toplevel);
|
2020-04-26 16:59:26 +00:00
|
|
|
return !sandbox.same_stdout(uglify_result, r);
|
2017-04-01 18:10:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (suspects.length > 0) {
|
2017-06-09 16:11:40 +00:00
|
|
|
errorln("Suspicious " + component + " options:");
|
2017-04-01 18:10:50 +00:00
|
|
|
suspects.forEach(function(name) {
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln(" " + name);
|
2017-04-01 18:10:50 +00:00
|
|
|
});
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln();
|
2017-04-01 18:10:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 13:35:17 +00:00
|
|
|
function log_suspects_global(options, toplevel) {
|
2020-04-18 10:03:06 +00:00
|
|
|
var suspects = Object.keys(default_options).filter(function(component) {
|
|
|
|
|
return typeof default_options[component] != "object";
|
2020-03-12 20:03:47 +00:00
|
|
|
}).filter(function(component) {
|
|
|
|
|
var m = JSON.parse(options);
|
|
|
|
|
m[component] = false;
|
2020-05-20 20:00:38 +00:00
|
|
|
m.validate = true;
|
2020-03-12 20:03:47 +00:00
|
|
|
var result = UglifyJS.minify(original_code, m);
|
2022-04-18 05:03:01 +00:00
|
|
|
if (sandbox.is_error(uglify_code)) {
|
2020-05-20 20:00:38 +00:00
|
|
|
return !sandbox.same_stdout(uglify_code, result.error);
|
|
|
|
|
} else if (result.error) {
|
2020-03-12 20:03:47 +00:00
|
|
|
errorln("Error testing options." + component);
|
|
|
|
|
errorln(result.error);
|
|
|
|
|
} else {
|
2021-02-26 20:56:34 +00:00
|
|
|
var r = run_code(result.code, toplevel);
|
2020-04-26 16:59:26 +00:00
|
|
|
return !sandbox.same_stdout(uglify_result, r);
|
2018-01-18 06:08:05 +00:00
|
|
|
}
|
2020-03-12 20:03:47 +00:00
|
|
|
});
|
|
|
|
|
if (suspects.length > 0) {
|
|
|
|
|
errorln("Suspicious options:");
|
|
|
|
|
suspects.forEach(function(name) {
|
|
|
|
|
errorln(" " + name);
|
|
|
|
|
});
|
|
|
|
|
errorln();
|
2018-01-18 06:08:05 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-01 18:10:50 +00:00
|
|
|
function log(options) {
|
2020-02-29 17:33:48 +00:00
|
|
|
var toplevel = sandbox.has_toplevel(JSON.parse(options));
|
2019-10-27 06:17:35 +00:00
|
|
|
if (!ok) errorln("\n\n\n\n\n\n!!!!!!!!!!\n\n\n");
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln("//=============================================================");
|
2017-06-09 16:11:40 +00:00
|
|
|
if (!ok) errorln("// !!!!!! Failed... round " + round);
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln("// original code");
|
2020-12-13 06:26:45 +00:00
|
|
|
try_beautify(original_code, toplevel, original_result, errorln, options);
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln();
|
|
|
|
|
errorln();
|
|
|
|
|
errorln("//-------------------------------------------------------------");
|
2022-04-18 05:03:01 +00:00
|
|
|
if (sandbox.is_error(uglify_code)) {
|
|
|
|
|
errorln("// !!! uglify failed !!!");
|
|
|
|
|
errorln(uglify_code);
|
|
|
|
|
if (original_erred) {
|
|
|
|
|
errorln();
|
|
|
|
|
errorln();
|
|
|
|
|
errorln("original stacktrace:");
|
|
|
|
|
errorln(original_result);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln("// uglified code");
|
2020-02-29 17:33:48 +00:00
|
|
|
try_beautify(uglify_code, toplevel, uglify_result, errorln);
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln();
|
|
|
|
|
errorln();
|
|
|
|
|
errorln("original result:");
|
2019-10-07 06:36:00 +00:00
|
|
|
errorln(original_result);
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln("uglified result:");
|
2019-10-07 06:36:00 +00:00
|
|
|
errorln(uglify_result);
|
2017-03-31 09:23:50 +00:00
|
|
|
}
|
2020-07-21 08:17:15 +00:00
|
|
|
errorln("//-------------------------------------------------------------");
|
2020-12-24 09:02:18 +00:00
|
|
|
if (!ok) {
|
|
|
|
|
var reduce_options = JSON.parse(options);
|
|
|
|
|
reduce_options.validate = true;
|
|
|
|
|
var reduced = reduce_test(original_code, reduce_options, {
|
|
|
|
|
verbose: false,
|
|
|
|
|
}).code;
|
|
|
|
|
if (reduced) {
|
|
|
|
|
errorln();
|
|
|
|
|
errorln("// reduced test case (output will differ)");
|
|
|
|
|
errorln();
|
|
|
|
|
errorln(reduced);
|
|
|
|
|
errorln();
|
|
|
|
|
errorln("//-------------------------------------------------------------");
|
|
|
|
|
}
|
2020-07-21 08:17:15 +00:00
|
|
|
}
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln("minify(options):");
|
2020-02-29 17:33:48 +00:00
|
|
|
errorln(JSON.stringify(JSON.parse(options), null, 2));
|
2017-06-09 07:56:28 +00:00
|
|
|
errorln();
|
2020-05-20 20:00:38 +00:00
|
|
|
if (!ok) {
|
2020-04-18 10:03:06 +00:00
|
|
|
Object.keys(default_options).filter(function(component) {
|
|
|
|
|
var defs = default_options[component];
|
|
|
|
|
return defs && typeof defs == "object";
|
|
|
|
|
}).forEach(log_suspects.bind(null, JSON.parse(options)));
|
2020-05-17 13:35:17 +00:00
|
|
|
log_suspects_global(options, toplevel);
|
2017-06-09 16:11:40 +00:00
|
|
|
errorln("!!!!!! Failed... round " + round);
|
2017-04-01 18:10:50 +00:00
|
|
|
}
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-09 23:28:56 +00:00
|
|
|
function sort_globals(code) {
|
2022-06-07 15:28:06 +00:00
|
|
|
var injected = "throw Object.keys(this).sort(" + function(global) {
|
2021-01-19 23:27:32 +00:00
|
|
|
return function(m, n) {
|
2021-03-23 03:15:41 +00:00
|
|
|
return (typeof global[n] == "function") - (typeof global[m] == "function")
|
2021-01-19 23:27:32 +00:00
|
|
|
|| (m < n ? -1 : m > n ? 1 : 0);
|
|
|
|
|
};
|
2022-06-07 15:28:06 +00:00
|
|
|
} + "(this));";
|
|
|
|
|
var save_async = async;
|
|
|
|
|
if (async && has_await) {
|
|
|
|
|
async = false;
|
|
|
|
|
injected = [
|
|
|
|
|
'"use strict";',
|
|
|
|
|
injected,
|
|
|
|
|
"(async function(){",
|
|
|
|
|
code,
|
|
|
|
|
"})();"
|
|
|
|
|
].join("\n");
|
|
|
|
|
} else {
|
|
|
|
|
injected += "\n" + code;
|
|
|
|
|
}
|
|
|
|
|
var globals = run_code(injected);
|
|
|
|
|
async = save_async;
|
2021-01-19 23:27:32 +00:00
|
|
|
if (!Array.isArray(globals)) {
|
|
|
|
|
errorln();
|
|
|
|
|
errorln();
|
|
|
|
|
errorln("//-------------------------------------------------------------");
|
|
|
|
|
errorln("// !!! sort_globals() failed !!!");
|
|
|
|
|
errorln("// expected Array, got:");
|
2021-01-21 06:33:31 +00:00
|
|
|
if (!sandbox.is_error(globals)) try {
|
|
|
|
|
globals = JSON.stringify(globals);
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
errorln(globals);
|
2021-01-19 23:27:32 +00:00
|
|
|
errorln("//");
|
|
|
|
|
errorln(code);
|
|
|
|
|
errorln();
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2020-12-30 13:53:03 +00:00
|
|
|
return globals.length ? "var " + globals.map(function(name) {
|
|
|
|
|
return name + "=" + name;
|
2021-01-19 23:27:32 +00:00
|
|
|
}).join() + ";" + code : code;
|
2020-06-09 23:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:32:47 +00:00
|
|
|
function fuzzy_match(original, uglified) {
|
2021-01-19 23:27:32 +00:00
|
|
|
var m = [], n = [];
|
|
|
|
|
if (collect(original, m) !== collect(uglified, n)) return false;
|
|
|
|
|
for (var i = 0; i < m.length; i++) {
|
|
|
|
|
var a = m[i];
|
|
|
|
|
var b = n[i];
|
|
|
|
|
if (Math.abs((b - a) / a) > 1e-10) return false;
|
2019-12-16 15:32:47 +00:00
|
|
|
}
|
|
|
|
|
return true;
|
2021-01-19 23:27:32 +00:00
|
|
|
|
|
|
|
|
function collect(input, nums) {
|
2022-01-10 05:02:26 +00:00
|
|
|
return input.replace(/-?([1-9][0-9]*(\.[0-9]+)?|0\.[0-9]+)(e-?[1-9][0-9]*)?/gi, function(num) {
|
2021-01-19 23:27:32 +00:00
|
|
|
return "<|" + nums.push(+num) + "|>";
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-12-16 15:32:47 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-12 20:10:59 +00:00
|
|
|
function patch_proto() {
|
|
|
|
|
[ Array, Boolean, Error, Function, Number, Object, RegExp, String ].forEach(function(type) {
|
|
|
|
|
[ "toString", "valueOf" ].forEach(function(prop) {
|
|
|
|
|
type.prototype[prop] = function(fn) {
|
|
|
|
|
return function() {
|
|
|
|
|
try {
|
|
|
|
|
return fn.apply(this, arguments);
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
};
|
|
|
|
|
}(type.prototype[prop]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-20 13:03:33 +00:00
|
|
|
function is_error_timeout(ex) {
|
|
|
|
|
return /timed out/.test(ex.message);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-17 22:35:53 +00:00
|
|
|
function is_error_in(ex) {
|
|
|
|
|
return ex.name == "TypeError" && /'in'/.test(ex.message);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-26 15:17:47 +00:00
|
|
|
function is_error_tdz(ex) {
|
|
|
|
|
return ex.name == "ReferenceError";
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-17 22:35:53 +00:00
|
|
|
function is_error_spread(ex) {
|
2022-05-29 04:10:19 +00:00
|
|
|
return ex.name == "TypeError" && /Found non-callable @@iterator| is not iterable| not a function|Symbol\(Symbol\.iterator\)/.test(ex.message);
|
2021-01-17 22:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_error_recursion(ex) {
|
|
|
|
|
return ex.name == "RangeError" && /Invalid string length|Maximum call stack size exceeded/.test(ex.message);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-24 22:35:59 +00:00
|
|
|
function is_error_set_property(ex) {
|
|
|
|
|
return ex.name == "TypeError" && /^Cannot set propert[\s\S]+? of (null|undefined)/.test(ex.message);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-28 23:13:49 +00:00
|
|
|
function is_error_redeclaration(ex) {
|
|
|
|
|
return ex.name == "SyntaxError" && /already been declared|redeclaration/.test(ex.message);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-22 18:00:26 +00:00
|
|
|
function is_error_destructuring(ex) {
|
2022-05-21 17:36:45 +00:00
|
|
|
return ex.name == "TypeError" && /^Cannot (destructure|read propert)/.test(ex.message);
|
2021-01-22 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-23 14:55:08 +00:00
|
|
|
function is_error_class_constructor(ex) {
|
|
|
|
|
return ex.name == "TypeError" && /\bconstructors?\b/.test(ex.message) && /\bnew\b/.test(ex.message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_error_getter_only_property(ex) {
|
|
|
|
|
return ex.name == "TypeError" && [ "getter", "only", "property" ].every(function(keyword) {
|
|
|
|
|
return ex.message.indexOf(keyword) >= 0;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 06:21:45 +00:00
|
|
|
function patch_try_catch(orig, toplevel) {
|
2022-05-25 15:50:47 +00:00
|
|
|
var patched = Object.create(null);
|
2022-05-24 22:35:59 +00:00
|
|
|
var patches = [];
|
2020-06-09 11:07:02 +00:00
|
|
|
var stack = [ {
|
|
|
|
|
code: orig,
|
|
|
|
|
index: 0,
|
|
|
|
|
offset: 0,
|
|
|
|
|
tries: [],
|
|
|
|
|
} ];
|
2021-01-19 23:27:32 +00:00
|
|
|
var tail_throw = '\nif (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;\n';
|
2021-09-29 17:49:46 +00:00
|
|
|
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^()[{]+)\)|}\s*finally)\s*(?={)/g;
|
2020-06-09 11:07:02 +00:00
|
|
|
while (stack.length) {
|
|
|
|
|
var code = stack[0].code;
|
|
|
|
|
var offset = stack[0].offset;
|
|
|
|
|
var tries = stack[0].tries;
|
|
|
|
|
var match;
|
|
|
|
|
re.lastIndex = stack.shift().index;
|
|
|
|
|
while (match = re.exec(code)) {
|
|
|
|
|
var index = match.index + match[0].length + 1;
|
|
|
|
|
if (/(?:^|[\s{}):;])try\s*$/.test(match[0])) {
|
|
|
|
|
tries.unshift({ try: index - offset });
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
var insert;
|
|
|
|
|
if (/}\s*finally\s*$/.test(match[0])) {
|
|
|
|
|
tries.shift();
|
2021-01-19 23:27:32 +00:00
|
|
|
insert = tail_throw;
|
2020-06-09 11:07:02 +00:00
|
|
|
} else {
|
|
|
|
|
while (tries.length && tries[0].catch) tries.shift();
|
|
|
|
|
tries[0].catch = index - offset;
|
|
|
|
|
insert = [
|
|
|
|
|
"if (!" + match[1] + ".ufuzz_var) {",
|
|
|
|
|
match[1] + '.ufuzz_var = "' + match[1] + '";',
|
|
|
|
|
match[1] + ".ufuzz_try = " + tries[0].try + ";",
|
|
|
|
|
match[1] + ".ufuzz_catch = " + tries[0].catch + ";",
|
|
|
|
|
"UFUZZ_ERROR = " + match[1] + ";",
|
|
|
|
|
"}",
|
|
|
|
|
"throw " + match[1] + ";",
|
|
|
|
|
].join("\n");
|
|
|
|
|
}
|
2022-06-01 18:42:39 +00:00
|
|
|
var new_code = code.slice(0, index) + insert + code.slice(index) + tail_throw + "var UFUZZ_ERROR;";
|
2021-02-26 20:56:34 +00:00
|
|
|
var result = run_code(new_code, toplevel);
|
2021-01-21 18:33:00 +00:00
|
|
|
if (!sandbox.is_error(result)) {
|
2020-06-13 19:42:42 +00:00
|
|
|
if (!stack.filled && match[1]) stack.push({
|
2020-06-09 11:07:02 +00:00
|
|
|
code: code,
|
2020-07-20 13:57:22 +00:00
|
|
|
index: index && index - 1,
|
2020-06-09 11:07:02 +00:00
|
|
|
offset: offset,
|
|
|
|
|
tries: JSON.parse(JSON.stringify(tries)),
|
|
|
|
|
});
|
|
|
|
|
offset += insert.length;
|
|
|
|
|
code = new_code;
|
2021-01-17 22:35:53 +00:00
|
|
|
} else if (is_error_in(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("invalid `in`");');
|
2022-05-26 15:17:47 +00:00
|
|
|
} else if (is_error_tdz(result)) {
|
|
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("TDZ");');
|
2021-01-17 22:35:53 +00:00
|
|
|
} else if (is_error_spread(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("spread not iterable");');
|
2021-01-17 22:35:53 +00:00
|
|
|
} else if (is_error_recursion(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_try, 'throw new Error("skipping infinite recursion");');
|
2022-05-24 22:35:59 +00:00
|
|
|
} else if (is_error_set_property(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("cannot set property");');
|
2021-01-22 18:00:26 +00:00
|
|
|
} else if (is_error_destructuring(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("cannot destructure");');
|
2021-02-23 14:55:08 +00:00
|
|
|
} else if (is_error_class_constructor(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("missing new for class");');
|
2021-02-23 14:55:08 +00:00
|
|
|
} else if (is_error_getter_only_property(result)) {
|
2022-05-25 15:50:47 +00:00
|
|
|
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("setting getter-only property");');
|
2020-06-09 11:07:02 +00:00
|
|
|
}
|
2020-05-12 23:07:49 +00:00
|
|
|
}
|
2020-06-13 19:42:42 +00:00
|
|
|
stack.filled = true;
|
2020-05-12 23:07:49 +00:00
|
|
|
}
|
2022-05-24 22:35:59 +00:00
|
|
|
if (patches.length) return patches.reduce(function(code, patch) {
|
|
|
|
|
var index = patch[0];
|
|
|
|
|
return code.slice(0, index) + patch[1] + code.slice(index);
|
|
|
|
|
}, orig);
|
2022-05-25 15:50:47 +00:00
|
|
|
|
|
|
|
|
function patch(index, code) {
|
|
|
|
|
if (patched[index]) return;
|
|
|
|
|
patched[index] = true;
|
|
|
|
|
patches.unshift([ index, code ]);
|
|
|
|
|
}
|
2020-05-12 23:07:49 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-13 06:26:45 +00:00
|
|
|
var beautify_options = {
|
|
|
|
|
compress: false,
|
|
|
|
|
mangle: false,
|
|
|
|
|
output: {
|
|
|
|
|
beautify: true,
|
|
|
|
|
braces: true,
|
|
|
|
|
},
|
|
|
|
|
};
|
2020-11-17 00:01:24 +00:00
|
|
|
var minify_options = require("./options.json");
|
2022-04-18 05:03:01 +00:00
|
|
|
if (sandbox.is_error(sandbox.run_code("A:if (0) B:; else B:;"))) {
|
2020-12-27 05:32:18 +00:00
|
|
|
minify_options.forEach(function(o) {
|
|
|
|
|
if (!("mangle" in o)) o.mangle = {};
|
|
|
|
|
if (o.mangle) o.mangle.v8 = true;
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-02-08 20:28:23 +00:00
|
|
|
var bug_async_arrow_rest = function() {};
|
2022-04-18 05:03:01 +00:00
|
|
|
if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && sandbox.is_error(sandbox.run_code("async (a = f(...[], b)) => 0;"))) {
|
2021-02-08 20:28:23 +00:00
|
|
|
bug_async_arrow_rest = function(ex) {
|
2021-01-17 22:35:53 +00:00
|
|
|
return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter";
|
|
|
|
|
};
|
|
|
|
|
}
|
2022-05-19 16:00:24 +00:00
|
|
|
var bug_class_static_await = SUPPORT.async && SUPPORT.class_field && sandbox.is_error(sandbox.run_code("var await; class A { static p = await; }"));
|
|
|
|
|
var bug_class_static_nontrivial = SUPPORT.class_field && sandbox.is_error(sandbox.run_code("class A { static 42; static get 42() {} }"));
|
2022-04-18 05:03:01 +00:00
|
|
|
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 []); }"));
|
2022-06-07 15:28:06 +00:00
|
|
|
var bug_proto_stream = function(ex) {
|
|
|
|
|
return ex.name == "TypeError" && ex.message == "callback is not a function";
|
|
|
|
|
}
|
2022-04-18 05:03:01 +00:00
|
|
|
if (SUPPORT.destructuring && sandbox.is_error(sandbox.run_code("console.log([ 1 ], {} = 2);"))) {
|
2020-12-13 06:26:45 +00:00
|
|
|
beautify_options.output.v8 = true;
|
2020-11-17 00:01:24 +00:00
|
|
|
minify_options.forEach(function(o) {
|
|
|
|
|
if (!("output" in o)) o.output = {};
|
|
|
|
|
o.output.v8 = true;
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-12-13 06:26:45 +00:00
|
|
|
beautify_options = JSON.stringify(beautify_options);
|
2020-11-17 00:01:24 +00:00
|
|
|
minify_options = minify_options.map(JSON.stringify);
|
2022-04-18 05:03:01 +00:00
|
|
|
var original_code, original_result, original_erred;
|
2017-04-01 18:10:50 +00:00
|
|
|
var uglify_code, uglify_result, ok;
|
2017-04-01 19:17:01 +00:00
|
|
|
for (var round = 1; round <= num_iterations; round++) {
|
2017-03-24 17:46:12 +00:00
|
|
|
process.stdout.write(round + " of " + num_iterations + "\r");
|
2017-03-31 09:23:50 +00:00
|
|
|
|
2017-04-23 12:05:22 +00:00
|
|
|
original_code = createTopLevelCode();
|
2021-02-26 20:56:34 +00:00
|
|
|
var orig_result = [ run_code(original_code), run_code(original_code, true) ];
|
2021-02-08 12:17:14 +00:00
|
|
|
if (orig_result.some(function(result, toplevel) {
|
2022-04-18 05:03:01 +00:00
|
|
|
if (!sandbox.is_error(result)) return;
|
2020-12-23 22:22:55 +00:00
|
|
|
println();
|
|
|
|
|
println();
|
2020-10-11 17:18:57 +00:00
|
|
|
println("//=============================================================");
|
2021-02-08 12:17:14 +00:00
|
|
|
println("// original code" + (toplevel ? " (toplevel)" : ""));
|
|
|
|
|
try_beautify(original_code, toplevel, result, println);
|
2020-10-11 17:18:57 +00:00
|
|
|
println();
|
|
|
|
|
println();
|
|
|
|
|
println("original result:");
|
2021-02-08 12:17:14 +00:00
|
|
|
println(result);
|
2020-10-11 17:18:57 +00:00
|
|
|
println();
|
2021-12-11 22:19:06 +00:00
|
|
|
// ignore v8 parser bug
|
|
|
|
|
return bug_async_arrow_rest(result)
|
2022-06-07 15:28:06 +00:00
|
|
|
// ignore Node.js `__proto__` quirks
|
|
|
|
|
|| bug_proto_stream(result)
|
2021-12-11 22:19:06 +00:00
|
|
|
// ignore runtime platform bugs
|
|
|
|
|
|| result.message == "Script execution aborted.";
|
2021-02-08 12:17:14 +00:00
|
|
|
})) continue;
|
2020-10-11 17:18:57 +00:00
|
|
|
minify_options.forEach(function(options) {
|
2019-05-15 15:26:57 +00:00
|
|
|
var o = JSON.parse(options);
|
2022-06-06 14:52:22 +00:00
|
|
|
if (async && has_await) {
|
|
|
|
|
o.module = true;
|
|
|
|
|
options = JSON.stringify(o);
|
|
|
|
|
}
|
2020-02-29 17:33:48 +00:00
|
|
|
var toplevel = sandbox.has_toplevel(o);
|
2020-05-09 21:25:44 +00:00
|
|
|
o.validate = true;
|
2019-05-15 15:26:57 +00:00
|
|
|
uglify_code = UglifyJS.minify(original_code, o);
|
2020-02-29 17:33:48 +00:00
|
|
|
original_result = orig_result[toplevel ? 1 : 0];
|
2022-04-18 05:03:01 +00:00
|
|
|
original_erred = sandbox.is_error(original_result);
|
2017-05-09 07:58:46 +00:00
|
|
|
if (!uglify_code.error) {
|
|
|
|
|
uglify_code = uglify_code.code;
|
2021-02-26 20:56:34 +00:00
|
|
|
uglify_result = run_code(uglify_code, toplevel);
|
2017-04-01 18:10:50 +00:00
|
|
|
ok = sandbox.same_stdout(original_result, uglify_result);
|
2022-04-18 05:03:01 +00:00
|
|
|
var uglify_erred = sandbox.is_error(uglify_result);
|
2021-01-21 06:33:31 +00:00
|
|
|
// ignore v8 parser bug
|
2022-04-18 05:03:01 +00:00
|
|
|
if (!ok && uglify_erred && bug_async_arrow_rest(uglify_result)) ok = true;
|
2022-06-07 15:28:06 +00:00
|
|
|
// ignore Node.js `__proto__` quirks
|
|
|
|
|
if (!ok && uglify_erred && bug_proto_stream(uglify_result)) ok = true;
|
2021-12-11 22:19:06 +00:00
|
|
|
// ignore runtime platform bugs
|
2022-04-18 05:03:01 +00:00
|
|
|
if (!ok && uglify_erred && uglify_result.message == "Script execution aborted.") ok = true;
|
2021-02-13 13:15:11 +00:00
|
|
|
// handle difference caused by time-outs
|
2022-02-01 04:17:47 +00:00
|
|
|
if (!ok) {
|
2022-04-18 05:03:01 +00:00
|
|
|
if (original_erred && is_error_timeout(original_result)) {
|
|
|
|
|
if (uglify_erred && is_error_timeout(uglify_result)) {
|
2022-02-01 04:17:47 +00:00
|
|
|
// ignore difference in error message
|
|
|
|
|
ok = true;
|
|
|
|
|
} else {
|
|
|
|
|
// ignore spurious time-outs
|
|
|
|
|
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);
|
|
|
|
|
}
|
2022-04-18 05:03:01 +00:00
|
|
|
} else if (uglify_erred && is_error_timeout(uglify_result)) {
|
2021-02-13 13:15:11 +00:00
|
|
|
// ignore spurious time-outs
|
2022-02-01 04:17:47 +00:00
|
|
|
var waited_result = run_code(uglify_code, toplevel, 10000);
|
|
|
|
|
ok = sandbox.same_stdout(original_result, waited_result);
|
2021-02-13 13:15:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-05-07 19:21:44 +00:00
|
|
|
// ignore declaration order of global variables
|
2022-04-18 05:03:01 +00:00
|
|
|
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)));
|
|
|
|
|
}
|
2020-05-07 19:21:44 +00:00
|
|
|
}
|
|
|
|
|
// ignore numerical imprecision caused by `unsafe_math`
|
2022-04-18 05:03:01 +00:00
|
|
|
if (!ok && o.compress && o.compress.unsafe_math) {
|
|
|
|
|
if (typeof original_result == "string" && typeof uglify_result == "string") {
|
2021-01-19 23:27:32 +00:00
|
|
|
ok = fuzzy_match(original_result, uglify_result);
|
2022-04-18 05:03:01 +00:00
|
|
|
} else if (original_erred && uglify_erred) {
|
2021-01-19 23:27:32 +00:00
|
|
|
ok = original_result.name == uglify_result.name && fuzzy_match(original_result.message, uglify_result.message);
|
|
|
|
|
}
|
2019-12-16 15:32:47 +00:00
|
|
|
if (!ok) {
|
2021-02-26 20:56:34 +00:00
|
|
|
var fuzzy_result = run_code(original_code.replace(/( - 0\.1){3}/g, " - 0.3"), toplevel);
|
2020-01-06 03:26:15 +00:00
|
|
|
ok = sandbox.same_stdout(fuzzy_result, uglify_result);
|
2019-12-16 15:32:47 +00:00
|
|
|
}
|
2019-10-28 10:08:51 +00:00
|
|
|
}
|
2022-05-25 15:50:47 +00:00
|
|
|
if (!ok && original_erred && uglify_erred && (
|
|
|
|
|
// ignore difference in error message caused by `in`
|
2022-05-26 15:17:47 +00:00
|
|
|
is_error_in(original_result) && is_error_in(uglify_result)
|
|
|
|
|
// ignore difference in error message caused by Temporal Dead Zone
|
|
|
|
|
|| is_error_tdz(original_result) && is_error_tdz(uglify_result)
|
2022-05-25 15:50:47 +00:00
|
|
|
// ignore difference in error message caused by spread syntax
|
|
|
|
|
|| is_error_spread(original_result) && is_error_spread(uglify_result)
|
|
|
|
|
// ignore difference in error message caused by destructuring assignment
|
|
|
|
|
|| is_error_set_property(original_result) && is_error_set_property(uglify_result)
|
|
|
|
|
// ignore difference in error message caused by `import` symbol redeclaration
|
|
|
|
|
|| /\bimport\b/.test(original_code) && is_error_redeclaration(original_result) && is_error_redeclaration(uglify_result)
|
|
|
|
|
// ignore difference in error message caused by destructuring
|
|
|
|
|
|| is_error_destructuring(original_result) && is_error_destructuring(uglify_result)
|
|
|
|
|
// ignore difference in error message caused by call on class
|
|
|
|
|
|| is_error_class_constructor(original_result) && is_error_class_constructor(uglify_result)
|
|
|
|
|
// ignore difference in error message caused by setting getter-only property
|
|
|
|
|
|| is_error_getter_only_property(original_result) && is_error_getter_only_property(uglify_result)
|
|
|
|
|
)) ok = true;
|
2021-07-12 20:10:59 +00:00
|
|
|
// ignore difference due to `__proto__` assignment
|
|
|
|
|
if (!ok && /\b__proto__\b/.test(original_code)) {
|
|
|
|
|
var original_proto = run_code("(" + patch_proto + ")();\n" + original_code, toplevel);
|
|
|
|
|
var uglify_proto = run_code("(" + patch_proto + ")();\n" + uglify_code, toplevel);
|
|
|
|
|
ok = sandbox.same_stdout(original_proto, uglify_proto);
|
|
|
|
|
}
|
2020-05-12 23:07:49 +00:00
|
|
|
// ignore difference in depth of termination caused by infinite recursion
|
2022-04-18 05:03:01 +00:00
|
|
|
if (!ok && original_erred && is_error_recursion(original_result)) {
|
|
|
|
|
if (!uglify_erred || is_error_recursion(uglify_result)) ok = true;
|
2021-01-17 22:35:53 +00:00
|
|
|
}
|
|
|
|
|
// ignore errors above when caught by try-catch
|
2020-05-12 23:07:49 +00:00
|
|
|
if (!ok) {
|
2020-06-08 06:21:45 +00:00
|
|
|
var orig_skipped = patch_try_catch(original_code, toplevel);
|
|
|
|
|
var uglify_skipped = patch_try_catch(uglify_code, toplevel);
|
2020-05-12 23:07:49 +00:00
|
|
|
if (orig_skipped && uglify_skipped) {
|
2021-02-26 20:56:34 +00:00
|
|
|
ok = sandbox.same_stdout(run_code(orig_skipped, toplevel), run_code(uglify_skipped, toplevel));
|
2020-05-12 23:07:49 +00:00
|
|
|
}
|
|
|
|
|
}
|
2017-05-09 07:58:46 +00:00
|
|
|
} else {
|
2020-05-10 23:32:21 +00:00
|
|
|
uglify_code = uglify_code.error;
|
2022-04-18 05:03:01 +00:00
|
|
|
ok = original_erred && uglify_code.name == original_result.name;
|
2017-04-01 18:10:50 +00:00
|
|
|
}
|
|
|
|
|
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
2017-04-08 17:36:38 +00:00
|
|
|
if (!ok && isFinite(num_iterations)) {
|
2017-06-09 07:56:28 +00:00
|
|
|
println();
|
2017-04-08 17:36:38 +00:00
|
|
|
process.exit(1);
|
|
|
|
|
}
|
2017-04-01 18:10:50 +00:00
|
|
|
});
|
2017-03-24 17:46:12 +00:00
|
|
|
}
|
2017-06-09 07:56:28 +00:00
|
|
|
println();
|