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

Last change on this file since 23470 was 23470, checked in by andersca, 18 years ago

Reviewed by Maciej.

Have JSCell inherit from Noncopyable.


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