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

source code of qtscript/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h