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; | |
Jakob Kummerow
2013/10/29 17:17:53
nit: s/size;/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 for those samples 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 MathSinImpl = function(x) { | |
243 var multiple = %_MathFloor(x * inverse_pi_half); | |
244 x = (multiple & 1) * pi_half + | |
245 (1 - ((multiple & 1) << 1)) * (x - multiple * pi_half); | |
246 var double_index = x * inverse_interval; | |
247 var index = double_index | 0; | |
248 var t1 = double_index - index; | |
249 var t2 = 1 - t1; | |
250 var y1 = table_sin[index]; | |
251 var y2 = table_sin[index + 1]; | |
252 var dy = y2 - y1; | |
253 return (t2 * y1 + t1 * y2 + | |
254 t1 * t2 * ((table_cos_interval[index] - dy) * t2 + | |
255 (dy - table_cos_interval[index + 1]) * t1)) * | |
256 (1 - (multiple & 2)); | |
257 }; | |
258 | |
259 MathCosImpl = function(x) { | |
260 return MathSinImpl(x + pi_half); | |
261 }; | |
262 | |
263 %SetInlineBuiltinFlag(MathSinImpl); | |
264 %SetInlineBuiltinFlag(MathCosImpl); | |
265 } | |
266 | |
267 | |
207 // ------------------------------------------------------------------- | 268 // ------------------------------------------------------------------- |
208 | 269 |
209 function SetUpMath() { | 270 function SetUpMath() { |
210 %CheckIsBootstrapping(); | 271 %CheckIsBootstrapping(); |
211 | 272 |
212 %SetPrototype($Math, $Object.prototype); | 273 %SetPrototype($Math, $Object.prototype); |
213 %SetProperty(global, "Math", $Math, DONT_ENUM); | 274 %SetProperty(global, "Math", $Math, DONT_ENUM); |
214 %FunctionSetInstanceClassName(MathConstructor, 'Math'); | 275 %FunctionSetInstanceClassName(MathConstructor, 'Math'); |
215 | 276 |
216 // Set up math constants. | 277 // Set up math constants. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 "round", MathRound, | 330 "round", MathRound, |
270 "sin", MathSin, | 331 "sin", MathSin, |
271 "sqrt", MathSqrt, | 332 "sqrt", MathSqrt, |
272 "tan", MathTan, | 333 "tan", MathTan, |
273 "atan2", MathAtan2, | 334 "atan2", MathAtan2, |
274 "pow", MathPow, | 335 "pow", MathPow, |
275 "max", MathMax, | 336 "max", MathMax, |
276 "min", MathMin, | 337 "min", MathMin, |
277 "imul", MathImul | 338 "imul", MathImul |
278 )); | 339 )); |
340 | |
341 %SetInlineBuiltinFlag(MathSin); | |
342 %SetInlineBuiltinFlag(MathCos); | |
343 %SetInlineBuiltinFlag(MathTan); | |
279 } | 344 } |
280 | 345 |
281 SetUpMath(); | 346 SetUpMath(); |
OLD | NEW |