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