22abf7931f90708f516711faf48c5aab33ff28d5
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSCell.h
1 /*
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.
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 "CallData.h"
27 #include "ConstructData.h"
28 #include "Heap.h"
29 #include "JSLock.h"
30 #include "SlotVisitor.h"
31 #include "TypedArrayDescriptor.h"
32 #include "WriteBarrier.h"
33 #include <wtf/Noncopyable.h>
34 #include <wtf/TypeTraits.h>
35
36 namespace JSC {
37
38 class CopyVisitor;
39 class ExecState;
40 class JSDestructibleObject;
41 class JSGlobalObject;
42 class LLIntOffsetsExtractor;
43 class PropertyDescriptor;
44 class PropertyNameArray;
45 class Structure;
46
47 enum EnumerationMode {
48     ExcludeDontEnumProperties,
49     IncludeDontEnumProperties
50 };
51
52 template<typename T> void* allocateCell(Heap&);
53 template<typename T> void* allocateCell(Heap&, size_t);
54
55 class JSCell {
56     friend class JSValue;
57     friend class MarkedBlock;
58     template<typename T> friend void* allocateCell(Heap&);
59     template<typename T> friend void* allocateCell(Heap&, size_t);
60
61 public:
62     static const unsigned StructureFlags = 0;
63
64     static const bool needsDestruction = false;
65     static const bool hasImmortalStructure = false;
66
67     enum CreatingEarlyCellTag { CreatingEarlyCell };
68     JSCell(CreatingEarlyCellTag);
69
70 protected:
71     JSCell(VM&, Structure*);
72     JS_EXPORT_PRIVATE static void destroy(JSCell*);
73
74 public:
75     // Querying the type.
76     bool isString() const;
77     bool isObject() const;
78     bool isGetterSetter() const;
79     bool isProxy() const;
80     bool inherits(const ClassInfo*) const;
81     bool isAPIValueWrapper() const;
82
83     Structure* structure() const;
84     void setStructure(VM&, Structure*);
85     void clearStructure() { m_structure.clear(); }
86
87     const char* className();
88
89     // Extracting the value.
90     JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const;
91     JS_EXPORT_PRIVATE String getString(ExecState*) const; // null string if not a string
92     JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object
93     const JSObject* getObject() const; // NULL if not an object
94         
95     JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);
96     JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
97
98     // Basic conversions.
99     JS_EXPORT_PRIVATE JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
100     bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
101     bool toBoolean(ExecState*) const;
102     TriState pureToBoolean() const;
103     JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
104     JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const;
105
106     static void visitChildren(JSCell*, SlotVisitor&);
107     JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
108
109     // Object operations, with the toObject operation included.
110     const ClassInfo* classInfo() const;
111     const MethodTable* methodTable() const;
112     const MethodTable* methodTableForDestruction() const;
113     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
114     static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
115         
116     static bool deleteProperty(JSCell*, ExecState*, PropertyName);
117     static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
118
119     static JSValue toThis(JSCell*, ExecState*, ECMAMode);
120
121     void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
122     bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
123
124     JSValue fastGetOwnProperty(ExecState*, const String&);
125
126     static ptrdiff_t structureOffset()
127     {
128         return OBJECT_OFFSETOF(JSCell, m_structure);
129     }
130
131     void* structureAddress()
132     {
133         return &m_structure;
134     }
135         
136 #if ENABLE(GC_VALIDATION)
137     Structure* unvalidatedStructure() { return m_structure.unvalidatedGet(); }
138 #endif
139         
140     static const TypedArrayType TypedArrayStorageType = TypedArrayNone;
141 protected:
142
143     void finishCreation(VM&);
144     void finishCreation(VM&, Structure*, CreatingEarlyCellTag);
145
146     // Dummy implementations of override-able static functions for classes to put in their MethodTable
147     static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
148     static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
149     static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
150     static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
151     static String className(const JSObject*);
152     JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue);
153     static NO_RETURN_DUE_TO_CRASH void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
154     static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
155     static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
156     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
157     static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
158
159 private:
160     friend class LLIntOffsetsExtractor;
161         
162     WriteBarrier<Structure> m_structure;
163 };
164
165 template<typename To, typename From>
166 inline To jsCast(From* from)
167 {
168     ASSERT(!from || from->JSCell::inherits(&WTF::RemovePointer<To>::Type::s_info));
169     return static_cast<To>(from);
170 }
171     
172 template<typename To>
173 inline To jsCast(JSValue from)
174 {
175     ASSERT(from.isCell() && from.asCell()->JSCell::inherits(&WTF::RemovePointer<To>::Type::s_info));
176     return static_cast<To>(from.asCell());
177 }
178
179 template<typename To, typename From>
180 inline To jsDynamicCast(From* from)
181 {
182     return from->inherits(&WTF::RemovePointer<To>::Type::s_info) ? static_cast<To>(from) : 0;
183 }
184
185 template<typename To>
186 inline To jsDynamicCast(JSValue from)
187 {
188     return from.isCell() && from.asCell()->inherits(&WTF::RemovePointer<To>::Type::s_info) ? static_cast<To>(from.asCell()) : 0;
189 }
190
191 } // namespace JSC
192
193 #endif // JSCell_h