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.
27 #include "ConstructData.h"
28 #include "EnumerationMode.h"
30 #include "IndexingType.h"
32 #include "JSTypeInfo.h"
33 #include "SlotVisitor.h"
34 #include "TypedArrayType.h"
35 #include "WriteBarrier.h"
36 #include <wtf/Noncopyable.h>
43 class JSArrayBufferView
;
44 class JSDestructibleObject
;
46 class LLIntOffsetsExtractor
;
47 class PropertyDescriptor
;
48 class PropertyNameArray
;
51 template<typename T
> void* allocateCell(Heap
&);
52 template<typename T
> void* allocateCell(Heap
&, size_t);
54 #define DECLARE_EXPORT_INFO \
56 static JS_EXPORTDATA const ::JSC::ClassInfo s_info; \
58 static const ::JSC::ClassInfo* info() { return &s_info; }
60 #define DECLARE_INFO \
62 static const ::JSC::ClassInfo s_info; \
64 static const ::JSC::ClassInfo* info() { return &s_info; }
68 friend class MarkedBlock
;
69 template<typename T
> friend void* allocateCell(Heap
&);
70 template<typename T
> friend void* allocateCell(Heap
&, size_t);
73 static const unsigned StructureFlags
= 0;
75 static const bool needsDestruction
= false;
77 static JSCell
* seenMultipleCalleeObjects() { return bitwise_cast
<JSCell
*>(static_cast<uintptr_t>(1)); }
79 enum CreatingEarlyCellTag
{ CreatingEarlyCell
};
80 JSCell(CreatingEarlyCellTag
);
83 JSCell(VM
&, Structure
*);
84 JS_EXPORT_PRIVATE
static void destroy(JSCell
*);
88 bool isString() const;
89 bool isSymbol() const;
90 bool isObject() const;
91 bool isGetterSetter() const;
92 bool isCustomGetterSetter() const;
94 bool inherits(const ClassInfo
*) const;
95 bool isAPIValueWrapper() const;
98 IndexingType
indexingType() const;
99 StructureID
structureID() const { return m_structureID
; }
100 Structure
* structure() const;
101 Structure
* structure(VM
&) const;
102 void setStructure(VM
&, Structure
*);
103 void clearStructure() { m_structureID
= 0; }
105 TypeInfo::InlineTypeFlags
inlineTypeFlags() const { return m_flags
; }
107 const char* className() const;
111 // Extracting the value.
112 JS_EXPORT_PRIVATE
bool getString(ExecState
*, String
&) const;
113 JS_EXPORT_PRIVATE String
getString(ExecState
*) const; // null string if not a string
114 JS_EXPORT_PRIVATE JSObject
* getObject(); // NULL if not an object
115 const JSObject
* getObject() const; // NULL if not an object
117 // Returns information about how to call/construct this cell as a function/constructor. May tell
118 // you that the cell is not callable or constructor (default is that it's not either). If it
119 // says that the function is callable, and the TypeOfShouldCallGetCallData type flag is set, and
120 // this is an object, then typeof will return "function" instead of "object". These methods
121 // cannot change their minds and must be thread-safe. They are sometimes called from compiler
123 JS_EXPORT_PRIVATE
static CallType
getCallData(JSCell
*, CallData
&);
124 JS_EXPORT_PRIVATE
static ConstructType
getConstructData(JSCell
*, ConstructData
&);
126 // Basic conversions.
127 JS_EXPORT_PRIVATE JSValue
toPrimitive(ExecState
*, PreferredPrimitiveType
) const;
128 bool getPrimitiveNumber(ExecState
*, double& number
, JSValue
&) const;
129 bool toBoolean(ExecState
*) const;
130 TriState
pureToBoolean() const;
131 JS_EXPORT_PRIVATE
double toNumber(ExecState
*) const;
132 JS_EXPORT_PRIVATE JSObject
* toObject(ExecState
*, JSGlobalObject
*) const;
134 void dump(PrintStream
&) const;
135 JS_EXPORT_PRIVATE
static void dumpToStream(const JSCell
*, PrintStream
&);
136 static void visitChildren(JSCell
*, SlotVisitor
&);
137 JS_EXPORT_PRIVATE
static void copyBackingStore(JSCell
*, CopyVisitor
&, CopyToken
);
139 // Object operations, with the toObject operation included.
140 const ClassInfo
* classInfo() const;
141 const MethodTable
* methodTable() const;
142 const MethodTable
* methodTable(VM
&) const;
143 static void put(JSCell
*, ExecState
*, PropertyName
, JSValue
, PutPropertySlot
&);
144 static void putByIndex(JSCell
*, ExecState
*, unsigned propertyName
, JSValue
, bool shouldThrow
);
146 static bool deleteProperty(JSCell
*, ExecState
*, PropertyName
);
147 static bool deletePropertyByIndex(JSCell
*, ExecState
*, unsigned propertyName
);
149 static JSValue
toThis(JSCell
*, ExecState
*, ECMAMode
);
151 void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
152 bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
154 static bool canUseFastGetOwnProperty(const Structure
&);
155 JSValue
fastGetOwnProperty(VM
&, Structure
&, PropertyName
);
157 enum GCData
: uint8_t {
158 Marked
= 0, // The object has survived a GC and is in the old gen.
159 NotMarked
= 1, // The object is new and in the eden gen.
160 MarkedAndRemembered
= 2, // The object is in the GC's remembered set.
162 // The object being in the GC's remembered set implies that it is also
163 // Marked. This is because objects are only added to the remembered sets
164 // by write barriers, and write barriers are only interested in old gen
165 // objects that point to potential eden gen objects.
168 void setMarked() { m_gcData
= Marked
; }
169 void setRemembered(bool remembered
)
171 ASSERT(m_gcData
== (remembered
? Marked
: MarkedAndRemembered
));
172 m_gcData
= remembered
? MarkedAndRemembered
: Marked
;
174 bool isMarked() const
178 case MarkedAndRemembered
:
183 RELEASE_ASSERT_NOT_REACHED();
186 bool isRemembered() const { return m_gcData
== MarkedAndRemembered
; }
188 static ptrdiff_t structureIDOffset()
190 return OBJECT_OFFSETOF(JSCell
, m_structureID
);
193 static ptrdiff_t typeInfoFlagsOffset()
195 return OBJECT_OFFSETOF(JSCell
, m_flags
);
198 static ptrdiff_t typeInfoTypeOffset()
200 return OBJECT_OFFSETOF(JSCell
, m_type
);
203 static ptrdiff_t indexingTypeOffset()
205 return OBJECT_OFFSETOF(JSCell
, m_indexingType
);
208 static ptrdiff_t gcDataOffset()
210 return OBJECT_OFFSETOF(JSCell
, m_gcData
);
213 static const TypedArrayType TypedArrayStorageType
= NotTypedArray
;
216 void finishCreation(VM
&);
217 void finishCreation(VM
&, Structure
*, CreatingEarlyCellTag
);
219 // Dummy implementations of override-able static functions for classes to put in their MethodTable
220 static JSValue
defaultValue(const JSObject
*, ExecState
*, PreferredPrimitiveType
);
221 static NO_RETURN_DUE_TO_CRASH
void getOwnPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
222 static NO_RETURN_DUE_TO_CRASH
void getOwnNonIndexPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
223 static NO_RETURN_DUE_TO_CRASH
void getPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
225 static uint32_t getEnumerableLength(ExecState
*, JSObject
*);
226 static NO_RETURN_DUE_TO_CRASH
void getStructurePropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
227 static NO_RETURN_DUE_TO_CRASH
void getGenericPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
229 static String
className(const JSObject
*);
230 JS_EXPORT_PRIVATE
static bool customHasInstance(JSObject
*, ExecState
*, JSValue
);
231 static bool defineOwnProperty(JSObject
*, ExecState
*, PropertyName
, const PropertyDescriptor
&, bool shouldThrow
);
232 static bool getOwnPropertySlot(JSObject
*, ExecState
*, PropertyName
, PropertySlot
&);
233 static bool getOwnPropertySlotByIndex(JSObject
*, ExecState
*, unsigned propertyName
, PropertySlot
&);
234 JS_EXPORT_PRIVATE
static ArrayBuffer
* slowDownAndWasteMemory(JSArrayBufferView
*);
235 JS_EXPORT_PRIVATE
static PassRefPtr
<ArrayBufferView
> getTypedArrayImpl(JSArrayBufferView
*);
238 friend class LLIntOffsetsExtractor
;
240 StructureID m_structureID
;
241 IndexingType m_indexingType
;
243 TypeInfo::InlineTypeFlags m_flags
;
247 template<typename To
, typename From
>
248 inline To
jsCast(From
* from
)
250 ASSERT_WITH_SECURITY_IMPLICATION(!from
|| from
->JSCell::inherits(std::remove_pointer
<To
>::type::info()));
251 return static_cast<To
>(from
);
254 template<typename To
>
255 inline To
jsCast(JSValue from
)
257 ASSERT_WITH_SECURITY_IMPLICATION(from
.isCell() && from
.asCell()->JSCell::inherits(std::remove_pointer
<To
>::type::info()));
258 return static_cast<To
>(from
.asCell());
261 template<typename To
, typename From
>
262 inline To
jsDynamicCast(From
* from
)
264 if (LIKELY(from
->inherits(std::remove_pointer
<To
>::type::info())))
265 return static_cast<To
>(from
);
269 template<typename To
>
270 inline To
jsDynamicCast(JSValue from
)
272 if (LIKELY(from
.isCell() && from
.asCell()->inherits(std::remove_pointer
<To
>::type::info())))
273 return static_cast<To
>(from
.asCell());