this._eval = fixed._eval;
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){
if (compressor.option("unsafe")) {
var key = this.property;
key = ev(key, compressor);
if (key === this.property) return this;
}
- var val = ev(this.expression, compressor);
- if (val === this.expression) return this;
- if (val && HOP(val, key)) {
- return val[key];
+ var exp = this.expression;
+ var val;
+ if (exp instanceof AST_SymbolRef && exp.undeclared()) {
+ 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;
});
"valueOf",
];
var native_fns = {
- Array: makePredicate([
+ Array: [
"indexOf",
"join",
"lastIndexOf",
"slice",
- ].concat(object_fns)),
- Boolean: makePredicate(object_fns),
- Number: makePredicate([
+ ].concat(object_fns),
+ Boolean: object_fns,
+ Number: [
"toExponential",
"toFixed",
"toPrecision",
- ].concat(object_fns)),
- RegExp: makePredicate([
+ ].concat(object_fns),
+ RegExp: [
"test",
- ].concat(object_fns)),
- String: makePredicate([
+ ].concat(object_fns),
+ String: [
"charAt",
"charCodeAt",
"concat",
"substr",
"substring",
"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){
var exp = this.expression;
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
key = ev(key, compressor);
if (key === exp.property) return this;
}
- var val = ev(exp.expression, compressor);
- if (val === exp.expression) return this;
- if ((val && native_fns[val.constructor.name] || return_false)(key)) {
- 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);
+ var val;
+ var e = exp.expression;
+ if (e instanceof AST_SymbolRef && e.undeclared()) {
+ if (!(static_fns[e.name] || return_false)(key)) return this;
+ val = global_objs[e.name];
+ } else {
+ val = ev(e, compressor);
+ if (val === e || !(val && native_fns[val.constructor.name] || return_false)(key)) return this;
+ }
+ 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;
});
}
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
+}