also propagate updateContents() calls to parent frame
[kdelibs.git] / kjs / math_object.cpp
blob866248923f860112776680bbe48312bbd089578a
1 // -*- c-basic-offset: 2 -*-
2 /*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "math_object.h"
23 #include <config.h>
24 #include "math_object.lut.h"
25 #include "wtf/MathExtras.h"
27 #include "operations.h"
28 #include <math.h>
29 #include <time.h>
31 #if PLATFORM(SOLARIS_OS)
32 static inline int signbit(double x)
34 return (x<0.0) ? 1 : 0;
36 #endif
38 #ifndef M_PI
39 #define M_PI 3.14159265358979323846
40 #endif /* M_PI */
42 using namespace KJS;
44 // ------------------------------ MathObjectImp --------------------------------
46 const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable, 0 };
48 /* Source for math_object.lut.h
49 @begin mathTable 21
50 E MathObjectImp::Euler DontEnum|DontDelete|ReadOnly
51 LN2 MathObjectImp::Ln2 DontEnum|DontDelete|ReadOnly
52 LN10 MathObjectImp::Ln10 DontEnum|DontDelete|ReadOnly
53 LOG2E MathObjectImp::Log2E DontEnum|DontDelete|ReadOnly
54 LOG10E MathObjectImp::Log10E DontEnum|DontDelete|ReadOnly
55 PI MathObjectImp::Pi DontEnum|DontDelete|ReadOnly
56 SQRT1_2 MathObjectImp::Sqrt1_2 DontEnum|DontDelete|ReadOnly
57 SQRT2 MathObjectImp::Sqrt2 DontEnum|DontDelete|ReadOnly
58 abs MathObjectImp::Abs DontEnum|Function 1
59 acos MathObjectImp::ACos DontEnum|Function 1
60 asin MathObjectImp::ASin DontEnum|Function 1
61 atan MathObjectImp::ATan DontEnum|Function 1
62 atan2 MathObjectImp::ATan2 DontEnum|Function 2
63 ceil MathObjectImp::Ceil DontEnum|Function 1
64 cos MathObjectImp::Cos DontEnum|Function 1
65 exp MathObjectImp::Exp DontEnum|Function 1
66 floor MathObjectImp::Floor DontEnum|Function 1
67 log MathObjectImp::Log DontEnum|Function 1
68 max MathObjectImp::Max DontEnum|Function 2
69 min MathObjectImp::Min DontEnum|Function 2
70 pow MathObjectImp::Pow DontEnum|Function 2
71 random MathObjectImp::Random DontEnum|Function 0
72 round MathObjectImp::Round DontEnum|Function 1
73 sin MathObjectImp::Sin DontEnum|Function 1
74 sqrt MathObjectImp::Sqrt DontEnum|Function 1
75 tan MathObjectImp::Tan DontEnum|Function 1
76 @end
79 MathObjectImp::MathObjectImp(ExecState * /*exec*/,
80 ObjectPrototype *objProto)
81 : JSObject(objProto)
85 // ECMA 15.8
87 bool MathObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
89 return getStaticPropertySlot<MathFuncImp, MathObjectImp, JSObject>(exec, &mathTable, this, propertyName, slot);
92 JSValue *MathObjectImp::getValueProperty(ExecState *, int token) const
94 double d = -42; // ;)
95 switch (token) {
96 case Euler:
97 d = exp(1.0);
98 break;
99 case Ln2:
100 d = log(2.0);
101 break;
102 case Ln10:
103 d = log(10.0);
104 break;
105 case Log2E:
106 d = 1.0/log(2.0);
107 break;
108 case Log10E:
109 d = 1.0/log(10.0);
110 break;
111 case Pi:
112 d = piDouble;
113 break;
114 case Sqrt1_2:
115 d = sqrt(0.5);
116 break;
117 case Sqrt2:
118 d = sqrt(2.0);
119 break;
120 default:
121 assert(0);
124 return jsNumber(d);
127 // ------------------------------ MathObjectImp --------------------------------
129 static bool randomSeeded = false;
131 MathFuncImp::MathFuncImp(ExecState* exec, int i, int l, const Identifier& name)
132 : InternalFunctionImp(static_cast<FunctionPrototype*>(exec->lexicalInterpreter()->builtinFunctionPrototype()), name)
133 , id(i)
135 putDirect(exec->propertyNames().length, l, DontDelete|ReadOnly|DontEnum);
138 JSValue *MathFuncImp::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const List &args)
140 double arg = args[0]->toNumber(exec);
141 double arg2 = args[1]->toNumber(exec);
142 double result;
144 switch (id) {
145 case MathObjectImp::Abs:
146 result = ( arg < 0 || arg == -0) ? (-arg) : arg;
147 break;
148 case MathObjectImp::ACos:
149 result = ::acos(arg);
150 break;
151 case MathObjectImp::ASin:
152 result = ::asin(arg);
153 break;
154 case MathObjectImp::ATan:
155 result = ::atan(arg);
156 break;
157 case MathObjectImp::ATan2:
158 result = ::atan2(arg, arg2);
159 break;
160 case MathObjectImp::Ceil:
161 result = ::ceil(arg);
162 break;
163 case MathObjectImp::Cos:
164 result = ::cos(arg);
165 break;
166 case MathObjectImp::Exp:
167 result = ::exp(arg);
168 break;
169 case MathObjectImp::Floor:
170 result = ::floor(arg);
171 break;
172 case MathObjectImp::Log:
173 result = ::log(arg);
174 break;
175 case MathObjectImp::Max: {
176 unsigned int argsCount = args.size();
177 result = -Inf;
178 for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
179 double val = args[k]->toNumber(exec);
180 if ( isNaN( val ) )
182 result = NaN;
183 break;
185 if ( val > result || (val == 0 && result == 0 && !signbit(val)) )
186 result = val;
188 break;
190 case MathObjectImp::Min: {
191 unsigned int argsCount = args.size();
192 result = +Inf;
193 for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
194 double val = args[k]->toNumber(exec);
195 if ( isNaN( val ) )
197 result = NaN;
198 break;
200 if ( val < result || (val == 0 && result == 0 && signbit(val)) )
201 result = val;
203 break;
205 case MathObjectImp::Pow:
206 // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
207 if (isNaN(arg2))
208 result = NaN;
209 else if (isNaN(arg) && arg2 != 0)
210 result = NaN;
211 else if (::fabs(arg) == 1 && isInf(arg2))
212 result = NaN;
213 else if (arg2 == 0 && arg != 0)
214 result = 1;
215 else
216 result = ::pow(arg, arg2);
217 break;
218 case MathObjectImp::Random:
219 if (!randomSeeded) {
220 srand(static_cast<unsigned>(time(0)));
221 randomSeeded = true;
223 result = (double)rand() / RAND_MAX;
224 break;
225 case MathObjectImp::Round:
226 if (signbit(arg) && arg >= -0.5)
227 result = -0.0;
228 else
229 result = ::floor(arg + 0.5);
230 break;
231 case MathObjectImp::Sin:
232 result = ::sin(arg);
233 break;
234 case MathObjectImp::Sqrt:
235 result = ::sqrt(arg);
236 break;
237 case MathObjectImp::Tan:
238 result = ::tan(arg);
239 break;
241 default:
242 result = 0.0;
243 assert(0);
246 return jsNumber(result);