2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
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.
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.
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.
26 #include <wtf/Noncopyable.h>
27 #include "Structure.h"
29 #include "JSImmediate.h"
30 #include "Collector.h"
34 class JSCell
: Noncopyable
{
36 friend class GetterSetter
;
38 friend class JSNumberCell
;
39 friend class JSObject
;
40 friend class JSPropertyNameIterator
;
41 friend class JSString
;
42 friend class JSValuePtr
;
43 friend class Interpreter
;
46 explicit JSCell(Structure
*);
51 bool isNumber() const;
52 bool isString() const;
53 bool isObject() const;
54 virtual bool isGetterSetter() const;
55 virtual bool isObject(const ClassInfo
*) const;
57 Structure
* structure() const;
59 // Extracting the value.
60 bool getString(UString
&) const;
61 UString
getString() const; // null string if not a string
62 JSObject
* getObject(); // NULL if not an object
63 const JSObject
* getObject() const; // NULL if not an object
65 virtual CallType
getCallData(CallData
&);
66 virtual ConstructType
getConstructData(ConstructData
&);
68 // Extracting integer values.
69 // FIXME: remove these methods, can check isNumberCell in JSValuePtr && then call asNumberCell::*.
70 virtual bool getUInt32(uint32_t&) const;
71 virtual bool getTruncatedInt32(int32_t&) const;
72 virtual bool getTruncatedUInt32(uint32_t&) const;
75 virtual JSValuePtr
toPrimitive(ExecState
*, PreferredPrimitiveType
) const = 0;
76 virtual bool getPrimitiveNumber(ExecState
*, double& number
, JSValuePtr
&) = 0;
77 virtual bool toBoolean(ExecState
*) const = 0;
78 virtual double toNumber(ExecState
*) const = 0;
79 virtual UString
toString(ExecState
*) const = 0;
80 virtual JSObject
* toObject(ExecState
*) const = 0;
82 // Garbage collection.
83 void* operator new(size_t, ExecState
*);
84 void* operator new(size_t, JSGlobalData
*);
85 void* operator new(size_t, void* placementNewDestination
) { return placementNewDestination
; }
89 // Object operations, with the toObject operation included.
90 virtual const ClassInfo
* classInfo() const;
91 virtual void put(ExecState
*, const Identifier
& propertyName
, JSValuePtr
, PutPropertySlot
&);
92 virtual void put(ExecState
*, unsigned propertyName
, JSValuePtr
);
93 virtual bool deleteProperty(ExecState
*, const Identifier
& propertyName
);
94 virtual bool deleteProperty(ExecState
*, unsigned propertyName
);
96 virtual JSObject
* toThisObject(ExecState
*) const;
97 virtual UString
toThisString(ExecState
*) const;
98 virtual JSString
* toThisJSString(ExecState
*);
99 virtual JSValuePtr
getJSNumber();
100 void* vptr() { return *reinterpret_cast<void**>(this); }
103 // Base implementation; for non-object classes implements getPropertySlot.
104 bool fastGetOwnPropertySlot(ExecState
*, const Identifier
& propertyName
, PropertySlot
&);
105 virtual bool getOwnPropertySlot(ExecState
*, const Identifier
& propertyName
, PropertySlot
&);
106 virtual bool getOwnPropertySlot(ExecState
*, unsigned propertyName
, PropertySlot
&);
108 Structure
* m_structure
;
111 JSCell
* asCell(JSValuePtr
);
113 inline JSCell
* asCell(JSValuePtr value
)
115 return value
.asCell();
118 inline JSCell::JSCell(Structure
* structure
)
119 : m_structure(structure
)
123 inline JSCell::~JSCell()
127 inline bool JSCell::isNumber() const
129 return Heap::isNumber(const_cast<JSCell
*>(this));
132 inline bool JSCell::isObject() const
134 return m_structure
->typeInfo().type() == ObjectType
;
137 inline bool JSCell::isString() const
139 return m_structure
->typeInfo().type() == StringType
;
142 inline Structure
* JSCell::structure() const
147 inline bool JSCell::marked() const
149 return Heap::isCellMarked(this);
152 inline void JSCell::mark()
154 return Heap::markCell(this);
157 ALWAYS_INLINE JSCell
* JSValuePtr::asCell() const
163 inline void* JSCell::operator new(size_t size
, JSGlobalData
* globalData
)
165 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
166 return globalData
->heap
.inlineAllocate(size
);
168 return globalData
->heap
.allocate(size
);
172 // --- JSValue inlines ----------------------------
174 inline bool JSValuePtr::isString() const
176 return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
179 inline bool JSValuePtr::isGetterSetter() const
181 return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
184 inline bool JSValuePtr::isObject() const
186 return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
189 inline bool JSValuePtr::getString(UString
& s
) const
191 return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s
);
194 inline UString
JSValuePtr::getString() const
196 return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
199 inline JSObject
* JSValuePtr::getObject() const
201 return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
204 inline CallType
JSValuePtr::getCallData(CallData
& callData
)
206 return JSImmediate::isImmediate(asValue()) ? CallTypeNone
: asCell()->getCallData(callData
);
209 inline ConstructType
JSValuePtr::getConstructData(ConstructData
& constructData
)
211 return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone
: asCell()->getConstructData(constructData
);
214 ALWAYS_INLINE
bool JSValuePtr::getUInt32(uint32_t& v
) const
216 return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v
) : asCell()->getUInt32(v
);
219 ALWAYS_INLINE
bool JSValuePtr::getTruncatedInt32(int32_t& v
) const
221 return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v
) : asCell()->getTruncatedInt32(v
);
224 inline bool JSValuePtr::getTruncatedUInt32(uint32_t& v
) const
226 return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v
) : asCell()->getTruncatedUInt32(v
);
229 inline void JSValuePtr::mark()
231 asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
234 inline bool JSValuePtr::marked() const
236 return JSImmediate::isImmediate(asValue()) || asCell()->marked();
239 inline JSValuePtr
JSValuePtr::toPrimitive(ExecState
* exec
, PreferredPrimitiveType preferredType
) const
241 return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec
, preferredType
);
244 inline bool JSValuePtr::getPrimitiveNumber(ExecState
* exec
, double& number
, JSValuePtr
& value
)
246 if (JSImmediate::isImmediate(asValue())) {
247 number
= JSImmediate::toDouble(asValue());
251 return asCell()->getPrimitiveNumber(exec
, number
, value
);
254 inline bool JSValuePtr::toBoolean(ExecState
* exec
) const
256 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec
);
259 ALWAYS_INLINE
double JSValuePtr::toNumber(ExecState
* exec
) const
261 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec
);
264 inline UString
JSValuePtr::toString(ExecState
* exec
) const
266 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec
);
269 inline JSObject
* JSValuePtr::toObject(ExecState
* exec
) const
271 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec
) : asCell()->toObject(exec
);
274 inline JSObject
* JSValuePtr::toThisObject(ExecState
* exec
) const
276 if (UNLIKELY(JSImmediate::isImmediate(asValue())))
277 return JSImmediate::toThisObject(asValue(), exec
);
278 return asCell()->toThisObject(exec
);
281 inline bool JSValuePtr::needsThisConversion() const
283 if (UNLIKELY(JSImmediate::isImmediate(asValue())))
285 return asCell()->structure()->typeInfo().needsThisConversion();
288 inline UString
JSValuePtr::toThisString(ExecState
* exec
) const
290 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec
);
293 inline JSValuePtr
JSValuePtr::getJSNumber()
295 return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();