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

Last change on this file since 12172 was 11962, checked in by thatcher, 19 years ago

Removes svn:keywords from all files.

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