source: webkit/trunk/JavaScriptCore/kjs/value.h@ 19901

Last change on this file since 19901 was 18715, checked in by ap, 18 years ago

2007-01-09 Mitz Pettel <[email protected]>

Reviewed by Darin.

JavaScriptCore:

  • JavaScriptCore.exp:
  • kjs/value.cpp: (KJS::JSValue::toInt32): Folded toInt32Inline into this method, which was its only caller. (KJS::JSValue::toUInt32): Added a variant that reports if the conversion has succeeded.
  • kjs/value.h:

WebCore:

  • bindings/js/kjs_html.cpp: (KJS::JSHTMLCollectionProtoFunc::callAsFunction): Changed item() to fall back to namedItem() if its argument does not convert to a number.

LayoutTests:

  • fast/dom/collection-namedItem-via-item-expected.txt: Added.
  • fast/dom/collection-namedItem-via-item.html: Added.
  • Property svn:eol-style set to native
File size: 9.9 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2001 Harri Porten ([email protected])
4 * Copyright (C) 2001 Peter Kelly ([email protected])
5 * Copyright (C) 2003-2005 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#ifndef KJS_VALUE_H
25#define KJS_VALUE_H
26
27#include "JSImmediate.h"
28#include "ustring.h"
29#include <stddef.h> // for size_t
30
31#ifndef NDEBUG // protection against problems if committing with KJS_VERBOSE on
32
33// Uncomment this to enable very verbose output from KJS
34//#define KJS_VERBOSE
35// Uncomment this to debug memory allocation and garbage collection
36//#define KJS_DEBUG_MEM
37
38#endif
39
40namespace KJS {
41
42class ExecState;
43class JSObject;
44class JSCell;
45
46struct ClassInfo;
47
48/**
49 * JSValue is the base type for all primitives (Undefined, Null, Boolean,
50 * String, Number) and objects in ECMAScript.
51 *
52 * Note: you should never inherit from JSValue as it is for primitive types
53 * only (all of which are provided internally by KJS). Instead, inherit from
54 * JSObject.
55 */
56class JSValue {
57 friend class JSCell; // so it can derive from this class
58 friend class Collector; // so it can call downcast()
59
60private:
61 JSValue();
62 virtual ~JSValue();
63
64public:
65 // Querying the type.
66 JSType type() const;
67 bool isUndefined() const;
68 bool isNull() const;
69 bool isUndefinedOrNull() const;
70 bool isBoolean() const;
71 bool isNumber() const;
72 bool isString() const;
73 bool isObject() const;
74 bool isObject(const ClassInfo *) const;
75
76 // Extracting the value.
77 bool getBoolean(bool&) const;
78 bool getBoolean() const; // false if not a boolean
79 bool getNumber(double&) const;
80 double getNumber() const; // NaN if not a number
81 bool getString(UString&) const;
82 UString getString() const; // null string if not a string
83 JSObject *getObject(); // NULL if not an object
84 const JSObject *getObject() const; // NULL if not an object
85
86 // Extracting integer values.
87 bool getUInt32(uint32_t&) const;
88
89 // Basic conversions.
90 JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
91 bool toBoolean(ExecState *exec) const;
92 double toNumber(ExecState *exec) const;
93 UString toString(ExecState *exec) const;
94 JSObject *toObject(ExecState *exec) const;
95
96 // Integer conversions.
97 double toInteger(ExecState*) const;
98 int32_t toInt32(ExecState*) const;
99 int32_t toInt32(ExecState*, bool& ok) const;
100 uint32_t toUInt32(ExecState*) const;
101 uint32_t toUInt32(ExecState*, bool& ok) const;
102 uint16_t toUInt16(ExecState*) const;
103
104 // Garbage collection.
105 void mark();
106 bool marked() const;
107
108private:
109 // Implementation details.
110 JSCell *downcast();
111 const JSCell *downcast() const;
112
113 // Give a compile time error if we try to copy one of these.
114 JSValue(const JSValue&);
115 JSValue& operator=(const JSValue&);
116};
117
118class JSCell : public JSValue {
119 friend class Collector;
120 friend class NumberImp;
121 friend class StringImp;
122 friend class JSObject;
123 friend class GetterSetterImp;
124private:
125 explicit JSCell(bool destructorIsThreadSafe = true);
126 virtual ~JSCell();
127public:
128 // Querying the type.
129 virtual JSType type() const = 0;
130 bool isNumber() const;
131 bool isString() const;
132 bool isObject() const;
133 bool isObject(const ClassInfo *) const;
134
135 // Extracting the value.
136 bool getNumber(double&) const;
137 double getNumber() const; // NaN if not a number
138 bool getString(UString&) const;
139 UString getString() const; // null string if not a string
140 JSObject *getObject(); // NULL if not an object
141 const JSObject *getObject() const; // NULL if not an object
142
143 // Extracting integer values.
144 virtual bool getUInt32(uint32_t&) const;
145
146 // Basic conversions.
147 virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const = 0;
148 virtual bool toBoolean(ExecState *exec) const = 0;
149 virtual double toNumber(ExecState *exec) const = 0;
150 virtual UString toString(ExecState *exec) const = 0;
151 virtual JSObject *toObject(ExecState *exec) const = 0;
152
153 // Garbage collection.
154 void *operator new(size_t);
155 virtual void mark();
156 bool marked() const;
157
158private:
159 bool m_destructorIsThreadSafe : 1;
160 bool m_marked : 1;
161};
162
163JSValue *jsNumberCell(double);
164
165JSCell *jsString(const UString &); // returns empty string if passed null string
166JSCell *jsString(const char * = ""); // returns empty string if passed 0
167
168extern const double NaN;
169extern const double Inf;
170
171
172inline JSValue *jsUndefined()
173{
174 return JSImmediate::undefinedImmediate();
175}
176
177inline JSValue *jsNull()
178{
179 return JSImmediate::nullImmediate();
180}
181
182inline JSValue *jsNaN()
183{
184 return JSImmediate::NaNImmediate();
185}
186
187inline JSValue *jsBoolean(bool b)
188{
189 return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
190}
191
192inline JSValue *jsNumber(double d)
193{
194 JSValue *v = JSImmediate::fromDouble(d);
195 return v ? v : jsNumberCell(d);
196}
197
198inline JSValue::JSValue()
199{
200}
201
202inline JSValue::~JSValue()
203{
204}
205
206inline JSCell::JSCell(bool destructorIsThreadSafe)
207 : m_destructorIsThreadSafe(destructorIsThreadSafe)
208 , m_marked(false)
209{
210}
211
212inline JSCell::~JSCell()
213{
214}
215
216inline bool JSCell::isNumber() const
217{
218 return type() == NumberType;
219}
220
221inline bool JSCell::isString() const
222{
223 return type() == StringType;
224}
225
226inline bool JSCell::isObject() const
227{
228 return type() == ObjectType;
229}
230
231inline bool JSCell::marked() const
232{
233 return m_marked;
234}
235
236inline void JSCell::mark()
237{
238 m_marked = true;
239}
240
241inline JSCell *JSValue::downcast()
242{
243 ASSERT(!JSImmediate::isImmediate(this));
244 return static_cast<JSCell *>(this);
245}
246
247inline const JSCell *JSValue::downcast() const
248{
249 ASSERT(!JSImmediate::isImmediate(this));
250 return static_cast<const JSCell *>(this);
251}
252
253inline bool JSValue::isUndefined() const
254{
255 return this == jsUndefined();
256}
257
258inline bool JSValue::isNull() const
259{
260 return this == jsNull();
261}
262
263inline bool JSValue::isUndefinedOrNull() const
264{
265 return JSImmediate::isUndefinedOrNull(this);
266}
267
268inline bool JSValue::isBoolean() const
269{
270 return JSImmediate::isBoolean(this);
271}
272
273inline bool JSValue::isNumber() const
274{
275 return JSImmediate::isNumber(this) || !JSImmediate::isImmediate(this) && downcast()->isNumber();
276}
277
278inline bool JSValue::isString() const
279{
280 return !JSImmediate::isImmediate(this) && downcast()->isString();
281}
282
283inline bool JSValue::isObject() const
284{
285 return !JSImmediate::isImmediate(this) && downcast()->isObject();
286}
287
288inline bool JSValue::getBoolean(bool& v) const
289{
290 if (JSImmediate::isBoolean(this)) {
291 v = JSImmediate::toBoolean(this);
292 return true;
293 }
294
295 return false;
296}
297
298inline bool JSValue::getBoolean() const
299{
300 return JSImmediate::isBoolean(this) ? JSImmediate::toBoolean(this) : false;
301}
302
303inline bool JSValue::getNumber(double& v) const
304{
305 if (JSImmediate::isImmediate(this)) {
306 v = JSImmediate::toDouble(this);
307 return true;
308 }
309 return downcast()->getNumber(v);
310}
311
312inline double JSValue::getNumber() const
313{
314 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : downcast()->getNumber();
315}
316
317inline bool JSValue::getString(UString& s) const
318{
319 return !JSImmediate::isImmediate(this) && downcast()->getString(s);
320}
321
322inline UString JSValue::getString() const
323{
324 return JSImmediate::isImmediate(this) ? UString() : downcast()->getString();
325}
326
327inline JSObject *JSValue::getObject()
328{
329 return JSImmediate::isImmediate(this) ? 0 : downcast()->getObject();
330}
331
332inline const JSObject *JSValue::getObject() const
333{
334 return JSImmediate::isImmediate(this) ? 0 : downcast()->getObject();
335}
336
337inline bool JSValue::getUInt32(uint32_t& v) const
338{
339 if (JSImmediate::isImmediate(this)) {
340 double d = JSImmediate::toDouble(this);
341 if (!(d >= 0) || d > 0xFFFFFFFFUL) // true for NaN
342 return false;
343 v = static_cast<uint32_t>(d);
344 return JSImmediate::isNumber(this);
345 }
346 return downcast()->getUInt32(v);
347}
348
349inline void JSValue::mark()
350{
351 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()
352 downcast()->mark();
353}
354
355inline bool JSValue::marked() const
356{
357 return JSImmediate::isImmediate(this) || downcast()->marked();
358}
359
360inline JSType JSValue::type() const
361{
362 return JSImmediate::isImmediate(this) ? JSImmediate::type(this) : downcast()->type();
363}
364
365inline JSValue *JSValue::toPrimitive(ExecState *exec, JSType preferredType) const
366{
367 return JSImmediate::isImmediate(this) ? const_cast<JSValue *>(this) : downcast()->toPrimitive(exec, preferredType);
368}
369
370inline bool JSValue::toBoolean(ExecState *exec) const
371{
372 return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : downcast()->toBoolean(exec);
373}
374
375inline double JSValue::toNumber(ExecState *exec) const
376{
377 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : downcast()->toNumber(exec);
378}
379
380inline UString JSValue::toString(ExecState *exec) const
381{
382 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : downcast()->toString(exec);
383}
384
385inline JSObject* JSValue::toObject(ExecState* exec) const
386{
387 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : downcast()->toObject(exec);
388}
389
390} // namespace
391
392#endif // KJS_VALUE_H
Note: See TracBrowser for help on using the repository browser.