source: webkit/trunk/JavaScriptCore/runtime/JSCell.h@ 50320

Last change on this file since 50320 was 49955, checked in by [email protected], 16 years ago

Fixed ASSERT when opening Safari's Caches window while the Web Inspector
is open.

Patch by Geoffrey Garen <[email protected]> on 2009-10-22
Reviewed by Alexey Proskuryakov.

  • runtime/Collector.cpp:

(JSC::typeName): Added two new types to the type name list in the Collector.
These types have been around for a while, but nobody remembered to consider them here.

  • runtime/JSCell.h:

(JSC::JSCell::isPropertyNameIterator):

  • runtime/JSPropertyNameIterator.h:

(JSC::JSPropertyNameIterator::isPropertyNameIterator): Give the Collector
a way to tell if a cell is a JSPropertyNameIterator.

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
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 "Collector.h"
27#include "JSImmediate.h"
28#include "JSValue.h"
29#include "MarkStack.h"
30#include "Structure.h"
31#include <wtf/Noncopyable.h>
32
33namespace JSC {
34
35 class JSCell : public NoncopyableCustomAllocated {
36 friend class GetterSetter;
37 friend class Heap;
38 friend class JIT;
39 friend class JSNumberCell;
40 friend class JSObject;
41 friend class JSPropertyNameIterator;
42 friend class JSString;
43 friend class JSValue;
44 friend class JSAPIValueWrapper;
45 friend struct VPtrSet;
46
47 private:
48 explicit JSCell(Structure*);
49 JSCell(); // Only used for initializing Collector blocks.
50 virtual ~JSCell();
51
52 public:
53 // Querying the type.
54#if USE(JSVALUE32)
55 bool isNumber() const;
56#endif
57 bool isString() const;
58 bool isObject() const;
59 virtual bool isGetterSetter() const;
60 bool inherits(const ClassInfo*) const;
61 virtual bool isAPIValueWrapper() const { return false; }
62 virtual bool isPropertyNameIterator() const { return false; }
63
64 Structure* structure() const;
65
66 // Extracting the value.
67 bool getString(UString&) const;
68 UString getString() const; // null string if not a string
69 JSObject* getObject(); // NULL if not an object
70 const JSObject* getObject() const; // NULL if not an object
71
72 virtual CallType getCallData(CallData&);
73 virtual ConstructType getConstructData(ConstructData&);
74
75 // Extracting integer values.
76 // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*.
77 virtual bool getUInt32(uint32_t&) const;
78
79 // Basic conversions.
80 virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
81 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
82 virtual bool toBoolean(ExecState*) const;
83 virtual double toNumber(ExecState*) const;
84 virtual UString toString(ExecState*) const;
85 virtual JSObject* toObject(ExecState*) const;
86
87 // Garbage collection.
88 void* operator new(size_t, ExecState*);
89 void* operator new(size_t, JSGlobalData*);
90 void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
91
92 virtual void markChildren(MarkStack&);
93
94 // Object operations, with the toObject operation included.
95 virtual const ClassInfo* classInfo() const;
96 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
97 virtual void put(ExecState*, unsigned propertyName, JSValue);
98 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
99 virtual bool deleteProperty(ExecState*, unsigned propertyName);
100
101 virtual JSObject* toThisObject(ExecState*) const;
102 virtual UString toThisString(ExecState*) const;
103 virtual JSString* toThisJSString(ExecState*);
104 virtual JSValue getJSNumber();
105 void* vptr() { return *reinterpret_cast<void**>(this); }
106
107 private:
108 // Base implementation; for non-object classes implements getPropertySlot.
109 bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
110 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
111 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
112
113 Structure* m_structure;
114 };
115
116 inline JSCell::JSCell(Structure* structure)
117 : m_structure(structure)
118 {
119 }
120
121 // Only used for initializing Collector blocks.
122 inline JSCell::JSCell()
123 {
124 }
125
126 inline JSCell::~JSCell()
127 {
128 }
129
130#if USE(JSVALUE32)
131 inline bool JSCell::isNumber() const
132 {
133 return Heap::isNumber(const_cast<JSCell*>(this));
134 }
135#endif
136
137 inline bool JSCell::isObject() const
138 {
139 return m_structure->typeInfo().type() == ObjectType;
140 }
141
142 inline bool JSCell::isString() const
143 {
144 return m_structure->typeInfo().type() == StringType;
145 }
146
147 inline Structure* JSCell::structure() const
148 {
149 return m_structure;
150 }
151
152 inline void JSCell::markChildren(MarkStack&)
153 {
154 }
155
156 inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
157 {
158 return globalData->heap.allocate(size);
159 }
160
161 // --- JSValue inlines ----------------------------
162
163 inline bool JSValue::isString() const
164 {
165 return isCell() && asCell()->isString();
166 }
167
168 inline bool JSValue::isGetterSetter() const
169 {
170 return isCell() && asCell()->isGetterSetter();
171 }
172
173 inline bool JSValue::isObject() const
174 {
175 return isCell() && asCell()->isObject();
176 }
177
178 inline bool JSValue::getString(UString& s) const
179 {
180 return isCell() && asCell()->getString(s);
181 }
182
183 inline UString JSValue::getString() const
184 {
185 return isCell() ? asCell()->getString() : UString();
186 }
187
188 inline JSObject* JSValue::getObject() const
189 {
190 return isCell() ? asCell()->getObject() : 0;
191 }
192
193 inline CallType JSValue::getCallData(CallData& callData)
194 {
195 return isCell() ? asCell()->getCallData(callData) : CallTypeNone;
196 }
197
198 inline ConstructType JSValue::getConstructData(ConstructData& constructData)
199 {
200 return isCell() ? asCell()->getConstructData(constructData) : ConstructTypeNone;
201 }
202
203 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
204 {
205 if (isInt32()) {
206 int32_t i = asInt32();
207 v = static_cast<uint32_t>(i);
208 return i >= 0;
209 }
210 if (isDouble()) {
211 double d = asDouble();
212 v = static_cast<uint32_t>(d);
213 return v == d;
214 }
215 return false;
216 }
217
218#if !USE(JSVALUE32_64)
219 ALWAYS_INLINE JSCell* JSValue::asCell() const
220 {
221 ASSERT(isCell());
222 return m_ptr;
223 }
224#endif // !USE(JSVALUE32_64)
225
226 inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
227 {
228 return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
229 }
230
231 inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
232 {
233 if (isInt32()) {
234 number = asInt32();
235 value = *this;
236 return true;
237 }
238 if (isDouble()) {
239 number = asDouble();
240 value = *this;
241 return true;
242 }
243 if (isCell())
244 return asCell()->getPrimitiveNumber(exec, number, value);
245 if (isTrue()) {
246 number = 1.0;
247 value = *this;
248 return true;
249 }
250 if (isFalse() || isNull()) {
251 number = 0.0;
252 value = *this;
253 return true;
254 }
255 ASSERT(isUndefined());
256 number = nonInlineNaN();
257 value = *this;
258 return true;
259 }
260
261 inline bool JSValue::toBoolean(ExecState* exec) const
262 {
263 if (isInt32())
264 return asInt32() != 0;
265 if (isDouble())
266 return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
267 if (isCell())
268 return asCell()->toBoolean(exec);
269 return isTrue(); // false, null, and undefined all convert to false.
270 }
271
272 ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
273 {
274 if (isInt32())
275 return asInt32();
276 if (isDouble())
277 return asDouble();
278 if (isCell())
279 return asCell()->toNumber(exec);
280 if (isTrue())
281 return 1.0;
282 return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
283 }
284
285 inline bool JSValue::needsThisConversion() const
286 {
287 if (UNLIKELY(!isCell()))
288 return true;
289 return asCell()->structure()->typeInfo().needsThisConversion();
290 }
291
292 inline UString JSValue::toThisString(ExecState* exec) const
293 {
294 return isCell() ? asCell()->toThisString(exec) : toString(exec);
295 }
296
297 inline JSValue JSValue::getJSNumber()
298 {
299 if (isInt32() || isDouble())
300 return *this;
301 if (isCell())
302 return asCell()->getJSNumber();
303 return JSValue();
304 }
305
306 inline JSObject* JSValue::toObject(ExecState* exec) const
307 {
308 return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec);
309 }
310
311 inline JSObject* JSValue::toThisObject(ExecState* exec) const
312 {
313 return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
314 }
315
316 ALWAYS_INLINE void MarkStack::append(JSCell* cell)
317 {
318 ASSERT(!m_isCheckingForDefaultMarkViolation);
319 ASSERT(cell);
320 if (Heap::isCellMarked(cell))
321 return;
322 Heap::markCell(cell);
323 if (cell->structure()->typeInfo().type() >= CompoundType)
324 m_values.append(cell);
325 }
326
327 ALWAYS_INLINE void MarkStack::append(JSValue value)
328 {
329 ASSERT(value);
330 if (value.isCell())
331 append(value.asCell());
332 }
333
334 inline Heap* Heap::heap(JSValue v)
335 {
336 if (!v.isCell())
337 return 0;
338 return heap(v.asCell());
339 }
340
341 inline Heap* Heap::heap(JSCell* c)
342 {
343 return cellBlock(c)->heap;
344 }
345
346} // namespace JSC
347
348#endif // JSCell_h
Note: See TracBrowser for help on using the repository browser.