source: webkit/trunk/JavaScriptCore/runtime/JSCell.h@ 46598

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

Merged nitro-extreme branch into trunk.

  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library 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.
10 *
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 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef JSCell_h
24#define JSCell_h
25
26#include <wtf/Noncopyable.h>
27#include "Structure.h"
28#include "JSValue.h"
29#include "JSImmediate.h"
30#include "Collector.h"
31
32namespace JSC {
33
34 class JSCell : public NoncopyableCustomAllocated {
35 friend class GetterSetter;
36 friend class Heap;
37 friend class JIT;
38 friend class JSNumberCell;
39 friend class JSObject;
40 friend class JSPropertyNameIterator;
41 friend class JSString;
42 friend class JSValue;
43 friend class JSAPIValueWrapper;
44 friend struct VPtrSet;
45
46 private:
47 explicit JSCell(Structure*);
48 virtual ~JSCell();
49
50 public:
51 // Querying the type.
52#if USE(JSVALUE32)
53 bool isNumber() const;
54#endif
55 bool isString() const;
56 bool isObject() const;
57 virtual bool isGetterSetter() const;
58 virtual bool isObject(const ClassInfo*) const;
59 virtual bool isAPIValueWrapper() const { return false; }
60
61 Structure* structure() const;
62
63 // Extracting the value.
64 bool getString(UString&) const;
65 UString getString() const; // null string if not a string
66 JSObject* getObject(); // NULL if not an object
67 const JSObject* getObject() const; // NULL if not an object
68
69 virtual CallType getCallData(CallData&);
70 virtual ConstructType getConstructData(ConstructData&);
71
72 // Extracting integer values.
73 // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*.
74 virtual bool getUInt32(uint32_t&) const;
75
76 // Basic conversions.
77 virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
78 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&) = 0;
79 virtual bool toBoolean(ExecState*) const = 0;
80 virtual double toNumber(ExecState*) const = 0;
81 virtual UString toString(ExecState*) const = 0;
82 virtual JSObject* toObject(ExecState*) const = 0;
83
84 // Garbage collection.
85 void* operator new(size_t, ExecState*);
86 void* operator new(size_t, JSGlobalData*);
87 void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
88 virtual void mark();
89 bool marked() const;
90
91 // Object operations, with the toObject operation included.
92 virtual const ClassInfo* classInfo() const;
93 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
94 virtual void put(ExecState*, unsigned propertyName, JSValue);
95 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
96 virtual bool deleteProperty(ExecState*, unsigned propertyName);
97
98 virtual JSObject* toThisObject(ExecState*) const;
99 virtual UString toThisString(ExecState*) const;
100 virtual JSString* toThisJSString(ExecState*);
101 virtual JSValue getJSNumber();
102 void* vptr() { return *reinterpret_cast<void**>(this); }
103
104 private:
105 // Base implementation; for non-object classes implements getPropertySlot.
106 bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
107 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
108 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
109
110 Structure* m_structure;
111 };
112
113 JSCell* asCell(JSValue);
114
115 inline JSCell* asCell(JSValue value)
116 {
117 return value.asCell();
118 }
119
120 inline JSCell::JSCell(Structure* structure)
121 : m_structure(structure)
122 {
123 }
124
125 inline JSCell::~JSCell()
126 {
127 }
128
129#if USE(JSVALUE32)
130 inline bool JSCell::isNumber() const
131 {
132 return Heap::isNumber(const_cast<JSCell*>(this));
133 }
134#endif
135
136 inline bool JSCell::isObject() const
137 {
138 return m_structure->typeInfo().type() == ObjectType;
139 }
140
141 inline bool JSCell::isString() const
142 {
143 return m_structure->typeInfo().type() == StringType;
144 }
145
146 inline Structure* JSCell::structure() const
147 {
148 return m_structure;
149 }
150
151 inline bool JSCell::marked() const
152 {
153 return Heap::isCellMarked(this);
154 }
155
156 inline void JSCell::mark()
157 {
158 return Heap::markCell(this);
159 }
160
161 inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
162 {
163#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
164 return globalData->heap.inlineAllocate(size);
165#else
166 return globalData->heap.allocate(size);
167#endif
168 }
169
170 // --- JSValue inlines ----------------------------
171
172 inline bool JSValue::isString() const
173 {
174 return isCell() && asCell()->isString();
175 }
176
177 inline bool JSValue::isGetterSetter() const
178 {
179 return isCell() && asCell()->isGetterSetter();
180 }
181
182 inline bool JSValue::isObject() const
183 {
184 return isCell() && asCell()->isObject();
185 }
186
187 inline bool JSValue::getString(UString& s) const
188 {
189 return isCell() && asCell()->getString(s);
190 }
191
192 inline UString JSValue::getString() const
193 {
194 return isCell() ? asCell()->getString() : UString();
195 }
196
197 inline JSObject* JSValue::getObject() const
198 {
199 return isCell() ? asCell()->getObject() : 0;
200 }
201
202 inline CallType JSValue::getCallData(CallData& callData)
203 {
204 return isCell() ? asCell()->getCallData(callData) : CallTypeNone;
205 }
206
207 inline ConstructType JSValue::getConstructData(ConstructData& constructData)
208 {
209 return isCell() ? asCell()->getConstructData(constructData) : ConstructTypeNone;
210 }
211
212 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
213 {
214 if (isInt32()) {
215 int32_t i = asInt32();
216 v = static_cast<uint32_t>(i);
217 return i >= 0;
218 }
219 if (isDouble()) {
220 double d = asDouble();
221 v = static_cast<uint32_t>(d);
222 return v == d;
223 }
224 return false;
225 }
226
227 inline void JSValue::mark()
228 {
229 asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
230 }
231
232 inline bool JSValue::marked() const
233 {
234 return !isCell() || asCell()->marked();
235 }
236
237#if !USE(JSVALUE32_64)
238 ALWAYS_INLINE JSCell* JSValue::asCell() const
239 {
240 ASSERT(isCell());
241 return m_ptr;
242 }
243#endif // !USE(JSVALUE32_64)
244
245 inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
246 {
247 return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
248 }
249
250 inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
251 {
252 if (isInt32()) {
253 number = asInt32();
254 value = *this;
255 return true;
256 }
257 if (isDouble()) {
258 number = asDouble();
259 value = *this;
260 return true;
261 }
262 if (isCell())
263 return asCell()->getPrimitiveNumber(exec, number, value);
264 if (isTrue()) {
265 number = 1.0;
266 value = *this;
267 return true;
268 }
269 if (isFalse() || isNull()) {
270 number = 0.0;
271 value = *this;
272 return true;
273 }
274 ASSERT(isUndefined());
275 number = nonInlineNaN();
276 value = *this;
277 return true;
278 }
279
280 inline bool JSValue::toBoolean(ExecState* exec) const
281 {
282 if (isInt32())
283 return asInt32() != 0;
284 if (isDouble())
285 return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
286 if (isCell())
287 return asCell()->toBoolean(exec);
288 return isTrue(); // false, null, and undefined all convert to false.
289 }
290
291 ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
292 {
293 if (isInt32())
294 return asInt32();
295 if (isDouble())
296 return asDouble();
297 if (isCell())
298 return asCell()->toNumber(exec);
299 if (isTrue())
300 return 1.0;
301 return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
302 }
303
304 inline UString JSValue::toString(ExecState* exec) const
305 {
306 if (isCell())
307 return asCell()->toString(exec);
308 if (isInt32())
309 return UString::from(asInt32());
310 if (isDouble())
311 return asDouble() == 0.0 ? "0" : UString::from(asDouble());
312 if (isTrue())
313 return "true";
314 if (isFalse())
315 return "false";
316 if (isNull())
317 return "null";
318 ASSERT(isUndefined());
319 return "undefined";
320 }
321
322 inline bool JSValue::needsThisConversion() const
323 {
324 if (UNLIKELY(!isCell()))
325 return true;
326 return asCell()->structure()->typeInfo().needsThisConversion();
327 }
328
329 inline UString JSValue::toThisString(ExecState* exec) const
330 {
331 return isCell() ? asCell()->toThisString(exec) : toString(exec);
332 }
333
334 inline JSValue JSValue::getJSNumber()
335 {
336 if (isInt32() || isDouble())
337 return *this;
338 if (isCell())
339 return asCell()->getJSNumber();
340 return JSValue();
341 }
342
343 inline JSObject* JSValue::toObject(ExecState* exec) const
344 {
345 return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec);
346 }
347
348 inline JSObject* JSValue::toThisObject(ExecState* exec) const
349 {
350 return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
351 }
352
353} // namespace JSC
354
355#endif // JSCell_h
Note: See TracBrowser for help on using the repository browser.