From 20bfd05f64071cbbfb866a0cb5c0a4fee9d015bb Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Fri, 19 Jan 2018 22:55:12 +0800 Subject: [PATCH] enable `unsafe` for `test/ufuzz.js` - introduce `unsafe_undefined` - safer `.toString()` compression Miscellaneous - rename `unsafe_Function` --- README.md | 9 +++++---- lib/compress.js | 19 +++++++++++-------- test/compress/functions.js | 2 +- test/compress/issue-1443.js | 4 ++-- test/compress/issue-1588.js | 2 +- test/compress/sequences.js | 2 +- test/ufuzz.json | 8 +++++++- 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index df90d1ca85..99e33af77c 100644 --- a/README.md +++ b/README.md @@ -737,7 +737,7 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u comparison are switching. Compression only works if both `comparisons` and `unsafe_comps` are both set to true. -- `unsafe_Func` (default: `false`) -- compress and mangle `Function(args, code)` +- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)` when both `args` and `code` are string literals. - `unsafe_math` (default: `false`) -- optimize numerical expressions like @@ -749,6 +749,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u - `unsafe_regexp` (default: `false`) -- enable substitutions of variables with `RegExp` values the same way as if they are constants. +- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a + variable named `undefined` in scope (variable name will be mangled, typically + reduced to a single character) + - `unused` (default: `true`) -- drop unreferenced functions and variables (simple direct variable assignments do not count as references unless set to `"keep_assign"`) @@ -922,9 +926,6 @@ when this flag is on: - `new Object()` → `{}` - `String(exp)` or `exp.toString()` → `"" + exp` - `new Object/RegExp/Function/Error/Array (...)` → we discard the `new` -- `void 0` → `undefined` (if there is a variable named "undefined" in - scope; we do it because the variable name will be mangled, typically - reduced to a single character) ### Conditional compilation diff --git a/lib/compress.js b/lib/compress.js index 5235a05ff5..49185aec6f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -84,10 +84,11 @@ function Compressor(options, false_by_default) { typeofs : !false_by_default, unsafe : false, unsafe_comps : false, - unsafe_Func : false, + unsafe_Function: false, unsafe_math : false, unsafe_proto : false, unsafe_regexp : false, + unsafe_undefined: false, unused : !false_by_default, warnings : false, }, true); @@ -4100,11 +4101,13 @@ merge(Compressor.prototype, { break; } else if (exp instanceof AST_Dot) switch(exp.property) { case "toString": - if (self.args.length == 0) return make_node(AST_Binary, self, { - left: make_node(AST_String, self, { value: "" }), - operator: "+", - right: exp.expression - }).optimize(compressor); + if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) { + return make_node(AST_Binary, self, { + left: make_node(AST_String, self, { value: "" }), + operator: "+", + right: exp.expression + }).optimize(compressor); + } break; case "join": if (exp.expression instanceof AST_Array) EXIT: { @@ -4212,7 +4215,7 @@ merge(Compressor.prototype, { break; } } - if (compressor.option("unsafe_Func") + if (compressor.option("unsafe_Function") && is_undeclared_ref(exp) && exp.name == "Function") { // new Function() => function(){} @@ -5220,7 +5223,7 @@ merge(Compressor.prototype, { } OPT(AST_Undefined, function(self, compressor){ - if (compressor.option("unsafe")) { + if (compressor.option("unsafe_undefined")) { var undef = find_variable(compressor, "undefined"); if (undef) { var ref = make_node(AST_SymbolRef, self, { diff --git a/test/compress/functions.js b/test/compress/functions.js index 2d55dd521d..8732882007 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -218,7 +218,7 @@ issue_203: { options = { keep_fargs: false, side_effects: true, - unsafe_Func: true, + unsafe_Function: true, unused: true, } input: { diff --git a/test/compress/issue-1443.js b/test/compress/issue-1443.js index 304a71ac0c..18554ff69b 100644 --- a/test/compress/issue-1443.js +++ b/test/compress/issue-1443.js @@ -4,7 +4,7 @@ unsafe_undefined: { options = { conditionals: true, if_return: true, - unsafe: true + unsafe_undefined: true, } mangle = {} input: { @@ -30,7 +30,7 @@ keep_fnames: { options = { conditionals: true, if_return: true, - unsafe: true + unsafe_undefined: true, } mangle = { keep_fnames: true diff --git a/test/compress/issue-1588.js b/test/compress/issue-1588.js index 187d9f6cf8..40efb63b72 100644 --- a/test/compress/issue-1588.js +++ b/test/compress/issue-1588.js @@ -61,7 +61,7 @@ unsafe_undefined: { options = { conditionals: true, if_return: true, - unsafe: true, + unsafe_undefined: true, } mangle = {} input: { diff --git a/test/compress/sequences.js b/test/compress/sequences.js index 2c900796fb..03075bf16b 100644 --- a/test/compress/sequences.js +++ b/test/compress/sequences.js @@ -288,7 +288,7 @@ unsafe_undefined: { if_return: true, sequences: true, side_effects: true, - unsafe: true, + unsafe_undefined: true, } input: { function f(undefined) { diff --git a/test/ufuzz.json b/test/ufuzz.json index f04b641733..5ccd96e065 100644 --- a/test/ufuzz.json +++ b/test/ufuzz.json @@ -21,7 +21,13 @@ { "compress": { "keep_fargs": false, - "passes": 100 + "passes": 1e6, + "sequences": 1e6, + "unsafe": true, + "unsafe_Function": true, + "unsafe_math": true, + "unsafe_proto": true, + "unsafe_regexp": true } } ]