inlining of static methods & constants (#2211)
- guard by `unsafe` - support `Array`, `Math`, `Number`, `Object` & `String` fixes #2207
This commit is contained in:
129
lib/compress.js
129
lib/compress.js
@@ -1718,6 +1718,40 @@ merge(Compressor.prototype, {
|
|||||||
this._eval = fixed._eval;
|
this._eval = fixed._eval;
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
var global_objs = {
|
||||||
|
Array: Array,
|
||||||
|
Boolean: Boolean,
|
||||||
|
Math: Math,
|
||||||
|
Number: Number,
|
||||||
|
RegExp: RegExp,
|
||||||
|
Object: Object,
|
||||||
|
String: String,
|
||||||
|
};
|
||||||
|
function convert_to_predicate(obj) {
|
||||||
|
for (var key in obj) {
|
||||||
|
obj[key] = makePredicate(obj[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var static_values = {
|
||||||
|
Math: [
|
||||||
|
"E",
|
||||||
|
"LN10",
|
||||||
|
"LN2",
|
||||||
|
"LOG2E",
|
||||||
|
"LOG10E",
|
||||||
|
"PI",
|
||||||
|
"SQRT1_2",
|
||||||
|
"SQRT2",
|
||||||
|
],
|
||||||
|
Number: [
|
||||||
|
"MAX_VALUE",
|
||||||
|
"MIN_VALUE",
|
||||||
|
"NaN",
|
||||||
|
"NEGATIVE_INFINITY",
|
||||||
|
"POSITIVE_INFINITY",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
convert_to_predicate(static_values);
|
||||||
def(AST_PropAccess, function(compressor){
|
def(AST_PropAccess, function(compressor){
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
var key = this.property;
|
var key = this.property;
|
||||||
@@ -1725,11 +1759,16 @@ merge(Compressor.prototype, {
|
|||||||
key = ev(key, compressor);
|
key = ev(key, compressor);
|
||||||
if (key === this.property) return this;
|
if (key === this.property) return this;
|
||||||
}
|
}
|
||||||
var val = ev(this.expression, compressor);
|
var exp = this.expression;
|
||||||
if (val === this.expression) return this;
|
var val;
|
||||||
if (val && HOP(val, key)) {
|
if (exp instanceof AST_SymbolRef && exp.undeclared()) {
|
||||||
return val[key];
|
if (!(static_values[exp.name] || return_false)(key)) return this;
|
||||||
|
val = global_objs[exp.name];
|
||||||
|
} else {
|
||||||
|
val = ev(exp, compressor);
|
||||||
|
if (!val || val === exp || !HOP(val, key)) return this;
|
||||||
}
|
}
|
||||||
|
return val[key];
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
});
|
});
|
||||||
@@ -1739,22 +1778,22 @@ merge(Compressor.prototype, {
|
|||||||
"valueOf",
|
"valueOf",
|
||||||
];
|
];
|
||||||
var native_fns = {
|
var native_fns = {
|
||||||
Array: makePredicate([
|
Array: [
|
||||||
"indexOf",
|
"indexOf",
|
||||||
"join",
|
"join",
|
||||||
"lastIndexOf",
|
"lastIndexOf",
|
||||||
"slice",
|
"slice",
|
||||||
].concat(object_fns)),
|
].concat(object_fns),
|
||||||
Boolean: makePredicate(object_fns),
|
Boolean: object_fns,
|
||||||
Number: makePredicate([
|
Number: [
|
||||||
"toExponential",
|
"toExponential",
|
||||||
"toFixed",
|
"toFixed",
|
||||||
"toPrecision",
|
"toPrecision",
|
||||||
].concat(object_fns)),
|
].concat(object_fns),
|
||||||
RegExp: makePredicate([
|
RegExp: [
|
||||||
"test",
|
"test",
|
||||||
].concat(object_fns)),
|
].concat(object_fns),
|
||||||
String: makePredicate([
|
String: [
|
||||||
"charAt",
|
"charAt",
|
||||||
"charCodeAt",
|
"charCodeAt",
|
||||||
"concat",
|
"concat",
|
||||||
@@ -1769,8 +1808,45 @@ merge(Compressor.prototype, {
|
|||||||
"substr",
|
"substr",
|
||||||
"substring",
|
"substring",
|
||||||
"trim",
|
"trim",
|
||||||
].concat(object_fns)),
|
].concat(object_fns),
|
||||||
};
|
};
|
||||||
|
convert_to_predicate(native_fns);
|
||||||
|
var static_fns = {
|
||||||
|
Array: [
|
||||||
|
"isArray",
|
||||||
|
],
|
||||||
|
Math: [
|
||||||
|
"abs",
|
||||||
|
"acos",
|
||||||
|
"asin",
|
||||||
|
"atan",
|
||||||
|
"ceil",
|
||||||
|
"cos",
|
||||||
|
"exp",
|
||||||
|
"floor",
|
||||||
|
"log",
|
||||||
|
"round",
|
||||||
|
"sin",
|
||||||
|
"sqrt",
|
||||||
|
"tan",
|
||||||
|
"atan2",
|
||||||
|
"pow",
|
||||||
|
"max",
|
||||||
|
"min"
|
||||||
|
],
|
||||||
|
Number: [
|
||||||
|
"isFinite",
|
||||||
|
"isNaN",
|
||||||
|
],
|
||||||
|
Object: [
|
||||||
|
"keys",
|
||||||
|
"getOwnPropertyNames",
|
||||||
|
],
|
||||||
|
String: [
|
||||||
|
"fromCharCode",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
convert_to_predicate(static_fns);
|
||||||
def(AST_Call, function(compressor){
|
def(AST_Call, function(compressor){
|
||||||
var exp = this.expression;
|
var exp = this.expression;
|
||||||
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
|
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
|
||||||
@@ -1779,18 +1855,23 @@ merge(Compressor.prototype, {
|
|||||||
key = ev(key, compressor);
|
key = ev(key, compressor);
|
||||||
if (key === exp.property) return this;
|
if (key === exp.property) return this;
|
||||||
}
|
}
|
||||||
var val = ev(exp.expression, compressor);
|
var val;
|
||||||
if (val === exp.expression) return this;
|
var e = exp.expression;
|
||||||
if ((val && native_fns[val.constructor.name] || return_false)(key)) {
|
if (e instanceof AST_SymbolRef && e.undeclared()) {
|
||||||
var args = [];
|
if (!(static_fns[e.name] || return_false)(key)) return this;
|
||||||
for (var i = 0, len = this.args.length; i < len; i++) {
|
val = global_objs[e.name];
|
||||||
var arg = this.args[i];
|
} else {
|
||||||
var value = ev(arg, compressor);
|
val = ev(e, compressor);
|
||||||
if (arg === value) return this;
|
if (val === e || !(val && native_fns[val.constructor.name] || return_false)(key)) return this;
|
||||||
args.push(value);
|
|
||||||
}
|
|
||||||
return val[key].apply(val, args);
|
|
||||||
}
|
}
|
||||||
|
var args = [];
|
||||||
|
for (var i = 0, len = this.args.length; i < len; i++) {
|
||||||
|
var arg = this.args[i];
|
||||||
|
var value = ev(arg, compressor);
|
||||||
|
if (arg === value) return this;
|
||||||
|
args.push(value);
|
||||||
|
}
|
||||||
|
return val[key].apply(val, args);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1085,3 +1085,75 @@ string_charCodeAt: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "NaN"
|
expect_stdout: "NaN"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2207_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(String.fromCharCode(65));
|
||||||
|
console.log(Math.max(3, 6, 2, 7, 3, 4));
|
||||||
|
console.log(Math.cos(1.2345));
|
||||||
|
console.log(Math.cos(1.2345) - Math.sin(4.321));
|
||||||
|
console.log(Math.pow(Math.PI, Math.E - Math.LN10));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("A");
|
||||||
|
console.log(7);
|
||||||
|
console.log(Math.cos(1.2345));
|
||||||
|
console.log(1.2543732512566947);
|
||||||
|
console.log(1.6093984514472044);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Math.E);
|
||||||
|
console.log(Math.LN10);
|
||||||
|
console.log(Math.LN2);
|
||||||
|
console.log(Math.LOG2E);
|
||||||
|
console.log(Math.LOG10E);
|
||||||
|
console.log(Math.PI);
|
||||||
|
console.log(Math.SQRT1_2);
|
||||||
|
console.log(Math.SQRT2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Math.E);
|
||||||
|
console.log(Math.LN10);
|
||||||
|
console.log(Math.LN2);
|
||||||
|
console.log(Math.LOG2E);
|
||||||
|
console.log(Math.LOG10E);
|
||||||
|
console.log(Math.PI);
|
||||||
|
console.log(Math.SQRT1_2);
|
||||||
|
console.log(Math.SQRT2);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Number.MAX_VALUE);
|
||||||
|
console.log(Number.MIN_VALUE);
|
||||||
|
console.log(Number.NaN);
|
||||||
|
console.log(Number.NEGATIVE_INFINITY);
|
||||||
|
console.log(Number.POSITIVE_INFINITY);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Number.MAX_VALUE);
|
||||||
|
console.log(5e-324);
|
||||||
|
console.log(NaN);
|
||||||
|
console.log(-1/0);
|
||||||
|
console.log(1/0);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user