]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSCell.h
JavaScriptCore-525.tar.gz
[apple/javascriptcore.git] / 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 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 <wtf/Noncopyable.h>
27 #include "Structure.h"
28 #include "JSValue.h"
29 #include "JSImmediate.h"
30 #include "Collector.h"
31
32 namespace JSC {
33
34 class JSCell : Noncopyable {
35 friend class JIT;
36 friend class GetterSetter;
37 friend class Heap;
38 friend class JSNumberCell;
39 friend class JSObject;
40 friend class JSPropertyNameIterator;
41 friend class JSString;
42 friend class JSValuePtr;
43 friend class Interpreter;
44
45 private:
46 explicit JSCell(Structure*);
47 virtual ~JSCell();
48
49 public:
50 // Querying the type.
51 bool isNumber() const;
52 bool isString() const;
53 bool isObject() const;
54 virtual bool isGetterSetter() const;
55 virtual bool isObject(const ClassInfo*) const;
56
57 Structure* structure() const;
58
59 // Extracting the value.
60 bool getString(UString&) const;
61 UString getString() const; // null string if not a string
62 JSObject* getObject(); // NULL if not an object
63 const JSObject* getObject() const; // NULL if not an object
64
65 virtual CallType getCallData(CallData&);
66 virtual ConstructType getConstructData(ConstructData&);
67
68 // Extracting integer values.
69 // FIXME: remove these methods, can check isNumberCell in JSValuePtr && then call asNumberCell::*.
70 virtual bool getUInt32(uint32_t&) const;
71 virtual bool getTruncatedInt32(int32_t&) const;
72 virtual bool getTruncatedUInt32(uint32_t&) const;
73
74 // Basic conversions.
75 virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
76 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&) = 0;
77 virtual bool toBoolean(ExecState*) const = 0;
78 virtual double toNumber(ExecState*) const = 0;
79 virtual UString toString(ExecState*) const = 0;
80 virtual JSObject* toObject(ExecState*) const = 0;
81
82 // Garbage collection.
83 void* operator new(size_t, ExecState*);
84 void* operator new(size_t, JSGlobalData*);
85 void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
86 virtual void mark();
87 bool marked() const;
88
89 // Object operations, with the toObject operation included.
90 virtual const ClassInfo* classInfo() const;
91 virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
92 virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
93 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
94 virtual bool deleteProperty(ExecState*, unsigned propertyName);
95
96 virtual JSObject* toThisObject(ExecState*) const;
97 virtual UString toThisString(ExecState*) const;
98 virtual JSString* toThisJSString(ExecState*);
99 virtual JSValuePtr getJSNumber();
100 void* vptr() { return *reinterpret_cast<void**>(this); }
101
102 private:
103 // Base implementation; for non-object classes implements getPropertySlot.
104 bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
105 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
106 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
107
108 Structure* m_structure;
109 };
110
111 JSCell* asCell(JSValuePtr);
112
113 inline JSCell* asCell(JSValuePtr value)
114 {
115 return value.asCell();
116 }
117
118 inline JSCell::JSCell(Structure* structure)
119 : m_structure(structure)
120 {
121 }
122
123 inline JSCell::~JSCell()
124 {
125 }
126
127 inline bool JSCell::isNumber() const
128 {
129 return Heap::isNumber(const_cast<JSCell*>(this));
130 }
131
132 inline bool JSCell::isObject() const
133 {
134 return m_structure->typeInfo().type() == ObjectType;
135 }
136
137 inline bool JSCell::isString() const
138 {
139 return m_structure->typeInfo().type() == StringType;
140 }
141
142 inline Structure* JSCell::structure() const
143 {
144 return m_structure;
145 }
146
147 inline bool JSCell::marked() const
148 {
149 return Heap::isCellMarked(this);
150 }
151
152 inline void JSCell::mark()
153 {
154 return Heap::markCell(this);
155 }
156
157 ALWAYS_INLINE JSCell* JSValuePtr::asCell() const
158 {
159 ASSERT(isCell());
160 return m_ptr;
161 }
162
163 inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
164 {
165 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
166 return globalData->heap.inlineAllocate(size);
167 #else
168 return globalData->heap.allocate(size);
169 #endif
170 }
171
172 // --- JSValue inlines ----------------------------
173
174 inline bool JSValuePtr::isString() const
175 {
176 return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
177 }
178
179 inline bool JSValuePtr::isGetterSetter() const
180 {
181 return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
182 }
183
184 inline bool JSValuePtr::isObject() const
185 {
186 return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
187 }
188
189 inline bool JSValuePtr::getString(UString& s) const
190 {
191 return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
192 }
193
194 inline UString JSValuePtr::getString() const
195 {
196 return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
197 }
198
199 inline JSObject* JSValuePtr::getObject() const
200 {
201 return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
202 }
203
204 inline CallType JSValuePtr::getCallData(CallData& callData)
205 {
206 return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData);
207 }
208
209 inline ConstructType JSValuePtr::getConstructData(ConstructData& constructData)
210 {
211 return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData);
212 }
213
214 ALWAYS_INLINE bool JSValuePtr::getUInt32(uint32_t& v) const
215 {
216 return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v);
217 }
218
219 ALWAYS_INLINE bool JSValuePtr::getTruncatedInt32(int32_t& v) const
220 {
221 return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v);
222 }
223
224 inline bool JSValuePtr::getTruncatedUInt32(uint32_t& v) const
225 {
226 return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v);
227 }
228
229 inline void JSValuePtr::mark()
230 {
231 asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
232 }
233
234 inline bool JSValuePtr::marked() const
235 {
236 return JSImmediate::isImmediate(asValue()) || asCell()->marked();
237 }
238
239 inline JSValuePtr JSValuePtr::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
240 {
241 return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType);
242 }
243
244 inline bool JSValuePtr::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& value)
245 {
246 if (JSImmediate::isImmediate(asValue())) {
247 number = JSImmediate::toDouble(asValue());
248 value = asValue();
249 return true;
250 }
251 return asCell()->getPrimitiveNumber(exec, number, value);
252 }
253
254 inline bool JSValuePtr::toBoolean(ExecState* exec) const
255 {
256 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec);
257 }
258
259 ALWAYS_INLINE double JSValuePtr::toNumber(ExecState* exec) const
260 {
261 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec);
262 }
263
264 inline UString JSValuePtr::toString(ExecState* exec) const
265 {
266 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec);
267 }
268
269 inline JSObject* JSValuePtr::toObject(ExecState* exec) const
270 {
271 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec);
272 }
273
274 inline JSObject* JSValuePtr::toThisObject(ExecState* exec) const
275 {
276 if (UNLIKELY(JSImmediate::isImmediate(asValue())))
277 return JSImmediate::toThisObject(asValue(), exec);
278 return asCell()->toThisObject(exec);
279 }
280
281 inline bool JSValuePtr::needsThisConversion() const
282 {
283 if (UNLIKELY(JSImmediate::isImmediate(asValue())))
284 return true;
285 return asCell()->structure()->typeInfo().needsThisConversion();
286 }
287
288 inline UString JSValuePtr::toThisString(ExecState* exec) const
289 {
290 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
291 }
292
293 inline JSValuePtr JSValuePtr::getJSNumber()
294 {
295 return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();
296 }
297
298 } // namespace JSC
299
300 #endif // JSCell_h