source: webkit/trunk/JavaScriptCore/runtime/MathObject.cpp@ 43424

Last change on this file since 43424 was 43372, checked in by [email protected], 16 years ago

Improve native call performance

Reviewed by Gavin Barraclough.

Fix the windows build by adding calling convention declarations everywhere,
chose fastcall as that seemed most sensible given we were having to declare
the convention explicitly. In addition switched to fastcall on mac in the
deluded belief that documented fastcall behavior on windows would match
actual its actual behavior.

  • Property svn:eol-style set to native
File size: 9.7 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#include "config.h"
22#include "MathObject.h"
23
24#include "ObjectPrototype.h"
25#include "Operations.h"
26#include <time.h>
27#include <wtf/Assertions.h>
28#include <wtf/MathExtras.h>
29#include <wtf/RandomNumber.h>
30#include <wtf/RandomNumberSeed.h>
31
32namespace JSC {
33
34ASSERT_CLASS_FITS_IN_CELL(MathObject);
35
36static JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*, JSObject*, JSValue, const ArgList&);
37static JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*, JSObject*, JSValue, const ArgList&);
38static JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState*, JSObject*, JSValue, const ArgList&);
39static JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState*, JSObject*, JSValue, const ArgList&);
40static JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*, JSObject*, JSValue, const ArgList&);
41static JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*, JSObject*, JSValue, const ArgList&);
42static JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*, JSObject*, JSValue, const ArgList&);
43static JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*, JSObject*, JSValue, const ArgList&);
44static JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*, JSObject*, JSValue, const ArgList&);
45static JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*, JSObject*, JSValue, const ArgList&);
46static JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState*, JSObject*, JSValue, const ArgList&);
47static JSValue JSC_HOST_CALL mathProtoFuncMin(ExecState*, JSObject*, JSValue, const ArgList&);
48static JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState*, JSObject*, JSValue, const ArgList&);
49static JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState*, JSObject*, JSValue, const ArgList&);
50static JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*, JSObject*, JSValue, const ArgList&);
51static JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*, JSObject*, JSValue, const ArgList&);
52static JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*, JSObject*, JSValue, const ArgList&);
53static JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*, JSObject*, JSValue, const ArgList&);
54
55}
56
57#include "MathObject.lut.h"
58
59namespace JSC {
60
61// ------------------------------ MathObject --------------------------------
62
63const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable };
64
65/* Source for MathObject.lut.h
66@begin mathTable
67 abs mathProtoFuncAbs DontEnum|Function 1
68 acos mathProtoFuncACos DontEnum|Function 1
69 asin mathProtoFuncASin DontEnum|Function 1
70 atan mathProtoFuncATan DontEnum|Function 1
71 atan2 mathProtoFuncATan2 DontEnum|Function 2
72 ceil mathProtoFuncCeil DontEnum|Function 1
73 cos mathProtoFuncCos DontEnum|Function 1
74 exp mathProtoFuncExp DontEnum|Function 1
75 floor mathProtoFuncFloor DontEnum|Function 1
76 log mathProtoFuncLog DontEnum|Function 1
77 max mathProtoFuncMax DontEnum|Function 2
78 min mathProtoFuncMin DontEnum|Function 2
79 pow mathProtoFuncPow DontEnum|Function 2
80 random mathProtoFuncRandom DontEnum|Function 0
81 round mathProtoFuncRound DontEnum|Function 1
82 sin mathProtoFuncSin DontEnum|Function 1
83 sqrt mathProtoFuncSqrt DontEnum|Function 1
84 tan mathProtoFuncTan DontEnum|Function 1
85@end
86*/
87
88MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> structure)
89 : JSObject(structure)
90{
91 putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exec, exp(1.0)), DontDelete | DontEnum | ReadOnly);
92 putDirectWithoutTransition(Identifier(exec, "LN2"), jsNumber(exec, log(2.0)), DontDelete | DontEnum | ReadOnly);
93 putDirectWithoutTransition(Identifier(exec, "LN10"), jsNumber(exec, log(10.0)), DontDelete | DontEnum | ReadOnly);
94 putDirectWithoutTransition(Identifier(exec, "LOG2E"), jsNumber(exec, 1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
95 putDirectWithoutTransition(Identifier(exec, "LOG10E"), jsNumber(exec, 1.0 / log(10.0)), DontDelete | DontEnum | ReadOnly);
96 putDirectWithoutTransition(Identifier(exec, "PI"), jsNumber(exec, piDouble), DontDelete | DontEnum | ReadOnly);
97 putDirectWithoutTransition(Identifier(exec, "SQRT1_2"), jsNumber(exec, sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
98 putDirectWithoutTransition(Identifier(exec, "SQRT2"), jsNumber(exec, sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
99 WTF::initializeWeakRandomNumberGenerator();
100}
101
102// ECMA 15.8
103
104bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
105{
106 const HashEntry* entry = ExecState::mathTable(exec)->entry(exec, propertyName);
107
108 if (!entry)
109 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
110
111 ASSERT(entry->attributes() & Function);
112 setUpStaticFunctionSlot(exec, entry, this, propertyName, slot);
113 return true;
114}
115
116// ------------------------------ Functions --------------------------------
117
118JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue, const ArgList& args)
119{
120 return jsNumber(exec, fabs(args.at(0).toNumber(exec)));
121}
122
123JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
124{
125 return jsNumber(exec, acos(args.at(0).toNumber(exec)));
126}
127
128JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
129{
130 return jsNumber(exec, asin(args.at(0).toNumber(exec)));
131}
132
133JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
134{
135 return jsNumber(exec, atan(args.at(0).toNumber(exec)));
136}
137
138JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue, const ArgList& args)
139{
140 return jsNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
141}
142
143JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, const ArgList& args)
144{
145 return jsNumber(exec, ceil(args.at(0).toNumber(exec)));
146}
147
148JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
149{
150 return jsNumber(exec, cos(args.at(0).toNumber(exec)));
151}
152
153JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec, JSObject*, JSValue, const ArgList& args)
154{
155 return jsNumber(exec, exp(args.at(0).toNumber(exec)));
156}
157
158JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
159{
160 return jsNumber(exec, floor(args.at(0).toNumber(exec)));
161}
162
163JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec, JSObject*, JSValue, const ArgList& args)
164{
165 return jsNumber(exec, log(args.at(0).toNumber(exec)));
166}
167
168JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec, JSObject*, JSValue, const ArgList& args)
169{
170 unsigned argsCount = args.size();
171 double result = -Inf;
172 for (unsigned k = 0; k < argsCount; ++k) {
173 double val = args.at(k).toNumber(exec);
174 if (isnan(val)) {
175 result = NaN;
176 break;
177 }
178 if (val > result || (val == 0 && result == 0 && !signbit(val)))
179 result = val;
180 }
181 return jsNumber(exec, result);
182}
183
184JSValue JSC_HOST_CALL mathProtoFuncMin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
185{
186 unsigned argsCount = args.size();
187 double result = +Inf;
188 for (unsigned k = 0; k < argsCount; ++k) {
189 double val = args.at(k).toNumber(exec);
190 if (isnan(val)) {
191 result = NaN;
192 break;
193 }
194 if (val < result || (val == 0 && result == 0 && signbit(val)))
195 result = val;
196 }
197 return jsNumber(exec, result);
198}
199
200JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, const ArgList& args)
201{
202 // ECMA 15.8.2.1.13
203
204 double arg = args.at(0).toNumber(exec);
205 double arg2 = args.at(1).toNumber(exec);
206
207 if (isnan(arg2))
208 return jsNaN(exec);
209 if (isinf(arg2) && fabs(arg) == 1)
210 return jsNaN(exec);
211 return jsNumber(exec, pow(arg, arg2));
212}
213
214JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
215{
216 return jsNumber(exec, WTF::weakRandomNumber());
217}
218
219JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
220{
221 double arg = args.at(0).toNumber(exec);
222 if (signbit(arg) && arg >= -0.5)
223 return jsNumber(exec, -0.0);
224 return jsNumber(exec, floor(arg + 0.5));
225}
226
227JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
228{
229 return jsNumber(exec, sin(args.at(0).toNumber(exec)));
230}
231
232JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
233{
234 return jsNumber(exec, sqrt(args.at(0).toNumber(exec)));
235}
236
237JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
238{
239 return jsNumber(exec, tan(args.at(0).toNumber(exec)));
240}
241
242} // namespace JSC
Note: See TracBrowser for help on using the repository browser.