Hide Math function implementations in a closure.
R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/990883002 Cr-Commit-Position: refs/heads/master@{#27072}
This commit is contained in:
parent
6f559b7ec3
commit
67bc45c278
2
BUILD.gn
2
BUILD.gn
@ -173,8 +173,8 @@ action("js2c") {
|
||||
"src/array.js",
|
||||
"src/string.js",
|
||||
"src/uri.js",
|
||||
"src/third_party/fdlibm/fdlibm.js",
|
||||
"src/math.js",
|
||||
"src/third_party/fdlibm/fdlibm.js",
|
||||
"src/date.js",
|
||||
"src/regexp.js",
|
||||
"src/arraybuffer.js",
|
||||
|
@ -240,7 +240,7 @@ function SparseMove(array, start_i, del_count, len, num_additional_args) {
|
||||
// Move data to new array.
|
||||
var new_array = new InternalArray(
|
||||
// Clamp array length to 2^32-1 to avoid early RangeError.
|
||||
MathMin(len - del_count + num_additional_args, 0xffffffff));
|
||||
$min(len - del_count + num_additional_args, 0xffffffff));
|
||||
var big_indices;
|
||||
var indices = %GetArrayKeys(array, len);
|
||||
if (IS_NUMBER(indices)) {
|
||||
|
@ -39,16 +39,16 @@ function ArrayBufferSlice(start, end) {
|
||||
var first;
|
||||
var byte_length = %_ArrayBufferGetByteLength(this);
|
||||
if (relativeStart < 0) {
|
||||
first = MathMax(byte_length + relativeStart, 0);
|
||||
first = $max(byte_length + relativeStart, 0);
|
||||
} else {
|
||||
first = MathMin(relativeStart, byte_length);
|
||||
first = $min(relativeStart, byte_length);
|
||||
}
|
||||
var relativeEnd = IS_UNDEFINED(end) ? byte_length : end;
|
||||
var fin;
|
||||
if (relativeEnd < 0) {
|
||||
fin = MathMax(byte_length + relativeEnd, 0);
|
||||
fin = $max(byte_length + relativeEnd, 0);
|
||||
} else {
|
||||
fin = MathMin(relativeEnd, byte_length);
|
||||
fin = $min(relativeEnd, byte_length);
|
||||
}
|
||||
|
||||
if (fin < first) {
|
||||
|
@ -230,8 +230,8 @@ function LocalTimezoneString(date) {
|
||||
|
||||
var timezoneOffset = -TIMEZONE_OFFSET(date);
|
||||
var sign = (timezoneOffset >= 0) ? 1 : -1;
|
||||
var hours = FLOOR((sign * timezoneOffset)/60);
|
||||
var min = FLOOR((sign * timezoneOffset)%60);
|
||||
var hours = $floor((sign * timezoneOffset)/60);
|
||||
var min = $floor((sign * timezoneOffset)%60);
|
||||
var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
|
||||
TwoDigitString(hours) + TwoDigitString(min);
|
||||
return gmt + ' (' + timezone + ')';
|
||||
@ -684,7 +684,7 @@ function DateToGMTString() {
|
||||
|
||||
function PadInt(n, digits) {
|
||||
if (digits == 1) return n;
|
||||
return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
|
||||
return n < %_MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,7 +52,7 @@ function StringStartsWith(searchString /* position */) { // length == 1
|
||||
}
|
||||
|
||||
var s_len = s.length;
|
||||
var start = MathMin(MathMax(pos, 0), s_len);
|
||||
var start = $min($max(pos, 0), s_len);
|
||||
var ss_len = ss.length;
|
||||
if (ss_len + start > s_len) {
|
||||
return false;
|
||||
@ -83,7 +83,7 @@ function StringEndsWith(searchString /* position */) { // length == 1
|
||||
}
|
||||
}
|
||||
|
||||
var end = MathMin(MathMax(pos, 0), s_len);
|
||||
var end = $min($max(pos, 0), s_len);
|
||||
var ss_len = ss.length;
|
||||
var start = end - ss_len;
|
||||
if (start < 0) {
|
||||
@ -113,7 +113,7 @@ function StringIncludes(searchString /* position */) { // length == 1
|
||||
}
|
||||
|
||||
var s_len = s.length;
|
||||
var start = MathMin(MathMax(pos, 0), s_len);
|
||||
var start = $min($max(pos, 0), s_len);
|
||||
var ss_len = ss.length;
|
||||
if (ss_len + start > s_len) {
|
||||
return false;
|
||||
|
@ -178,7 +178,7 @@ function JSONStringify(value, replacer, space) {
|
||||
}
|
||||
var gap;
|
||||
if (IS_NUMBER(space)) {
|
||||
space = MathMax(0, MathMin(ToInteger(space), 10));
|
||||
space = $max(0, $min(ToInteger(space), 10));
|
||||
gap = %_SubString(" ", 0, space);
|
||||
} else if (IS_STRING(space)) {
|
||||
if (space.length > 10) {
|
||||
|
@ -111,7 +111,6 @@ macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
|
||||
macro IS_SET_ITERATOR(arg) = (%_ClassOf(arg) === 'Set Iterator');
|
||||
macro IS_MAP_ITERATOR(arg) = (%_ClassOf(arg) === 'Map Iterator');
|
||||
macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(arg));
|
||||
macro FLOOR(arg) = $floor(arg);
|
||||
|
||||
# Macro for ECMAScript 5 queries of the type:
|
||||
# "Type(O) is object."
|
||||
|
145
src/math.js
145
src/math.js
@ -8,19 +8,23 @@
|
||||
// in runtime.js:
|
||||
// var $Object = global.Object;
|
||||
|
||||
// Keep reference to original values of some global properties. This
|
||||
// has the added benefit that the code in this file is isolated from
|
||||
// changes to these properties.
|
||||
var $floor = MathFloor;
|
||||
var $abs = MathAbs;
|
||||
|
||||
// Instance class name can only be set on functions. That is the only
|
||||
// purpose for MathConstructor.
|
||||
function MathConstructor() {}
|
||||
var $Math = new MathConstructor();
|
||||
|
||||
var rngstate; // Initialized to a Uint32Array during genesis.
|
||||
|
||||
var $abs;
|
||||
var $exp;
|
||||
var $floor;
|
||||
var $max;
|
||||
var $min;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
(function() {
|
||||
|
||||
// ECMA 262 - 15.8.2.1
|
||||
function MathAbs(x) {
|
||||
if (%_IsSmi(x)) return x >= 0 ? x : -x;
|
||||
@ -142,7 +146,6 @@ function MathPow(x, y) {
|
||||
}
|
||||
|
||||
// ECMA 262 - 15.8.2.14
|
||||
var rngstate; // Initialized to a Uint32Array during genesis.
|
||||
function MathRandom() {
|
||||
var r0 = (MathImul(18030, rngstate[0] & 0xFFFF) + (rngstate[0] >>> 16)) | 0;
|
||||
rngstate[0] = r0;
|
||||
@ -303,75 +306,71 @@ function CubeRoot(x) {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function SetUpMath() {
|
||||
%CheckIsBootstrapping();
|
||||
%CheckIsBootstrapping();
|
||||
|
||||
%InternalSetPrototype($Math, $Object.prototype);
|
||||
%AddNamedProperty(global, "Math", $Math, DONT_ENUM);
|
||||
%FunctionSetInstanceClassName(MathConstructor, 'Math');
|
||||
%InternalSetPrototype($Math, $Object.prototype);
|
||||
%AddNamedProperty(global, "Math", $Math, DONT_ENUM);
|
||||
%FunctionSetInstanceClassName(MathConstructor, 'Math');
|
||||
|
||||
%AddNamedProperty($Math, symbolToStringTag, "Math", READ_ONLY | DONT_ENUM);
|
||||
%AddNamedProperty($Math, symbolToStringTag, "Math", READ_ONLY | DONT_ENUM);
|
||||
|
||||
// Set up math constants.
|
||||
InstallConstants($Math, $Array(
|
||||
// ECMA-262, section 15.8.1.1.
|
||||
"E", 2.7182818284590452354,
|
||||
// ECMA-262, section 15.8.1.2.
|
||||
"LN10", 2.302585092994046,
|
||||
// ECMA-262, section 15.8.1.3.
|
||||
"LN2", 0.6931471805599453,
|
||||
// ECMA-262, section 15.8.1.4.
|
||||
"LOG2E", 1.4426950408889634,
|
||||
"LOG10E", 0.4342944819032518,
|
||||
"PI", 3.1415926535897932,
|
||||
"SQRT1_2", 0.7071067811865476,
|
||||
"SQRT2", 1.4142135623730951
|
||||
));
|
||||
// Set up math constants.
|
||||
InstallConstants($Math, $Array(
|
||||
// ECMA-262, section 15.8.1.1.
|
||||
"E", 2.7182818284590452354,
|
||||
// ECMA-262, section 15.8.1.2.
|
||||
"LN10", 2.302585092994046,
|
||||
// ECMA-262, section 15.8.1.3.
|
||||
"LN2", 0.6931471805599453,
|
||||
// ECMA-262, section 15.8.1.4.
|
||||
"LOG2E", 1.4426950408889634,
|
||||
"LOG10E", 0.4342944819032518,
|
||||
"PI", 3.1415926535897932,
|
||||
"SQRT1_2", 0.7071067811865476,
|
||||
"SQRT2", 1.4142135623730951
|
||||
));
|
||||
|
||||
// Set up non-enumerable functions of the Math object and
|
||||
// set their names.
|
||||
InstallFunctions($Math, DONT_ENUM, $Array(
|
||||
"random", MathRandom,
|
||||
"abs", MathAbs,
|
||||
"acos", MathAcosJS,
|
||||
"asin", MathAsinJS,
|
||||
"atan", MathAtanJS,
|
||||
"ceil", MathCeil,
|
||||
"cos", MathCos, // implemented by third_party/fdlibm
|
||||
"exp", MathExp,
|
||||
"floor", MathFloor,
|
||||
"log", MathLog,
|
||||
"round", MathRound,
|
||||
"sin", MathSin, // implemented by third_party/fdlibm
|
||||
"sqrt", MathSqrt,
|
||||
"tan", MathTan, // implemented by third_party/fdlibm
|
||||
"atan2", MathAtan2JS,
|
||||
"pow", MathPow,
|
||||
"max", MathMax,
|
||||
"min", MathMin,
|
||||
"imul", MathImul,
|
||||
"sign", MathSign,
|
||||
"trunc", MathTrunc,
|
||||
"sinh", MathSinh, // implemented by third_party/fdlibm
|
||||
"cosh", MathCosh, // implemented by third_party/fdlibm
|
||||
"tanh", MathTanh,
|
||||
"asinh", MathAsinh,
|
||||
"acosh", MathAcosh,
|
||||
"atanh", MathAtanh,
|
||||
"log10", MathLog10, // implemented by third_party/fdlibm
|
||||
"log2", MathLog2, // implemented by third_party/fdlibm
|
||||
"hypot", MathHypot,
|
||||
"fround", MathFroundJS,
|
||||
"clz32", MathClz32,
|
||||
"cbrt", MathCbrt,
|
||||
"log1p", MathLog1p, // implemented by third_party/fdlibm
|
||||
"expm1", MathExpm1 // implemented by third_party/fdlibm
|
||||
));
|
||||
// Set up non-enumerable functions of the Math object and
|
||||
// set their names.
|
||||
InstallFunctions($Math, DONT_ENUM, $Array(
|
||||
"random", MathRandom,
|
||||
"abs", MathAbs,
|
||||
"acos", MathAcosJS,
|
||||
"asin", MathAsinJS,
|
||||
"atan", MathAtanJS,
|
||||
"ceil", MathCeil,
|
||||
"exp", MathExp,
|
||||
"floor", MathFloor,
|
||||
"log", MathLog,
|
||||
"round", MathRound,
|
||||
"sqrt", MathSqrt,
|
||||
"atan2", MathAtan2JS,
|
||||
"pow", MathPow,
|
||||
"max", MathMax,
|
||||
"min", MathMin,
|
||||
"imul", MathImul,
|
||||
"sign", MathSign,
|
||||
"trunc", MathTrunc,
|
||||
"tanh", MathTanh,
|
||||
"asinh", MathAsinh,
|
||||
"acosh", MathAcosh,
|
||||
"atanh", MathAtanh,
|
||||
"hypot", MathHypot,
|
||||
"fround", MathFroundJS,
|
||||
"clz32", MathClz32,
|
||||
"cbrt", MathCbrt
|
||||
));
|
||||
|
||||
%SetInlineBuiltinFlag(MathCeil);
|
||||
%SetInlineBuiltinFlag(MathRandom);
|
||||
%SetInlineBuiltinFlag(MathSin);
|
||||
%SetInlineBuiltinFlag(MathCos);
|
||||
}
|
||||
%SetInlineBuiltinFlag(MathCeil);
|
||||
%SetInlineBuiltinFlag(MathRandom);
|
||||
|
||||
SetUpMath();
|
||||
// Keep reference to original values of some global properties. This
|
||||
// has the added benefit that the code in this file is isolated from
|
||||
// changes to these properties.
|
||||
$abs = MathAbs;
|
||||
$exp = MathExp;
|
||||
$floor = MathFloor;
|
||||
$max = MathMax;
|
||||
$min = MathMin;
|
||||
|
||||
})();
|
||||
|
43
src/third_party/fdlibm/fdlibm.js
vendored
43
src/third_party/fdlibm/fdlibm.js
vendored
@ -28,6 +28,8 @@
|
||||
var kMath;
|
||||
var rempio2result;
|
||||
|
||||
(function() {
|
||||
|
||||
const INVPIO2 = kMath[0];
|
||||
const PIO2_1 = kMath[1];
|
||||
const PIO2_1T = kMath[2];
|
||||
@ -79,7 +81,7 @@ macro REMPIO2(X)
|
||||
}
|
||||
} else if (ix <= 0x413921fb) {
|
||||
// |X| ~<= 2^19*(pi/2), medium size
|
||||
var t = MathAbs(X);
|
||||
var t = $abs(X);
|
||||
n = (t * INVPIO2 + 0.5) | 0;
|
||||
var r = t - n * PIO2_1;
|
||||
var w = n * PIO2_1T;
|
||||
@ -261,7 +263,7 @@ function KernelTan(x, y, returnTan) {
|
||||
if (ix < 0x3e300000) { // |x| < 2^-28
|
||||
if (((ix | %_DoubleLo(x)) | (returnTan + 1)) == 0) {
|
||||
// x == 0 && returnTan = -1
|
||||
return 1 / MathAbs(x);
|
||||
return 1 / $abs(x);
|
||||
} else {
|
||||
if (returnTan == 1) {
|
||||
return x;
|
||||
@ -749,7 +751,7 @@ function MathSinh(x) {
|
||||
x = x * 1; // Convert to number.
|
||||
var h = (x < 0) ? -0.5 : 0.5;
|
||||
// |x| in [0, 22]. return sign(x)*0.5*(E+E/(E+1))
|
||||
var ax = MathAbs(x);
|
||||
var ax = $abs(x);
|
||||
if (ax < 22) {
|
||||
// For |x| < 2^-28, sinh(x) = x
|
||||
if (ax < TWO_M28) return x;
|
||||
@ -758,11 +760,11 @@ function MathSinh(x) {
|
||||
return h * (t + t / (t + 1));
|
||||
}
|
||||
// |x| in [22, log(maxdouble)], return 0.5 * exp(|x|)
|
||||
if (ax < LOG_MAXD) return h * MathExp(ax);
|
||||
if (ax < LOG_MAXD) return h * $exp(ax);
|
||||
// |x| in [log(maxdouble), overflowthreshold]
|
||||
// overflowthreshold = 710.4758600739426
|
||||
if (ax <= KSINH_OVERFLOW) {
|
||||
var w = MathExp(0.5 * ax);
|
||||
var w = $exp(0.5 * ax);
|
||||
var t = h * w;
|
||||
return t * w;
|
||||
}
|
||||
@ -800,7 +802,7 @@ function MathCosh(x) {
|
||||
var ix = %_DoubleHi(x) & 0x7fffffff;
|
||||
// |x| in [0,0.5*log2], return 1+expm1(|x|)^2/(2*exp(|x|))
|
||||
if (ix < 0x3fd62e43) {
|
||||
var t = MathExpm1(MathAbs(x));
|
||||
var t = MathExpm1($abs(x));
|
||||
var w = 1 + t;
|
||||
// For |x| < 2^-55, cosh(x) = 1
|
||||
if (ix < 0x3c800000) return w;
|
||||
@ -808,14 +810,14 @@ function MathCosh(x) {
|
||||
}
|
||||
// |x| in [0.5*log2, 22], return (exp(|x|)+1/exp(|x|)/2
|
||||
if (ix < 0x40360000) {
|
||||
var t = MathExp(MathAbs(x));
|
||||
var t = $exp($abs(x));
|
||||
return 0.5 * t + 0.5 / t;
|
||||
}
|
||||
// |x| in [22, log(maxdouble)], return half*exp(|x|)
|
||||
if (ix < 0x40862e42) return 0.5 * MathExp(MathAbs(x));
|
||||
if (ix < 0x40862e42) return 0.5 * $exp($abs(x));
|
||||
// |x| in [log(maxdouble), overflowthreshold]
|
||||
if (MathAbs(x) <= KCOSH_OVERFLOW) {
|
||||
var w = MathExp(0.5 * MathAbs(x));
|
||||
if ($abs(x) <= KCOSH_OVERFLOW) {
|
||||
var w = $exp(0.5 * $abs(x));
|
||||
var t = 0.5 * w;
|
||||
return t * w;
|
||||
}
|
||||
@ -883,7 +885,7 @@ function MathLog10(x) {
|
||||
y = k + i;
|
||||
x = %_ConstructDouble(hx, lx);
|
||||
|
||||
z = y * LOG10_2LO + IVLN10 * MathLog(x);
|
||||
z = y * LOG10_2LO + IVLN10 * %_MathLogRT(x);
|
||||
return z + y * LOG10_2HI;
|
||||
}
|
||||
|
||||
@ -918,7 +920,7 @@ const TWO53 = 9007199254740992;
|
||||
|
||||
function MathLog2(x) {
|
||||
x = x * 1; // Convert to number.
|
||||
var ax = MathAbs(x);
|
||||
var ax = $abs(x);
|
||||
var hx = %_DoubleHi(x);
|
||||
var lx = %_DoubleLo(x);
|
||||
var ix = hx & 0x7fffffff;
|
||||
@ -1001,3 +1003,20 @@ function MathLog2(x) {
|
||||
// t1 + t2 = log2(ax), sum up because we do not care about extra precision.
|
||||
return t1 + t2;
|
||||
}
|
||||
|
||||
InstallFunctions($Math, DONT_ENUM, $Array(
|
||||
"cos", MathCos,
|
||||
"sin", MathSin,
|
||||
"tan", MathTan,
|
||||
"sinh", MathSinh,
|
||||
"cosh", MathCosh,
|
||||
"log10", MathLog10,
|
||||
"log2", MathLog2,
|
||||
"log1p", MathLog1p,
|
||||
"expm1", MathExpm1
|
||||
));
|
||||
|
||||
%SetInlineBuiltinFlag(MathSin);
|
||||
%SetInlineBuiltinFlag(MathCos);
|
||||
|
||||
})();
|
@ -162,16 +162,16 @@ function NAMESubArray(begin, end) {
|
||||
|
||||
var srcLength = %_TypedArrayGetLength(this);
|
||||
if (beginInt < 0) {
|
||||
beginInt = MathMax(0, srcLength + beginInt);
|
||||
beginInt = $max(0, srcLength + beginInt);
|
||||
} else {
|
||||
beginInt = MathMin(srcLength, beginInt);
|
||||
beginInt = $min(srcLength, beginInt);
|
||||
}
|
||||
|
||||
var endInt = IS_UNDEFINED(end) ? srcLength : end;
|
||||
if (endInt < 0) {
|
||||
endInt = MathMax(0, srcLength + endInt);
|
||||
endInt = $max(0, srcLength + endInt);
|
||||
} else {
|
||||
endInt = MathMin(endInt, srcLength);
|
||||
endInt = $min(endInt, srcLength);
|
||||
}
|
||||
if (endInt < beginInt) {
|
||||
endInt = beginInt;
|
||||
|
@ -9,9 +9,6 @@
|
||||
// var $Number = global.Number;
|
||||
// var $Function = global.Function;
|
||||
// var $Array = global.Array;
|
||||
//
|
||||
// in math.js:
|
||||
// var $floor = MathFloor
|
||||
|
||||
var $isNaN = GlobalIsNaN;
|
||||
var $isFinite = GlobalIsFinite;
|
||||
@ -1655,8 +1652,7 @@ function NumberIsNaN(number) {
|
||||
function NumberIsSafeInteger(number) {
|
||||
if (NumberIsFinite(number)) {
|
||||
var integral = TO_INTEGER(number);
|
||||
if (integral == number)
|
||||
return MathAbs(integral) <= $Number.MAX_SAFE_INTEGER;
|
||||
if (integral == number) return $abs(integral) <= $Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1678,8 +1678,8 @@
|
||||
'../../src/array.js',
|
||||
'../../src/string.js',
|
||||
'../../src/uri.js',
|
||||
'../../src/third_party/fdlibm/fdlibm.js',
|
||||
'../../src/math.js',
|
||||
'../../src/third_party/fdlibm/fdlibm.js',
|
||||
'../../src/date.js',
|
||||
'../../src/regexp.js',
|
||||
'../../src/arraybuffer.js',
|
||||
|
Loading…
Reference in New Issue
Block a user