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"
30 #include "SlotVisitor.h"
31 #include "TypedArrayDescriptor.h"
32 #include "WriteBarrier.h"
33 #include <wtf/Noncopyable.h>
34 #include <wtf/TypeTraits.h>
40 class JSDestructibleObject
;
42 class LLIntOffsetsExtractor
;
43 class PropertyDescriptor
;
44 class PropertyNameArray
;
47 enum EnumerationMode
{
48 ExcludeDontEnumProperties
,
49 IncludeDontEnumProperties
54 friend class MarkedBlock
;
55 template<typename T
> friend void* allocateCell(Heap
&);
56 template<typename T
> friend void* allocateCell(Heap
&, size_t);
59 static const unsigned StructureFlags
= 0;
61 static const bool needsDestruction
= false;
62 static const bool hasImmortalStructure
= false;
64 enum CreatingEarlyCellTag
{ CreatingEarlyCell
};
65 JSCell(CreatingEarlyCellTag
);
68 JSCell(VM
&, Structure
*);
69 JS_EXPORT_PRIVATE
static void destroy(JSCell
*);
73 bool isString() const;
74 bool isObject() const;
75 bool isGetterSetter() const;
77 bool inherits(const ClassInfo
*) const;
78 bool isAPIValueWrapper() const;
80 Structure
* structure() const;
81 void setStructure(VM
&, Structure
*);
82 void clearStructure() { m_structure
.clear(); }
84 const char* className();
86 // Extracting the value.
87 JS_EXPORT_PRIVATE
bool getString(ExecState
*, String
&) const;
88 JS_EXPORT_PRIVATE String
getString(ExecState
*) const; // null string if not a string
89 JS_EXPORT_PRIVATE JSObject
* getObject(); // NULL if not an object
90 const JSObject
* getObject() const; // NULL if not an object
92 JS_EXPORT_PRIVATE
static CallType
getCallData(JSCell
*, CallData
&);
93 JS_EXPORT_PRIVATE
static ConstructType
getConstructData(JSCell
*, ConstructData
&);
96 JS_EXPORT_PRIVATE JSValue
toPrimitive(ExecState
*, PreferredPrimitiveType
) const;
97 bool getPrimitiveNumber(ExecState
*, double& number
, JSValue
&) const;
98 bool toBoolean(ExecState
*) const;
99 TriState
pureToBoolean() const;
100 JS_EXPORT_PRIVATE
double toNumber(ExecState
*) const;
101 JS_EXPORT_PRIVATE JSObject
* toObject(ExecState
*, JSGlobalObject
*) const;
103 static void visitChildren(JSCell
*, SlotVisitor
&);
104 JS_EXPORT_PRIVATE
static void copyBackingStore(JSCell
*, CopyVisitor
&);
106 // Object operations, with the toObject operation included.
107 const ClassInfo
* classInfo() const;
108 const MethodTable
* methodTable() const;
109 const MethodTable
* methodTableForDestruction() const;
110 static void put(JSCell
*, ExecState
*, PropertyName
, JSValue
, PutPropertySlot
&);
111 static void putByIndex(JSCell
*, ExecState
*, unsigned propertyName
, JSValue
, bool shouldThrow
);
113 static bool deleteProperty(JSCell
*, ExecState
*, PropertyName
);
114 static bool deletePropertyByIndex(JSCell
*, ExecState
*, unsigned propertyName
);
116 static JSObject
* toThisObject(JSCell
*, ExecState
*);
118 void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
119 bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
121 // FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and
122 // fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always
123 // call this function, not its slower virtual counterpart. (For integer
124 // property names, we want a similar interface with appropriate optimizations.)
125 bool fastGetOwnPropertySlot(ExecState
*, PropertyName
, PropertySlot
&);
126 JSValue
fastGetOwnProperty(ExecState
*, const String
&);
128 static ptrdiff_t structureOffset()
130 return OBJECT_OFFSETOF(JSCell
, m_structure
);
133 void* structureAddress()
138 #if ENABLE(GC_VALIDATION)
139 Structure
* unvalidatedStructure() { return m_structure
.unvalidatedGet(); }
142 static const TypedArrayType TypedArrayStorageType
= TypedArrayNone
;
145 void finishCreation(VM
&);
146 void finishCreation(VM
&, Structure
*, CreatingEarlyCellTag
);
148 // Base implementation; for non-object classes implements getPropertySlot.
149 static bool getOwnPropertySlot(JSCell
*, ExecState
*, PropertyName
, PropertySlot
&);
150 static bool getOwnPropertySlotByIndex(JSCell
*, ExecState
*, unsigned propertyName
, PropertySlot
&);
152 // Dummy implementations of override-able static functions for classes to put in their MethodTable
153 static JSValue
defaultValue(const JSObject
*, ExecState
*, PreferredPrimitiveType
);
154 static NO_RETURN_DUE_TO_CRASH
void getOwnPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
155 static NO_RETURN_DUE_TO_CRASH
void getOwnNonIndexPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
156 static NO_RETURN_DUE_TO_CRASH
void getPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
157 static String
className(const JSObject
*);
158 JS_EXPORT_PRIVATE
static bool customHasInstance(JSObject
*, ExecState
*, JSValue
);
159 static NO_RETURN_DUE_TO_CRASH
void putDirectVirtual(JSObject
*, ExecState
*, PropertyName
, JSValue
, unsigned attributes
);
160 static bool defineOwnProperty(JSObject
*, ExecState
*, PropertyName
, PropertyDescriptor
&, bool shouldThrow
);
161 static bool getOwnPropertyDescriptor(JSObject
*, ExecState
*, PropertyName
, PropertyDescriptor
&);
164 friend class LLIntOffsetsExtractor
;
166 WriteBarrier
<Structure
> m_structure
;
169 template<typename To
, typename From
>
170 inline To
jsCast(From
* from
)
172 ASSERT(!from
|| from
->JSCell::inherits(&WTF::RemovePointer
<To
>::Type::s_info
));
173 return static_cast<To
>(from
);
176 template<typename To
>
177 inline To
jsCast(JSValue from
)
179 ASSERT(from
.isCell() && from
.asCell()->JSCell::inherits(&WTF::RemovePointer
<To
>::Type::s_info
));
180 return static_cast<To
>(from
.asCell());
183 template<typename To
, typename From
>
184 inline To
jsDynamicCast(From
* from
)
186 return from
->inherits(&WTF::RemovePointer
<To
>::Type::s_info
) ? static_cast<To
>(from
) : 0;
189 template<typename To
>
190 inline To
jsDynamicCast(JSValue from
)
192 return from
.isCell() && from
.asCell()->inherits(&WTF::RemovePointer
<To
>::Type::s_info
) ? static_cast<To
>(from
.asCell()) : 0;