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 ) {
matrix [ name ] = typeof sandbox . run _code ( matrix [ name ] ) == "string" ;
}
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() {} }" ,
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 ) ;
2020-06-07 21:23:23 +00:00
BINARY _OPS . push ( " in " ) ;
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
2017-03-24 17:46:12 +00:00
function rng ( max ) {
2017-04-01 21:11:29 +00:00
var r = randomBytes ( 2 ) . readUInt16LE ( 0 ) / 65536 ;
2017-04-01 09:09:52 +00:00
return Math . floor ( max * r ) ;
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 ;
2020-12-06 21:22:40 +00:00
async = false ;
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 ;
2021-02-23 14:55:08 +00:00
in _class = 0 ;
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 {
s . push ( createFunctions ( rng ( MAX _GENERATED _TOPLEVELS _PER _RUN ) + 1 , MAX _GENERATION _RECURSION _DEPTH , DEFUN _OK , CANNOT _THROW , 0 ) ) ;
}
} ) ;
// 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 = "" ;
2017-03-31 09:23:50 +00:00
while ( n -- > 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 = [ ] ;
for ( var n = rng ( 4 ) ; -- n >= 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 = [ ] ;
2020-12-11 19:43:12 +00:00
for ( var n = rng ( 4 ) ; -- n >= 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.
s . push ( createFunctions ( rng ( 5 ) + 1 , Math . ceil ( recurmax * 0.7 ) , DEFUN _OK , canThrow , stmtDepth ) ) ;
} 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 ) {
2019-10-27 06:17:35 +00:00
if ( -- recurmax < 0 ) { return ";" ; }
var s = "" ;
2017-03-31 09:23:50 +00:00
while ( -- n > 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 ) ;
2019-10-27 06:17:35 +00:00
return label . target + "{" + createStatements ( rng ( 5 ) + 1 , 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 = [ ] ;
for ( var i = rng ( 4 ) ; -- 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 ..."
// (dont both with func decls in `if`; it's only a parser thing because you cant 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
}
2019-10-27 06:17:35 +00:00
if ( n !== 0 ) s += " finally { " + createStatements ( 3 , recurmax , canThrow , canBreak , canContinue , cannotReturn , stmtDepth ) + " }" ;
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 ) + ":" ,
2020-10-11 17:18:57 +00:00
_createStatements ( rng ( 3 ) + 1 , 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:" ,
2020-10-11 17:18:57 +00:00
_createStatements ( rng ( 3 ) + 1 , 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 ( ) ,
_createStatements ( rng ( 5 ) + 1 , recurmax , canThrow , CANNOT _BREAK , CANNOT _CONTINUE , CAN _RETURN , stmtDepth )
) ;
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 ( ) ,
createStatements ( rng ( 5 ) + 1 , 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 ( ) ,
createStatements ( rng ( 5 ) + 1 , 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 ( ) ,
createStatements ( rng ( 5 ) + 1 , 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 ( ) ,
createStatements ( rng ( 5 ) + 1 , 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 ( ) ) ;
2020-10-11 17:18:57 +00:00
if ( instantiate ) for ( var i = rng ( 4 ) ; -- 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
}
2020-12-07 02:07:34 +00:00
s . push ( _createStatements ( rng ( 5 ) + 1 , 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 = [ ] ;
2020-12-11 19:43:12 +00:00
for ( var i = rng ( 6 ) ; -- 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 ( ) ;
for ( var i = rng ( 6 ) ; -- i >= 0 ; ) {
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 ;
2021-02-23 14:55:08 +00:00
if ( /^(constructor|super)$/ . test ( internal ) || rng ( 10 ) == 0 ) for ( var i = rng ( 4 ) ; -- i >= 0 ; ) {
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 ;
2020-12-11 19:43:12 +00:00
for ( var i = rng ( 6 ) ; -- 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 {
s += "(" + p + " && " + p + ".constructor === Function ? " + p + " : function() {})" ;
}
}
s += " {\n" ;
var declared = [ ] ;
for ( var i = rng ( 6 ) ; -- i >= 0 ; ) {
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 ) ) {
s += internal || createObjectKey ( recurmax , stmtDepth , canThrow ) ;
if ( rng ( 5 ) ) {
2021-04-22 02:58:50 +00:00
async = bug _async _class _await && fixed && 0 ;
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" ;
} 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 ) ] ;
} while ( noComma && op == "," || ! canThrow && op == " in " ) ;
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" :
2021-04-22 02:58:50 +00:00
return async !== false ;
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 ) {
exports . createTopLevelCode = createTopLevelCode ;
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 ) {
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 ) {
var beautified = UglifyJS . minify ( code , JSON . parse ( beautify _options ) ) ;
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 ;
if ( typeof uglify _code != "string" || uglified . error ) {
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 ) {
2018-01-18 06:08:05 +00:00
var flip = 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 ) ;
2020-05-20 20:00:38 +00:00
if ( typeof uglify _code != "string" ) {
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 ) ;
2020-05-20 20:00:38 +00:00
if ( typeof uglify _code != "string" ) {
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 ( "//-------------------------------------------------------------" ) ;
2017-03-31 21:47:11 +00:00
if ( typeof uglify _code == "string" ) {
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 21:47:11 +00:00
} else {
2017-06-09 07:56:28 +00:00
errorln ( "// !!! uglify failed !!!" ) ;
2019-10-07 06:36:00 +00:00
errorln ( uglify _code ) ;
2019-05-15 15:26:57 +00:00
if ( errored ) {
2017-06-09 07:56:28 +00:00
errorln ( ) ;
errorln ( ) ;
errorln ( "original stacktrace:" ) ;
2019-10-07 06:36:00 +00:00
errorln ( original _result ) ;
2017-04-23 12:05:22 +00:00
}
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 ) {
2021-02-26 20:56:34 +00:00
var globals = run _code ( "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 ) ;
} ;
2021-07-12 20:10:59 +00:00
} + "(this));\n" + code ) ;
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 ) ;
}
function is _error _spread ( ex ) {
2021-05-13 11:57:36 +00:00
return ex . name == "TypeError" && /Found non-callable @@iterator| is not iterable| not a function/ . 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 ) ;
}
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 ) {
return ex . name == "TypeError" && /^Cannot destructure / . test ( ex . message ) ;
}
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 ) {
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" ) ;
}
2021-01-19 23:27:32 +00:00
var new _code = code . slice ( 0 , index ) + insert + code . slice ( index ) + tail _throw ;
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 ) ) {
2020-06-09 11:07:02 +00:00
index = result . ufuzz _catch ;
return orig . slice ( 0 , index ) + result . ufuzz _var + ' = new Error("invalid `in`");' + orig . slice ( index ) ;
2021-01-17 22:35:53 +00:00
} else if ( is _error _spread ( result ) ) {
2020-12-05 21:19:31 +00:00
index = result . ufuzz _catch ;
return orig . slice ( 0 , index ) + result . ufuzz _var + ' = new Error("spread not iterable");' + orig . slice ( index ) ;
2021-01-17 22:35:53 +00:00
} else if ( is _error _recursion ( result ) ) {
2020-06-09 11:07:02 +00:00
index = result . ufuzz _try ;
return orig . slice ( 0 , index ) + 'throw new Error("skipping infinite recursion");' + orig . slice ( index ) ;
2021-01-22 18:00:26 +00:00
} else if ( is _error _destructuring ( result ) ) {
index = result . ufuzz _catch ;
return orig . slice ( 0 , index ) + result . ufuzz _var + ' = new Error("cannot destructure");' + orig . slice ( index ) ;
2021-02-23 14:55:08 +00:00
} else if ( is _error _class _constructor ( result ) ) {
index = result . ufuzz _catch ;
return orig . slice ( 0 , index ) + result . ufuzz _var + ' = new Error("missing new for class");' + orig . slice ( index ) ;
} else if ( is _error _getter _only _property ( result ) ) {
index = result . ufuzz _catch ;
return orig . slice ( 0 , index ) + result . ufuzz _var + ' = new Error("setting getter-only property");' + orig . slice ( index ) ;
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
}
}
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" ) ;
2020-12-27 05:32:18 +00:00
if ( typeof sandbox . run _code ( "A:if (0) B:; else B:;" ) != "string" ) {
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 ( ) { } ;
2021-01-17 22:35:53 +00:00
if ( SUPPORT . arrow && SUPPORT . async && SUPPORT . rest && typeof sandbox . run _code ( "async (a = f(...[], b)) => 0;" ) != "string" ) {
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" ;
} ;
}
2021-04-21 00:33:54 +00:00
var bug _async _class _await = SUPPORT . async && SUPPORT . class _field && typeof sandbox . run _code ( "var await; async function f() { class A { static p = await; } }" ) != "string" ;
var bug _for _of _async = SUPPORT . for _await _of && typeof sandbox . run _code ( "var async; for (async of []);" ) != "string" ;
2021-02-08 20:28:23 +00:00
var bug _for _of _var = SUPPORT . for _of && SUPPORT . let && typeof sandbox . run _code ( "try {} catch (e) { for (var e of []); }" ) != "string" ;
2020-12-11 19:43:12 +00:00
if ( SUPPORT . destructuring && typeof sandbox . run _code ( "console.log([ 1 ], {} = 2);" ) != "string" ) {
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 ) ;
2019-05-15 15:26:57 +00:00
var original _code , original _result , errored ;
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 ) {
if ( typeof result == "string" ) 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 )
// 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 ) ;
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 ] ;
2021-02-08 12:17:14 +00:00
errored = typeof original _result != "string" ;
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 ) ;
2021-01-21 06:33:31 +00:00
// ignore v8 parser bug
2021-02-08 20:28:23 +00:00
if ( ! ok && bug _async _arrow _rest ( uglify _result ) ) ok = true ;
2021-12-11 22:19:06 +00:00
// ignore runtime platform bugs
if ( ! ok && uglify _result . message == "Script execution aborted." ) ok = true ;
2021-02-13 13:15:11 +00:00
// handle difference caused by time-outs
if ( ! ok && errored && is _error _timeout ( original _result ) ) {
if ( is _error _timeout ( uglify _result ) ) {
// ignore difference in error message
ok = true ;
} else {
// ignore spurious time-outs
2021-02-26 20:56:34 +00:00
if ( ! orig _result [ toplevel ? 3 : 2 ] ) orig _result [ toplevel ? 3 : 2 ] = run _code ( original _code , toplevel , 10000 ) ;
2021-02-13 13:15:11 +00:00
ok = sandbox . same _stdout ( orig _result [ toplevel ? 3 : 2 ] , uglify _result ) ;
}
}
2020-05-07 19:21:44 +00:00
// ignore declaration order of global variables
2022-01-09 13:15:42 +00:00
if ( ! ok && ! toplevel && uglify _result . name != "SyntaxError" && original _result . name != "SyntaxError" ) {
2021-02-26 20:56:34 +00:00
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`
2021-01-19 23:27:32 +00:00
if ( ! ok && o . compress && o . compress . unsafe _math && typeof original _result == typeof uglify _result ) {
if ( typeof original _result == "string" ) {
ok = fuzzy _match ( original _result , uglify _result ) ;
} else if ( sandbox . is _error ( original _result ) ) {
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
}
2020-10-11 17:18:57 +00:00
// ignore difference in error message caused by Temporal Dead Zone
2020-10-30 03:06:48 +00:00
if ( ! ok && errored && uglify _result . name == "ReferenceError" && original _result . name == "ReferenceError" ) ok = true ;
2021-02-23 14:55:08 +00:00
// ignore difference due to implicit strict-mode in `class`
2022-01-09 21:05:35 +00:00
if ( ! ok && /\bclass\b/ . test ( original _code ) ) {
var original _strict = run _code ( '"use strict";\n' + original _code , toplevel ) ;
if ( /^(Syntax|Type)Error$/ . test ( uglify _result . name ) ) {
ok = typeof original _strict != "string" ;
} else {
ok = sandbox . same _stdout ( original _strict , uglify _result ) ;
}
2021-02-23 14:55:08 +00:00
}
2021-02-28 23:13:49 +00:00
// ignore difference in error message caused by `import` symbol redeclaration
if ( ! ok && errored && /\bimport\b/ . test ( original _code ) ) {
if ( is _error _redeclaration ( uglify _result ) && is _error _redeclaration ( original _result ) ) ok = true ;
}
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-06-08 06:21:45 +00:00
// ignore difference in error message caused by `in`
2021-01-17 22:35:53 +00:00
if ( ! ok && errored && is _error _in ( uglify _result ) && is _error _in ( original _result ) ) ok = true ;
2020-12-05 21:19:31 +00:00
// ignore difference in error message caused by spread syntax
2021-01-17 22:35:53 +00:00
if ( ! ok && errored && is _error _spread ( uglify _result ) && is _error _spread ( original _result ) ) ok = true ;
2020-05-12 23:07:49 +00:00
// ignore difference in depth of termination caused by infinite recursion
2021-01-17 22:35:53 +00:00
if ( ! ok && errored && is _error _recursion ( original _result ) ) {
if ( is _error _recursion ( uglify _result ) || typeof uglify _result == "string" ) ok = true ;
}
2021-01-22 18:00:26 +00:00
// ignore difference in error message caused by destructuring
if ( ! ok && errored && is _error _destructuring ( uglify _result ) && is _error _destructuring ( original _result ) ) {
ok = true ;
}
2021-02-23 14:55:08 +00:00
// ignore difference in error message caused by call on class
if ( ! ok && errored && is _error _class _constructor ( uglify _result ) && is _error _class _constructor ( original _result ) ) {
ok = true ;
}
// ignore difference in error message caused by setting getter-only property
if ( ! ok && errored && is _error _getter _only _property ( uglify _result ) && is _error _getter _only _property ( original _result ) ) {
ok = true ;
}
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 ;
ok = errored && 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 ( ) ;