enable unsafe for test/ufuzz.js (#2819)

- introduce `unsafe_undefined`
- safer `.toString()` compression

Miscellaneous
- rename `unsafe_Function`
This commit is contained in:
Alex Lam S.L
2018-01-19 23:47:42 +08:00
committed by GitHub
parent 3e7873217c
commit 069df27bf1
7 changed files with 28 additions and 18 deletions

View File

@@ -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 comparison are switching. Compression only works if both `comparisons` and
`unsafe_comps` are both set to true. `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. when both `args` and `code` are string literals.
- `unsafe_math` (default: `false`) -- optimize numerical expressions like - `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 - `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
`RegExp` values the same way as if they are constants. `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 - `unused` (default: `true`) -- drop unreferenced functions and variables (simple
direct variable assignments do not count as references unless set to `"keep_assign"`) direct variable assignments do not count as references unless set to `"keep_assign"`)
@@ -922,9 +926,6 @@ when this flag is on:
- `new Object()``{}` - `new Object()``{}`
- `String(exp)` or `exp.toString()``"" + exp` - `String(exp)` or `exp.toString()``"" + exp`
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new` - `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 ### Conditional compilation

View File

@@ -84,10 +84,11 @@ function Compressor(options, false_by_default) {
typeofs : !false_by_default, typeofs : !false_by_default,
unsafe : false, unsafe : false,
unsafe_comps : false, unsafe_comps : false,
unsafe_Func : false, unsafe_Function: false,
unsafe_math : false, unsafe_math : false,
unsafe_proto : false, unsafe_proto : false,
unsafe_regexp : false, unsafe_regexp : false,
unsafe_undefined: false,
unused : !false_by_default, unused : !false_by_default,
warnings : false, warnings : false,
}, true); }, true);
@@ -4100,11 +4101,13 @@ merge(Compressor.prototype, {
break; break;
} else if (exp instanceof AST_Dot) switch(exp.property) { } else if (exp instanceof AST_Dot) switch(exp.property) {
case "toString": case "toString":
if (self.args.length == 0) return make_node(AST_Binary, self, { if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) {
left: make_node(AST_String, self, { value: "" }), return make_node(AST_Binary, self, {
operator: "+", left: make_node(AST_String, self, { value: "" }),
right: exp.expression operator: "+",
}).optimize(compressor); right: exp.expression
}).optimize(compressor);
}
break; break;
case "join": case "join":
if (exp.expression instanceof AST_Array) EXIT: { if (exp.expression instanceof AST_Array) EXIT: {
@@ -4212,7 +4215,7 @@ merge(Compressor.prototype, {
break; break;
} }
} }
if (compressor.option("unsafe_Func") if (compressor.option("unsafe_Function")
&& is_undeclared_ref(exp) && is_undeclared_ref(exp)
&& exp.name == "Function") { && exp.name == "Function") {
// new Function() => function(){} // new Function() => function(){}
@@ -5220,7 +5223,7 @@ merge(Compressor.prototype, {
} }
OPT(AST_Undefined, function(self, compressor){ OPT(AST_Undefined, function(self, compressor){
if (compressor.option("unsafe")) { if (compressor.option("unsafe_undefined")) {
var undef = find_variable(compressor, "undefined"); var undef = find_variable(compressor, "undefined");
if (undef) { if (undef) {
var ref = make_node(AST_SymbolRef, self, { var ref = make_node(AST_SymbolRef, self, {

View File

@@ -218,7 +218,7 @@ issue_203: {
options = { options = {
keep_fargs: false, keep_fargs: false,
side_effects: true, side_effects: true,
unsafe_Func: true, unsafe_Function: true,
unused: true, unused: true,
} }
input: { input: {

View File

@@ -4,7 +4,7 @@ unsafe_undefined: {
options = { options = {
conditionals: true, conditionals: true,
if_return: true, if_return: true,
unsafe: true unsafe_undefined: true,
} }
mangle = {} mangle = {}
input: { input: {
@@ -30,7 +30,7 @@ keep_fnames: {
options = { options = {
conditionals: true, conditionals: true,
if_return: true, if_return: true,
unsafe: true unsafe_undefined: true,
} }
mangle = { mangle = {
keep_fnames: true keep_fnames: true

View File

@@ -61,7 +61,7 @@ unsafe_undefined: {
options = { options = {
conditionals: true, conditionals: true,
if_return: true, if_return: true,
unsafe: true, unsafe_undefined: true,
} }
mangle = {} mangle = {}
input: { input: {

View File

@@ -288,7 +288,7 @@ unsafe_undefined: {
if_return: true, if_return: true,
sequences: true, sequences: true,
side_effects: true, side_effects: true,
unsafe: true, unsafe_undefined: true,
} }
input: { input: {
function f(undefined) { function f(undefined) {

View File

@@ -21,7 +21,13 @@
{ {
"compress": { "compress": {
"keep_fargs": false, "keep_fargs": false,
"passes": 100 "passes": 1e6,
"sequences": 1e6,
"unsafe": true,
"unsafe_Function": true,
"unsafe_math": true,
"unsafe_proto": true,
"unsafe_regexp": true
} }
} }
] ]