OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 return %Math_atan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x)); | 72 return %Math_atan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x)); |
73 } | 73 } |
74 | 74 |
75 // ECMA 262 - 15.8.2.6 | 75 // ECMA 262 - 15.8.2.6 |
76 function MathCeil(x) { | 76 function MathCeil(x) { |
77 return %Math_ceil(TO_NUMBER_INLINE(x)); | 77 return %Math_ceil(TO_NUMBER_INLINE(x)); |
78 } | 78 } |
79 | 79 |
80 // ECMA 262 - 15.8.2.7 | 80 // ECMA 262 - 15.8.2.7 |
81 function MathCos(x) { | 81 function MathCos(x) { |
82 return %_MathCos(TO_NUMBER_INLINE(x)); | 82 return MathCosImpl(x); |
83 } | 83 } |
84 | 84 |
85 // ECMA 262 - 15.8.2.8 | 85 // ECMA 262 - 15.8.2.8 |
86 function MathExp(x) { | 86 function MathExp(x) { |
87 return %Math_exp(TO_NUMBER_INLINE(x)); | 87 return %Math_exp(TO_NUMBER_INLINE(x)); |
88 } | 88 } |
89 | 89 |
90 // ECMA 262 - 15.8.2.9 | 90 // ECMA 262 - 15.8.2.9 |
91 function MathFloor(x) { | 91 function MathFloor(x) { |
92 x = TO_NUMBER_INLINE(x); | 92 x = TO_NUMBER_INLINE(x); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 return %_RandomHeapNumber(); | 178 return %_RandomHeapNumber(); |
179 } | 179 } |
180 | 180 |
181 // ECMA 262 - 15.8.2.15 | 181 // ECMA 262 - 15.8.2.15 |
182 function MathRound(x) { | 182 function MathRound(x) { |
183 return %RoundNumber(TO_NUMBER_INLINE(x)); | 183 return %RoundNumber(TO_NUMBER_INLINE(x)); |
184 } | 184 } |
185 | 185 |
186 // ECMA 262 - 15.8.2.16 | 186 // ECMA 262 - 15.8.2.16 |
187 function MathSin(x) { | 187 function MathSin(x) { |
188 return %_MathSin(TO_NUMBER_INLINE(x)); | 188 return MathSinImpl(x); |
189 } | 189 } |
190 | 190 |
191 // ECMA 262 - 15.8.2.17 | 191 // ECMA 262 - 15.8.2.17 |
192 function MathSqrt(x) { | 192 function MathSqrt(x) { |
193 return %_MathSqrt(TO_NUMBER_INLINE(x)); | 193 return %_MathSqrt(TO_NUMBER_INLINE(x)); |
194 } | 194 } |
195 | 195 |
196 // ECMA 262 - 15.8.2.18 | 196 // ECMA 262 - 15.8.2.18 |
197 function MathTan(x) { | 197 function MathTan(x) { |
198 return %_MathTan(TO_NUMBER_INLINE(x)); | 198 return MathSinImpl(x) / MathCosImpl(x); |
199 } | 199 } |
200 | 200 |
201 // Non-standard extension. | 201 // Non-standard extension. |
202 function MathImul(x, y) { | 202 function MathImul(x, y) { |
203 return %NumberImul(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y)); | 203 return %NumberImul(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y)); |
204 } | 204 } |
205 | 205 |
206 | 206 |
| 207 var MathSinImpl = function(x) { |
| 208 InitTrigonometricFunctions(); |
| 209 return MathSinImpl(x); |
| 210 } |
| 211 |
| 212 |
| 213 var MathCosImpl = function(x) { |
| 214 InitTrigonometricFunctions(); |
| 215 return MathCosImpl(x); |
| 216 } |
| 217 |
| 218 |
| 219 function InitTrigonometricFunctions() { |
| 220 var samples = 2048; // Table size. |
| 221 var pi = 3.1415926535897932; |
| 222 var pi_half = pi / 2; |
| 223 var inverse_pi_half = 1 / pi_half; |
| 224 var two_pi = pi * 2; |
| 225 var interval = pi_half / samples; |
| 226 var inverse_interval = samples / pi_half; |
| 227 var table_sin = new global.Float64Array(samples + 2); |
| 228 var table_cos_interval = new global.Float64Array(samples + 2); |
| 229 |
| 230 %PopulateTrigonometricTable(table_sin, table_cos_interval, samples); |
| 231 |
| 232 // This implements the following algorithm. |
| 233 // 1) Multiplication takes care of to-number conversion. |
| 234 // 2) Reduce x to the first quadrant [0, pi/2]. |
| 235 // Conveniently enough, in case of +/-Infinity, we get NaN. |
| 236 // 3) Replace x by (pi/2-x) if x was in the 2nd or 4th quadrant. |
| 237 // 4) Do a table lookup for the closest samples to the left and right of x. |
| 238 // 5) Find the derivatives at those sampling points by table lookup: |
| 239 // dsin(x)/dx = cos(x) = sin(pi/2-x) for x in [0, pi/2]. |
| 240 // 6) Use cubic spline interpolation to approximate sin(x). |
| 241 // 7) Negate the result if x was in the 3rd or 4th quadrant. |
| 242 // 8) Get rid of -0 by adding 0. |
| 243 MathSinImpl = function(x) { |
| 244 var multiple = %_MathFloor(x * inverse_pi_half); |
| 245 x = (multiple & 1) * pi_half + |
| 246 (1 - ((multiple & 1) << 1)) * (x - multiple * pi_half); |
| 247 var double_index = x * inverse_interval; |
| 248 var index = double_index | 0; |
| 249 var t1 = double_index - index; |
| 250 var t2 = 1 - t1; |
| 251 var y1 = table_sin[index]; |
| 252 var y2 = table_sin[index + 1]; |
| 253 var dy = y2 - y1; |
| 254 return (t2 * y1 + t1 * y2 + |
| 255 t1 * t2 * ((table_cos_interval[index] - dy) * t2 + |
| 256 (dy - table_cos_interval[index + 1]) * t1)) * |
| 257 (1 - (multiple & 2)) + 0; |
| 258 }; |
| 259 |
| 260 MathCosImpl = function(x) { |
| 261 return MathSinImpl(x + pi_half); |
| 262 }; |
| 263 |
| 264 %SetInlineBuiltinFlag(MathSinImpl); |
| 265 %SetInlineBuiltinFlag(MathCosImpl); |
| 266 } |
| 267 |
| 268 |
207 // ------------------------------------------------------------------- | 269 // ------------------------------------------------------------------- |
208 | 270 |
209 function SetUpMath() { | 271 function SetUpMath() { |
210 %CheckIsBootstrapping(); | 272 %CheckIsBootstrapping(); |
211 | 273 |
212 %SetPrototype($Math, $Object.prototype); | 274 %SetPrototype($Math, $Object.prototype); |
213 %SetProperty(global, "Math", $Math, DONT_ENUM); | 275 %SetProperty(global, "Math", $Math, DONT_ENUM); |
214 %FunctionSetInstanceClassName(MathConstructor, 'Math'); | 276 %FunctionSetInstanceClassName(MathConstructor, 'Math'); |
215 | 277 |
216 // Set up math constants. | 278 // Set up math constants. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 "round", MathRound, | 331 "round", MathRound, |
270 "sin", MathSin, | 332 "sin", MathSin, |
271 "sqrt", MathSqrt, | 333 "sqrt", MathSqrt, |
272 "tan", MathTan, | 334 "tan", MathTan, |
273 "atan2", MathAtan2, | 335 "atan2", MathAtan2, |
274 "pow", MathPow, | 336 "pow", MathPow, |
275 "max", MathMax, | 337 "max", MathMax, |
276 "min", MathMin, | 338 "min", MathMin, |
277 "imul", MathImul | 339 "imul", MathImul |
278 )); | 340 )); |
| 341 |
| 342 %SetInlineBuiltinFlag(MathSin); |
| 343 %SetInlineBuiltinFlag(MathCos); |
| 344 %SetInlineBuiltinFlag(MathTan); |
279 } | 345 } |
280 | 346 |
281 SetUpMath(); | 347 SetUpMath(); |
OLD | NEW |