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

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

[ES5] Implement getOwnPropertyDescriptor
https://bugs.webkit.org/show_bug.cgi?id=28724

Reviewed by Gavin Barraclough.

JavaScriptCore:
Implement the core runtime support for getOwnPropertyDescriptor.
This adds a virtual getOwnPropertyDescriptor method to every class
that implements getOwnPropertySlot that shadows the behaviour of
getOwnPropertySlot. The alternative would be to make getOwnPropertySlot
(or PropertySlots in general) provide property attribute information,
but quick testing showed this to be a regression.

WebCore:
Implement the WebCore side of getOwnPropertyDescriptor. This
requires a custom implementation of getOwnPropertyDescriptor
for every class with a custom implementation of getOwnPropertySlot.

The bindings generator has been updated to generate appropriate
versions of getOwnPropertyDescriptor for the general case where
a custom getOwnPropertyDescriptor is not needed. ES5 is vague
about how getOwnPropertyDescriptor should work in the context of
"host" functions with polymorphic GetOwnProperty, so it seems
okay that occasionally we "guess" what attributes -- eg. determining
whether a property is writable.

Test: fast/js/getOwnPropertyDescriptor.html

  • 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 return getStaticFunctionSlot<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, slot);
107}
108
109bool MathObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
110{
111 return getStaticFunctionDescriptor<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, descriptor);
112}
113
114// ------------------------------ Functions --------------------------------
115
116JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue, const ArgList& args)
117{
118 return jsNumber(exec, fabs(args.at(0).toNumber(exec)));
119}
120
121JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
122{
123 return jsNumber(exec, acos(args.at(0).toNumber(exec)));
124}
125
126JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
127{
128 return jsNumber(exec, asin(args.at(0).toNumber(exec)));
129}
130
131JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
132{
133 return jsNumber(exec, atan(args.at(0).toNumber(exec)));
134}
135
136JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue, const ArgList& args)
137{
138 return jsNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
139}
140
141JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, const ArgList& args)
142{
143 return jsNumber(exec, ceil(args.at(0).toNumber(exec)));
144}
145
146JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
147{
148 return jsNumber(exec, cos(args.at(0).toNumber(exec)));
149}
150
151JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec, JSObject*, JSValue, const ArgList& args)
152{
153 return jsNumber(exec, exp(args.at(0).toNumber(exec)));
154}
155
156JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
157{
158 return jsNumber(exec, floor(args.at(0).toNumber(exec)));
159}
160
161JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec, JSObject*, JSValue, const ArgList& args)
162{
163 return jsNumber(exec, log(args.at(0).toNumber(exec)));
164}
165
166JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec, JSObject*, JSValue, const ArgList& args)
167{
168 unsigned argsCount = args.size();
169 double result = -Inf;
170 for (unsigned k = 0; k < argsCount; ++k) {
171 double val = args.at(k).toNumber(exec);
172 if (isnan(val)) {
173 result = NaN;
174 break;
175 }
176 if (val > result || (val == 0 && result == 0 && !signbit(val)))
177 result = val;
178 }
179 return jsNumber(exec, result);
180}
181
182JSValue JSC_HOST_CALL mathProtoFuncMin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
183{
184 unsigned argsCount = args.size();
185 double result = +Inf;
186 for (unsigned k = 0; k < argsCount; ++k) {
187 double val = args.at(k).toNumber(exec);
188 if (isnan(val)) {
189 result = NaN;
190 break;
191 }
192 if (val < result || (val == 0 && result == 0 && signbit(val)))
193 result = val;
194 }
195 return jsNumber(exec, result);
196}
197
198JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, const ArgList& args)
199{
200 // ECMA 15.8.2.1.13
201
202 double arg = args.at(0).toNumber(exec);
203 double arg2 = args.at(1).toNumber(exec);
204
205 if (isnan(arg2))
206 return jsNaN(exec);
207 if (isinf(arg2) && fabs(arg) == 1)
208 return jsNaN(exec);
209 return jsNumber(exec, pow(arg, arg2));
210}
211
212JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
213{
214 return jsNumber(exec, WTF::weakRandomNumber());
215}
216
217JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
218{
219 double arg = args.at(0).toNumber(exec);
220 if (signbit(arg) && arg >= -0.5)
221 return jsNumber(exec, -0.0);
222 return jsNumber(exec, floor(arg + 0.5));
223}
224
225JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
226{
227 return jsNumber(exec, sin(args.at(0).toNumber(exec)));
228}
229
230JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
231{
232 return jsNumber(exec, sqrt(args.at(0).toNumber(exec)));
233}
234
235JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
236{
237 return jsNumber(exec, tan(args.at(0).toNumber(exec)));
238}
239
240} // namespace JSC
Note: See TracBrowser for help on using the repository browser.