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, 2009 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 "Collector.h"
27 #include "JSImmediate.h"
29 #include "MarkStack.h"
30 #include "Structure.h"
31 #include <wtf/Noncopyable.h>
35 class JSCell
: public NoncopyableCustomAllocated
{
36 friend class GetterSetter
;
39 friend class JSNumberCell
;
40 friend class JSObject
;
41 friend class JSPropertyNameIterator
;
42 friend class JSString
;
44 friend class JSAPIValueWrapper
;
45 friend class JSZombie
;
46 friend class JSGlobalData
;
49 explicit JSCell(Structure
*);
53 static PassRefPtr
<Structure
> createDummyStructure()
55 return Structure::create(jsNull(), TypeInfo(UnspecifiedType
), AnonymousSlotCount
);
60 bool isNumber() const;
62 bool isString() const;
63 bool isObject() const;
64 virtual bool isGetterSetter() const;
65 bool inherits(const ClassInfo
*) const;
66 virtual bool isAPIValueWrapper() const { return false; }
67 virtual bool isPropertyNameIterator() const { return false; }
69 Structure
* structure() const;
71 // Extracting the value.
72 bool getString(ExecState
* exec
, UString
&) const;
73 UString
getString(ExecState
* exec
) const; // null string if not a string
74 JSObject
* getObject(); // NULL if not an object
75 const JSObject
* getObject() const; // NULL if not an object
77 virtual CallType
getCallData(CallData
&);
78 virtual ConstructType
getConstructData(ConstructData
&);
80 // Extracting integer values.
81 // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*.
82 virtual bool getUInt32(uint32_t&) const;
85 virtual JSValue
toPrimitive(ExecState
*, PreferredPrimitiveType
) const;
86 virtual bool getPrimitiveNumber(ExecState
*, double& number
, JSValue
&);
87 virtual bool toBoolean(ExecState
*) const;
88 virtual double toNumber(ExecState
*) const;
89 virtual UString
toString(ExecState
*) const;
90 virtual JSObject
* toObject(ExecState
*) const;
92 // Garbage collection.
93 void* operator new(size_t, ExecState
*);
94 void* operator new(size_t, JSGlobalData
*);
95 void* operator new(size_t, void* placementNewDestination
) { return placementNewDestination
; }
97 virtual void markChildren(MarkStack
&);
98 #if ENABLE(JSC_ZOMBIES)
99 virtual bool isZombie() const { return false; }
102 // Object operations, with the toObject operation included.
103 virtual const ClassInfo
* classInfo() const;
104 virtual void put(ExecState
*, const Identifier
& propertyName
, JSValue
, PutPropertySlot
&);
105 virtual void put(ExecState
*, unsigned propertyName
, JSValue
);
106 virtual bool deleteProperty(ExecState
*, const Identifier
& propertyName
);
107 virtual bool deleteProperty(ExecState
*, unsigned propertyName
);
109 virtual JSObject
* toThisObject(ExecState
*) const;
110 virtual UString
toThisString(ExecState
*) const;
111 virtual JSString
* toThisJSString(ExecState
*);
112 virtual JSValue
getJSNumber();
113 void* vptr() { return *reinterpret_cast<void**>(this); }
114 void setVPtr(void* vptr
) { *reinterpret_cast<void**>(this) = vptr
; }
117 static const unsigned AnonymousSlotCount
= 0;
120 // Base implementation; for non-object classes implements getPropertySlot.
121 bool fastGetOwnPropertySlot(ExecState
*, const Identifier
& propertyName
, PropertySlot
&);
122 virtual bool getOwnPropertySlot(ExecState
*, const Identifier
& propertyName
, PropertySlot
&);
123 virtual bool getOwnPropertySlot(ExecState
*, unsigned propertyName
, PropertySlot
&);
125 Structure
* m_structure
;
128 inline JSCell::JSCell(Structure
* structure
)
129 : m_structure(structure
)
133 inline JSCell::~JSCell()
138 inline bool JSCell::isNumber() const
140 return m_structure
->typeInfo().type() == NumberType
;
144 inline bool JSCell::isObject() const
146 return m_structure
->typeInfo().type() == ObjectType
;
149 inline bool JSCell::isString() const
151 return m_structure
->typeInfo().type() == StringType
;
154 inline Structure
* JSCell::structure() const
159 inline void JSCell::markChildren(MarkStack
&)
163 inline void* JSCell::operator new(size_t size
, JSGlobalData
* globalData
)
165 return globalData
->heap
.allocate(size
);
168 inline void* JSCell::operator new(size_t size
, ExecState
* exec
)
170 return exec
->heap()->allocate(size
);
173 // --- JSValue inlines ----------------------------
175 inline bool JSValue::isString() const
177 return isCell() && asCell()->isString();
180 inline bool JSValue::isGetterSetter() const
182 return isCell() && asCell()->isGetterSetter();
185 inline bool JSValue::isObject() const
187 return isCell() && asCell()->isObject();
190 inline bool JSValue::getString(ExecState
* exec
, UString
& s
) const
192 return isCell() && asCell()->getString(exec
, s
);
195 inline UString
JSValue::getString(ExecState
* exec
) const
197 return isCell() ? asCell()->getString(exec
) : UString();
200 inline JSObject
* JSValue::getObject() const
202 return isCell() ? asCell()->getObject() : 0;
205 inline CallType
JSValue::getCallData(CallData
& callData
)
207 return isCell() ? asCell()->getCallData(callData
) : CallTypeNone
;
210 inline ConstructType
JSValue::getConstructData(ConstructData
& constructData
)
212 return isCell() ? asCell()->getConstructData(constructData
) : ConstructTypeNone
;
215 ALWAYS_INLINE
bool JSValue::getUInt32(uint32_t& v
) const
218 int32_t i
= asInt32();
219 v
= static_cast<uint32_t>(i
);
223 double d
= asDouble();
224 v
= static_cast<uint32_t>(d
);
230 #if !USE(JSVALUE32_64)
231 ALWAYS_INLINE JSCell
* JSValue::asCell() const
236 #endif // !USE(JSVALUE32_64)
238 inline JSValue
JSValue::toPrimitive(ExecState
* exec
, PreferredPrimitiveType preferredType
) const
240 return isCell() ? asCell()->toPrimitive(exec
, preferredType
) : asValue();
243 inline bool JSValue::getPrimitiveNumber(ExecState
* exec
, double& number
, JSValue
& value
)
256 return asCell()->getPrimitiveNumber(exec
, number
, value
);
262 if (isFalse() || isNull()) {
267 ASSERT(isUndefined());
268 number
= nonInlineNaN();
273 inline bool JSValue::toBoolean(ExecState
* exec
) const
276 return asInt32() != 0;
278 return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
280 return asCell()->toBoolean(exec
);
281 return isTrue(); // false, null, and undefined all convert to false.
284 ALWAYS_INLINE
double JSValue::toNumber(ExecState
* exec
) const
291 return asCell()->toNumber(exec
);
294 return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
297 inline bool JSValue::needsThisConversion() const
299 if (UNLIKELY(!isCell()))
301 return asCell()->structure()->typeInfo().needsThisConversion();
304 inline UString
JSValue::toThisString(ExecState
* exec
) const
306 return isCell() ? asCell()->toThisString(exec
) : toString(exec
);
309 inline JSValue
JSValue::getJSNumber()
311 if (isInt32() || isDouble())
314 return asCell()->getJSNumber();
318 inline JSObject
* JSValue::toObject(ExecState
* exec
) const
320 return isCell() ? asCell()->toObject(exec
) : toObjectSlowCase(exec
);
323 inline JSObject
* JSValue::toThisObject(ExecState
* exec
) const
325 return isCell() ? asCell()->toThisObject(exec
) : toThisObjectSlowCase(exec
);
328 ALWAYS_INLINE
void MarkStack::append(JSCell
* cell
)
330 ASSERT(!m_isCheckingForDefaultMarkViolation
);
332 if (Heap::isCellMarked(cell
))
334 Heap::markCell(cell
);
335 if (cell
->structure()->typeInfo().type() >= CompoundType
)
336 m_values
.append(cell
);
339 ALWAYS_INLINE
void MarkStack::append(JSValue value
)
343 append(value
.asCell());
346 inline Heap
* Heap::heap(JSValue v
)
350 return heap(v
.asCell());
353 inline Heap
* Heap::heap(JSCell
* c
)
355 return cellBlock(c
)->heap
;
358 #if ENABLE(JSC_ZOMBIES)
359 inline bool JSValue::isZombie() const
361 return isCell() && asCell() && asCell()->isZombie();