]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
1 | /* |
2 | * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) | |
3 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) | |
f9bf01c6 | 4 | * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved. |
9dae56ea A |
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 | ||
14957cd0 | 26 | #include "CallData.h" |
14957cd0 A |
27 | #include "ConstructData.h" |
28 | #include "Heap.h" | |
81345200 | 29 | #include "IndexingType.h" |
14957cd0 | 30 | #include "JSLock.h" |
81345200 | 31 | #include "JSTypeInfo.h" |
6fe7ccc8 | 32 | #include "SlotVisitor.h" |
81345200 | 33 | #include "TypedArrayType.h" |
14957cd0 | 34 | #include "WriteBarrier.h" |
f9bf01c6 | 35 | #include <wtf/Noncopyable.h> |
9dae56ea A |
36 | |
37 | namespace JSC { | |
38 | ||
93a37866 A |
39 | class CopyVisitor; |
40 | class ExecState; | |
81345200 | 41 | class JSArrayBufferView; |
93a37866 A |
42 | class JSDestructibleObject; |
43 | class JSGlobalObject; | |
44 | class LLIntOffsetsExtractor; | |
45 | class PropertyDescriptor; | |
46 | class PropertyNameArray; | |
47 | class Structure; | |
48 | ||
49 | enum EnumerationMode { | |
50 | ExcludeDontEnumProperties, | |
51 | IncludeDontEnumProperties | |
52 | }; | |
53 | ||
81345200 A |
54 | template<typename T> void* allocateCell(Heap&); |
55 | template<typename T> void* allocateCell(Heap&, size_t); | |
56 | ||
57 | #define DECLARE_EXPORT_INFO \ | |
58 | protected: \ | |
59 | static JS_EXPORTDATA const ::JSC::ClassInfo s_info; \ | |
60 | public: \ | |
61 | static const ::JSC::ClassInfo* info() { return &s_info; } | |
62 | ||
63 | #define DECLARE_INFO \ | |
64 | protected: \ | |
65 | static const ::JSC::ClassInfo s_info; \ | |
66 | public: \ | |
67 | static const ::JSC::ClassInfo* info() { return &s_info; } | |
68 | ||
93a37866 A |
69 | class JSCell { |
70 | friend class JSValue; | |
71 | friend class MarkedBlock; | |
72 | template<typename T> friend void* allocateCell(Heap&); | |
73 | template<typename T> friend void* allocateCell(Heap&, size_t); | |
74 | ||
75 | public: | |
76 | static const unsigned StructureFlags = 0; | |
77 | ||
78 | static const bool needsDestruction = false; | |
79 | static const bool hasImmortalStructure = false; | |
80 | ||
81 | enum CreatingEarlyCellTag { CreatingEarlyCell }; | |
82 | JSCell(CreatingEarlyCellTag); | |
83 | ||
84 | protected: | |
85 | JSCell(VM&, Structure*); | |
86 | JS_EXPORT_PRIVATE static void destroy(JSCell*); | |
87 | ||
88 | public: | |
89 | // Querying the type. | |
90 | bool isString() const; | |
91 | bool isObject() const; | |
92 | bool isGetterSetter() const; | |
81345200 | 93 | bool isCustomGetterSetter() const; |
93a37866 A |
94 | bool isProxy() const; |
95 | bool inherits(const ClassInfo*) const; | |
96 | bool isAPIValueWrapper() const; | |
97 | ||
81345200 A |
98 | JSType type() const; |
99 | IndexingType indexingType() const; | |
100 | StructureID structureID() const { return m_structureID; } | |
93a37866 | 101 | Structure* structure() const; |
81345200 | 102 | Structure* structure(VM&) const; |
93a37866 | 103 | void setStructure(VM&, Structure*); |
81345200 A |
104 | void clearStructure() { m_structureID = 0; } |
105 | ||
106 | TypeInfo::InlineTypeFlags inlineTypeFlags() const { return m_flags; } | |
93a37866 | 107 | |
81345200 | 108 | const char* className() const; |
93a37866 A |
109 | |
110 | // Extracting the value. | |
111 | JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const; | |
112 | JS_EXPORT_PRIVATE String getString(ExecState*) const; // null string if not a string | |
113 | JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object | |
114 | const JSObject* getObject() const; // NULL if not an object | |
6fe7ccc8 | 115 | |
93a37866 A |
116 | JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&); |
117 | JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&); | |
118 | ||
119 | // Basic conversions. | |
120 | JS_EXPORT_PRIVATE JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; | |
121 | bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const; | |
122 | bool toBoolean(ExecState*) const; | |
123 | TriState pureToBoolean() const; | |
124 | JS_EXPORT_PRIVATE double toNumber(ExecState*) const; | |
125 | JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const; | |
126 | ||
81345200 A |
127 | void dump(PrintStream&) const; |
128 | JS_EXPORT_PRIVATE static void dumpToStream(const JSCell*, PrintStream&); | |
93a37866 | 129 | static void visitChildren(JSCell*, SlotVisitor&); |
81345200 | 130 | JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken); |
93a37866 A |
131 | |
132 | // Object operations, with the toObject operation included. | |
133 | const ClassInfo* classInfo() const; | |
134 | const MethodTable* methodTable() const; | |
81345200 | 135 | const MethodTable* methodTable(VM&) const; |
93a37866 A |
136 | static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); |
137 | static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); | |
9dae56ea | 138 | |
93a37866 A |
139 | static bool deleteProperty(JSCell*, ExecState*, PropertyName); |
140 | static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); | |
9dae56ea | 141 | |
81345200 | 142 | static JSValue toThis(JSCell*, ExecState*, ECMAMode); |
9dae56ea | 143 | |
93a37866 A |
144 | void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; } |
145 | bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); } | |
9dae56ea | 146 | |
81345200 A |
147 | static bool canUseFastGetOwnProperty(const Structure&); |
148 | JSValue fastGetOwnProperty(VM&, Structure&, const String&); | |
9dae56ea | 149 | |
81345200 A |
150 | enum GCData : uint8_t { |
151 | Marked = 0, | |
152 | NotMarked = 1, | |
153 | MarkedAndRemembered = 2, | |
154 | }; | |
155 | ||
156 | void setMarked() { m_gcData = Marked; } | |
157 | void setRemembered(bool remembered) | |
158 | { | |
159 | ASSERT(m_gcData == (remembered ? Marked : MarkedAndRemembered)); | |
160 | m_gcData = remembered ? MarkedAndRemembered : Marked; | |
161 | } | |
162 | bool isMarked() const | |
9dae56ea | 163 | { |
81345200 A |
164 | switch (m_gcData) { |
165 | case Marked: | |
166 | case MarkedAndRemembered: | |
167 | return true; | |
168 | case NotMarked: | |
169 | return false; | |
170 | } | |
171 | RELEASE_ASSERT_NOT_REACHED(); | |
172 | return false; | |
9dae56ea | 173 | } |
81345200 | 174 | bool isRemembered() const { return m_gcData == MarkedAndRemembered; } |
9dae56ea | 175 | |
81345200 | 176 | static ptrdiff_t structureIDOffset() |
9dae56ea | 177 | { |
81345200 | 178 | return OBJECT_OFFSETOF(JSCell, m_structureID); |
9dae56ea | 179 | } |
81345200 A |
180 | |
181 | static ptrdiff_t typeInfoFlagsOffset() | |
182 | { | |
183 | return OBJECT_OFFSETOF(JSCell, m_flags); | |
184 | } | |
185 | ||
186 | static ptrdiff_t typeInfoTypeOffset() | |
187 | { | |
188 | return OBJECT_OFFSETOF(JSCell, m_type); | |
189 | } | |
190 | ||
191 | static ptrdiff_t indexingTypeOffset() | |
192 | { | |
193 | return OBJECT_OFFSETOF(JSCell, m_indexingType); | |
194 | } | |
195 | ||
196 | static ptrdiff_t gcDataOffset() | |
197 | { | |
198 | return OBJECT_OFFSETOF(JSCell, m_gcData); | |
199 | } | |
200 | ||
201 | static const TypedArrayType TypedArrayStorageType = NotTypedArray; | |
93a37866 A |
202 | protected: |
203 | ||
204 | void finishCreation(VM&); | |
205 | void finishCreation(VM&, Structure*, CreatingEarlyCellTag); | |
206 | ||
93a37866 A |
207 | // Dummy implementations of override-able static functions for classes to put in their MethodTable |
208 | static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); | |
209 | static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); | |
210 | static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); | |
211 | static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); | |
212 | static String className(const JSObject*); | |
213 | JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue); | |
81345200 A |
214 | static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); |
215 | static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); | |
216 | static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); | |
217 | JS_EXPORT_PRIVATE static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*); | |
218 | JS_EXPORT_PRIVATE static PassRefPtr<ArrayBufferView> getTypedArrayImpl(JSArrayBufferView*); | |
93a37866 A |
219 | |
220 | private: | |
221 | friend class LLIntOffsetsExtractor; | |
81345200 A |
222 | |
223 | StructureID m_structureID; | |
224 | IndexingType m_indexingType; | |
225 | JSType m_type; | |
226 | TypeInfo::InlineTypeFlags m_flags; | |
227 | uint8_t m_gcData; | |
93a37866 A |
228 | }; |
229 | ||
230 | template<typename To, typename From> | |
231 | inline To jsCast(From* from) | |
232 | { | |
81345200 | 233 | ASSERT(!from || from->JSCell::inherits(std::remove_pointer<To>::type::info())); |
93a37866 A |
234 | return static_cast<To>(from); |
235 | } | |
14957cd0 | 236 | |
93a37866 A |
237 | template<typename To> |
238 | inline To jsCast(JSValue from) | |
239 | { | |
81345200 | 240 | ASSERT(from.isCell() && from.asCell()->JSCell::inherits(std::remove_pointer<To>::type::info())); |
93a37866 A |
241 | return static_cast<To>(from.asCell()); |
242 | } | |
243 | ||
244 | template<typename To, typename From> | |
245 | inline To jsDynamicCast(From* from) | |
246 | { | |
81345200 A |
247 | if (LIKELY(from->inherits(std::remove_pointer<To>::type::info()))) |
248 | return static_cast<To>(from); | |
249 | return nullptr; | |
93a37866 A |
250 | } |
251 | ||
252 | template<typename To> | |
253 | inline To jsDynamicCast(JSValue from) | |
254 | { | |
81345200 A |
255 | if (LIKELY(from.isCell() && from.asCell()->inherits(std::remove_pointer<To>::type::info()))) |
256 | return static_cast<To>(from.asCell()); | |
257 | return nullptr; | |
93a37866 | 258 | } |
14957cd0 | 259 | |
9dae56ea A |
260 | } // namespace JSC |
261 | ||
262 | #endif // JSCell_h |