]> git.saurik.com Git - apple/javascriptcore.git/blame - kjs/math_object.cpp
JavaScriptCore-466.1.tar.gz
[apple/javascriptcore.git] / kjs / math_object.cpp
CommitLineData
b37bf2e1
A
1/*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
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 "math_object.h"
23#include "math_object.lut.h"
24
25#include "operations.h"
26#include <time.h>
27#include <wtf/Assertions.h>
28#include <wtf/MathExtras.h>
29
30namespace KJS {
31
32// ------------------------------ MathObjectImp --------------------------------
33
34const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable };
35
36/* Source for math_object.lut.h
37@begin mathTable 21
38 E MathObjectImp::Euler DontEnum|DontDelete|ReadOnly
39 LN2 MathObjectImp::Ln2 DontEnum|DontDelete|ReadOnly
40 LN10 MathObjectImp::Ln10 DontEnum|DontDelete|ReadOnly
41 LOG2E MathObjectImp::Log2E DontEnum|DontDelete|ReadOnly
42 LOG10E MathObjectImp::Log10E DontEnum|DontDelete|ReadOnly
43 PI MathObjectImp::Pi DontEnum|DontDelete|ReadOnly
44 SQRT1_2 MathObjectImp::Sqrt1_2 DontEnum|DontDelete|ReadOnly
45 SQRT2 MathObjectImp::Sqrt2 DontEnum|DontDelete|ReadOnly
46 abs mathProtoFuncAbs DontEnum|Function 1
47 acos mathProtoFuncACos DontEnum|Function 1
48 asin mathProtoFuncASin DontEnum|Function 1
49 atan mathProtoFuncATan DontEnum|Function 1
50 atan2 mathProtoFuncATan2 DontEnum|Function 2
51 ceil mathProtoFuncCeil DontEnum|Function 1
52 cos mathProtoFuncCos DontEnum|Function 1
53 exp mathProtoFuncExp DontEnum|Function 1
54 floor mathProtoFuncFloor DontEnum|Function 1
55 log mathProtoFuncLog DontEnum|Function 1
56 max mathProtoFuncMax DontEnum|Function 2
57 min mathProtoFuncMin DontEnum|Function 2
58 pow mathProtoFuncPow DontEnum|Function 2
59 random mathProtoFuncRandom DontEnum|Function 0
60 round mathProtoFuncRound DontEnum|Function 1
61 sin mathProtoFuncSin DontEnum|Function 1
62 sqrt mathProtoFuncSqrt DontEnum|Function 1
63 tan mathProtoFuncTan DontEnum|Function 1
64@end
65*/
66
67MathObjectImp::MathObjectImp(ExecState*, ObjectPrototype* objectPrototype)
68 : JSObject(objectPrototype)
69{
70}
71
72// ECMA 15.8
73
74bool MathObjectImp::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
75{
76 return getStaticPropertySlot<MathObjectImp, JSObject>(exec, &mathTable, this, propertyName, slot);
77}
78
79JSValue* MathObjectImp::getValueProperty(ExecState*, int token) const
80{
81 switch (token) {
82 case Euler:
83 return jsNumber(exp(1.0));
84 case Ln2:
85 return jsNumber(log(2.0));
86 case Ln10:
87 return jsNumber(log(10.0));
88 case Log2E:
89 return jsNumber(1.0 / log(2.0));
90 case Log10E:
91 return jsNumber(1.0 / log(10.0));
92 case Pi:
93 return jsNumber(piDouble);
94 case Sqrt1_2:
95 return jsNumber(sqrt(0.5));
96 case Sqrt2:
97 return jsNumber(sqrt(2.0));
98 }
99
100 ASSERT_NOT_REACHED();
101 return 0;
102}
103
104// ------------------------------ Functions --------------------------------
105
106JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, const List& args)
107{
108 double arg = args[0]->toNumber(exec);
109 return signbit(arg) ? jsNumber(-arg) : jsNumber(arg);
110}
111
112JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, const List& args)
113{
114 return jsNumber(acos(args[0]->toNumber(exec)));
115}
116
117JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, const List& args)
118{
119 return jsNumber(asin(args[0]->toNumber(exec)));
120}
121
122JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, const List& args)
123{
124 return jsNumber(atan(args[0]->toNumber(exec)));
125}
126
127JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, const List& args)
128{
129 return jsNumber(atan2(args[0]->toNumber(exec), args[1]->toNumber(exec)));
130}
131
132JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, const List& args)
133{
134 double arg = args[0]->toNumber(exec);
135 if (signbit(arg) && arg > -1.0)
136 return jsNumber(-0.0);
137 return jsNumber(ceil(arg));
138}
139
140JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, const List& args)
141{
142 return jsNumber(cos(args[0]->toNumber(exec)));
143}
144
145JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, const List& args)
146{
147 return jsNumber(exp(args[0]->toNumber(exec)));
148}
149
150JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, const List& args)
151{
152 double arg = args[0]->toNumber(exec);
153 if (signbit(arg) && arg == 0.0)
154 return jsNumber(-0.0);
155 return jsNumber(floor(arg));
156}
157
158JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, const List& args)
159{
160 return jsNumber(log(args[0]->toNumber(exec)));
161}
162
163JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, const List& args)
164{
165 unsigned argsCount = args.size();
166 double result = -Inf;
167 for (unsigned k = 0; k < argsCount; ++k) {
168 double val = args[k]->toNumber(exec);
169 if (isnan(val)) {
170 result = NaN;
171 break;
172 }
173 if (val > result || (val == 0 && result == 0 && !signbit(val)))
174 result = val;
175 }
176 return jsNumber(result);
177}
178
179JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, const List& args)
180{
181 unsigned argsCount = args.size();
182 double result = +Inf;
183 for (unsigned k = 0; k < argsCount; ++k) {
184 double val = args[k]->toNumber(exec);
185 if (isnan(val)) {
186 result = NaN;
187 break;
188 }
189 if (val < result || (val == 0 && result == 0 && signbit(val)))
190 result = val;
191 }
192 return jsNumber(result);
193}
194
195JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, const List& args)
196{
197 // ECMA 15.8.2.1.13
198
199 double arg = args[0]->toNumber(exec);
200 double arg2 = args[1]->toNumber(exec);
201
202 if (isnan(arg2))
203 return jsNumber(NaN);
204 if (isinf(arg2) && fabs(arg) == 1)
205 return jsNumber(NaN);
206 return jsNumber(pow(arg, arg2));
207}
208
209static bool didInitRandom;
210
211JSValue* mathProtoFuncRandom(ExecState*, JSObject*, const List&)
212{
213 if (!didInitRandom) {
214 wtf_random_init();
215 didInitRandom = true;
216 }
217 return jsNumber(wtf_random());
218}
219
220JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, const List& args)
221{
222 double arg = args[0]->toNumber(exec);
223 if (signbit(arg) && arg >= -0.5)
224 return jsNumber(-0.0);
225 return jsNumber(floor(arg + 0.5));
226}
227
228JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, const List& args)
229{
230 return jsNumber(sin(args[0]->toNumber(exec)));
231}
232
233JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, const List& args)
234{
235 return jsNumber(sqrt(args[0]->toNumber(exec)));
236}
237
238JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, const List& args)
239{
240 return jsNumber(tan(args[0]->toNumber(exec)));
241}
242
243} // namespace KJS