Chromium Code Reviews| Index: src/math.js |
| diff --git a/src/math.js b/src/math.js |
| index efab63a186d4f8b924894dad9c1f0be59ef9846a..8e52ebf1ed5a343002440b1c64f7bc63ac9ebbfd 100644 |
| --- a/src/math.js |
| +++ b/src/math.js |
| @@ -79,7 +79,7 @@ function MathCeil(x) { |
| // ECMA 262 - 15.8.2.7 |
| function MathCos(x) { |
| - return %_MathCos(TO_NUMBER_INLINE(x)); |
| + return MathCosImpl(x); |
| } |
| // ECMA 262 - 15.8.2.8 |
| @@ -185,7 +185,7 @@ function MathRound(x) { |
| // ECMA 262 - 15.8.2.16 |
| function MathSin(x) { |
| - return %_MathSin(TO_NUMBER_INLINE(x)); |
| + return MathSinImpl(x); |
| } |
| // ECMA 262 - 15.8.2.17 |
| @@ -195,7 +195,7 @@ function MathSqrt(x) { |
| // ECMA 262 - 15.8.2.18 |
| function MathTan(x) { |
| - return %_MathTan(TO_NUMBER_INLINE(x)); |
| + return MathSinImpl(x) / MathCosImpl(x); |
| } |
| // Non-standard extension. |
| @@ -204,6 +204,67 @@ function MathImul(x, y) { |
| } |
| +var MathSinImpl = function(x) { |
| + InitTrigonometricFunctions(); |
| + return MathSinImpl(x); |
| +} |
| + |
| + |
| +var MathCosImpl = function(x) { |
| + InitTrigonometricFunctions(); |
| + return MathCosImpl(x); |
| +} |
| + |
| + |
| +function InitTrigonometricFunctions() { |
| + var samples = 2048; // Table size; |
|
Jakob Kummerow
2013/10/29 17:17:53
nit: s/size;/size./
|
| + var pi = 3.1415926535897932; |
| + var pi_half = pi / 2; |
| + var inverse_pi_half = 1 / pi_half; |
| + var two_pi = pi * 2; |
| + var interval = pi_half / samples; |
| + var inverse_interval = samples / pi_half; |
| + var table_sin = new global.Float64Array(samples + 2); |
| + var table_cos_interval = new global.Float64Array(samples + 2); |
| + |
| + %PopulateTrigonometricTable(table_sin, table_cos_interval, samples); |
| + |
| + // This implements the following algorithm. |
| + // 1) Multiplication takes care of to-number conversion. |
| + // 2) Reduce x to the first quadrant [0, pi/2]. |
| + // Conveniently enough, in case of +/-Infinity, we get NaN. |
| + // 3) Replace x by (pi/2-x) if x was in the 2nd or 4th quadrant. |
| + // 4) Do a table lookup for the closest samples to the left and right of x. |
| + // 5) Find the derivatives for those samples by table lookup: |
| + // dsin(x)/dx = cos(x) = sin(pi/2-x) for x in [0, pi/2]. |
| + // 6) Use cubic spline interpolation to approximate sin(x). |
| + // 7) Negate the result if x was in the 3rd or 4th quadrant. |
| + MathSinImpl = function(x) { |
| + var multiple = %_MathFloor(x * inverse_pi_half); |
| + x = (multiple & 1) * pi_half + |
| + (1 - ((multiple & 1) << 1)) * (x - multiple * pi_half); |
| + var double_index = x * inverse_interval; |
| + var index = double_index | 0; |
| + var t1 = double_index - index; |
| + var t2 = 1 - t1; |
| + var y1 = table_sin[index]; |
| + var y2 = table_sin[index + 1]; |
| + var dy = y2 - y1; |
| + return (t2 * y1 + t1 * y2 + |
| + t1 * t2 * ((table_cos_interval[index] - dy) * t2 + |
| + (dy - table_cos_interval[index + 1]) * t1)) * |
| + (1 - (multiple & 2)); |
| + }; |
| + |
| + MathCosImpl = function(x) { |
| + return MathSinImpl(x + pi_half); |
| + }; |
| + |
| + %SetInlineBuiltinFlag(MathSinImpl); |
| + %SetInlineBuiltinFlag(MathCosImpl); |
| +} |
| + |
| + |
| // ------------------------------------------------------------------- |
| function SetUpMath() { |
| @@ -276,6 +337,10 @@ function SetUpMath() { |
| "min", MathMin, |
| "imul", MathImul |
| )); |
| + |
| + %SetInlineBuiltinFlag(MathSin); |
| + %SetInlineBuiltinFlag(MathCos); |
| + %SetInlineBuiltinFlag(MathTan); |
| } |
| SetUpMath(); |