|
1 // -*- c-basic-offset: 2 -*- |
|
2 /* |
|
3 * This file is part of the KDE libraries |
|
4 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) |
|
5 * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
|
6 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. |
|
7 * |
|
8 * This library is free software; you can redistribute it and/or |
|
9 * modify it under the terms of the GNU Library General Public |
|
10 * License as published by the Free Software Foundation; either |
|
11 * version 2 of the License, or (at your option) any later version. |
|
12 * |
|
13 * This library is distributed in the hope that it will be useful, |
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
16 * Library General Public License for more details. |
|
17 * |
|
18 * You should have received a copy of the GNU Library General Public License |
|
19 * along with this library; see the file COPYING.LIB. If not, write to |
|
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
|
21 * Boston, MA 02110-1301, USA. |
|
22 * |
|
23 */ |
|
24 |
|
25 #ifndef KJS_OBJECT_H |
|
26 #define KJS_OBJECT_H |
|
27 |
|
28 #include "JSType.h" |
|
29 #include "CommonIdentifiers.h" |
|
30 #include "interpreter.h" |
|
31 #include "property_map.h" |
|
32 #include "property_slot.h" |
|
33 #include "scope_chain.h" |
|
34 #include <wtf/AlwaysInline.h> |
|
35 |
|
36 #if PLATFORM(SYMBIAN) |
|
37 #include "collector.h" |
|
38 #endif // PLATFORM(SYMBIAN) |
|
39 |
|
40 namespace KJS { |
|
41 |
|
42 class InternalFunctionImp; |
|
43 class PropertyNameArray; |
|
44 |
|
45 struct HashEntry; |
|
46 struct HashTable; |
|
47 |
|
48 // ECMA 262-3 8.6.1 |
|
49 // Property attributes |
|
50 enum Attribute { None = 0, |
|
51 ReadOnly = 1 << 1, // property can be only read, not written |
|
52 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) |
|
53 DontDelete = 1 << 3, // property can't be deleted |
|
54 Internal = 1 << 4, // an internal property, set to bypass checks |
|
55 Function = 1 << 5, // property is a function - only used by static hashtables |
|
56 GetterSetter = 1 << 6 }; // property is a getter or setter |
|
57 |
|
58 /** |
|
59 * Class Information |
|
60 */ |
|
61 struct ClassInfo { |
|
62 /** |
|
63 * A string denoting the class name. Example: "Window". |
|
64 */ |
|
65 const char* className; |
|
66 /** |
|
67 * Pointer to the class information of the base class. |
|
68 * 0L if there is none. |
|
69 */ |
|
70 const ClassInfo *parentClass; |
|
71 /** |
|
72 * Static hash-table of properties. |
|
73 */ |
|
74 const HashTable *propHashTable; |
|
75 /** |
|
76 * Reserved for future extension. |
|
77 */ |
|
78 void *dummy; |
|
79 }; |
|
80 |
|
81 // This is an internal value object which stores getter and setter functions |
|
82 // for a property. |
|
83 class GetterSetterImp : public JSCell { |
|
84 public: |
|
85 JSType type() const { return GetterSetterType; } |
|
86 |
|
87 GetterSetterImp() : getter(0), setter(0) { } |
|
88 |
|
89 virtual JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const; |
|
90 virtual bool toBoolean(ExecState *exec) const; |
|
91 virtual double toNumber(ExecState *exec) const; |
|
92 virtual UString toString(ExecState *exec) const; |
|
93 virtual JSObject *toObject(ExecState *exec) const; |
|
94 |
|
95 IMPORT virtual void mark(); |
|
96 |
|
97 JSObject *getGetter() { return getter; } |
|
98 void setGetter(JSObject *g) { getter = g; } |
|
99 JSObject *getSetter() { return setter; } |
|
100 void setSetter(JSObject *s) { setter = s; } |
|
101 |
|
102 private: |
|
103 JSObject *getter; |
|
104 JSObject *setter; |
|
105 }; |
|
106 |
|
107 class JSObject : public JSCell { |
|
108 public: |
|
109 /** |
|
110 * Creates a new JSObject with the specified prototype |
|
111 * |
|
112 * @param proto The prototype |
|
113 */ |
|
114 JSObject(JSValue* proto); |
|
115 |
|
116 /** |
|
117 * Creates a new JSObject with a prototype of jsNull() |
|
118 * (that is, the ECMAScript "null" value, not a null object pointer). |
|
119 */ |
|
120 JSObject(); |
|
121 |
|
122 IMPORT virtual void mark(); |
|
123 IMPORT virtual JSType type() const; |
|
124 |
|
125 /** |
|
126 * A pointer to a ClassInfo struct for this class. This provides a basic |
|
127 * facility for run-time type information, and can be used to check an |
|
128 * object's class an inheritance (see inherits()). This should |
|
129 * always return a statically declared pointer, or 0 to indicate that |
|
130 * there is no class information. |
|
131 * |
|
132 * This is primarily useful if you have application-defined classes that you |
|
133 * wish to check against for casting purposes. |
|
134 * |
|
135 * For example, to specify the class info for classes FooImp and BarImp, |
|
136 * where FooImp inherits from BarImp, you would add the following in your |
|
137 * class declarations: |
|
138 * |
|
139 * \code |
|
140 * class BarImp : public JSObject { |
|
141 * virtual const ClassInfo *classInfo() const { return &info; } |
|
142 * static const ClassInfo info; |
|
143 * // ... |
|
144 * }; |
|
145 * |
|
146 * class FooImp : public JSObject { |
|
147 * virtual const ClassInfo *classInfo() const { return &info; } |
|
148 * static const ClassInfo info; |
|
149 * // ... |
|
150 * }; |
|
151 * \endcode |
|
152 * |
|
153 * And in your source file: |
|
154 * |
|
155 * \code |
|
156 * const ClassInfo BarImp::info = {"Bar", 0, 0, 0}; // no parent class |
|
157 * const ClassInfo FooImp::info = {"Foo", &BarImp::info, 0, 0}; |
|
158 * \endcode |
|
159 * |
|
160 * @see inherits() |
|
161 */ |
|
162 IMPORT virtual const ClassInfo *classInfo() const; |
|
163 |
|
164 /** |
|
165 * Checks whether this object inherits from the class with the specified |
|
166 * classInfo() pointer. This requires that both this class and the other |
|
167 * class return a non-NULL pointer for their classInfo() methods (otherwise |
|
168 * it will return false). |
|
169 * |
|
170 * For example, for two JSObject pointers obj1 and obj2, you can check |
|
171 * if obj1's class inherits from obj2's class using the following: |
|
172 * |
|
173 * if (obj1->inherits(obj2->classInfo())) { |
|
174 * // ... |
|
175 * } |
|
176 * |
|
177 * If you have a handle to a statically declared ClassInfo, such as in the |
|
178 * classInfo() example, you can check for inheritance without needing |
|
179 * an instance of the other class: |
|
180 * |
|
181 * if (obj1->inherits(FooImp::info)) { |
|
182 * // ... |
|
183 * } |
|
184 * |
|
185 * @param cinfo The ClassInfo pointer for the class you want to check |
|
186 * inheritance against. |
|
187 * @return true if this object's class inherits from class with the |
|
188 * ClassInfo pointer specified in cinfo |
|
189 */ |
|
190 bool inherits(const ClassInfo *cinfo) const; |
|
191 |
|
192 // internal properties (ECMA 262-3 8.6.2) |
|
193 |
|
194 /** |
|
195 * Returns the prototype of this object. Note that this is not the same as |
|
196 * the "prototype" property. |
|
197 * |
|
198 * See ECMA 8.6.2 |
|
199 * |
|
200 * @return The object's prototype |
|
201 */ |
|
202 JSValue *prototype() const; |
|
203 void setPrototype(JSValue *proto); |
|
204 |
|
205 /** |
|
206 * Returns the class name of the object |
|
207 * |
|
208 * See ECMA 8.6.2 |
|
209 * |
|
210 * @return The object's class name |
|
211 */ |
|
212 /** |
|
213 * Implementation of the [[Class]] internal property (implemented by all |
|
214 * Objects) |
|
215 * |
|
216 * The default implementation uses classInfo(). |
|
217 * You should either implement classInfo(), or |
|
218 * if you simply need a classname, you can reimplement className() |
|
219 * instead. |
|
220 */ |
|
221 IMPORT virtual UString className() const; |
|
222 |
|
223 /** |
|
224 * Retrieves the specified property from the object. If neither the object |
|
225 * or any other object in it's prototype chain have the property, this |
|
226 * function will return Undefined. |
|
227 * |
|
228 * See ECMA 8.6.2.1 |
|
229 * |
|
230 * @param exec The current execution state |
|
231 * @param propertyName The name of the property to retrieve |
|
232 * |
|
233 * @return The specified property, or Undefined |
|
234 */ |
|
235 IMPORT JSValue *get(ExecState *exec, const Identifier &propertyName) const; |
|
236 IMPORT JSValue *get(ExecState *exec, unsigned propertyName) const; |
|
237 |
|
238 bool getPropertySlot(ExecState *, const Identifier&, PropertySlot&); |
|
239 bool getPropertySlot(ExecState *, unsigned, PropertySlot&); |
|
240 |
|
241 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); |
|
242 IMPORT virtual bool getOwnPropertySlot(ExecState *, unsigned index, PropertySlot&); |
|
243 |
|
244 /** |
|
245 * Sets the specified property. |
|
246 * |
|
247 * See ECMA 8.6.2.2 |
|
248 * |
|
249 * @param exec The current execution state |
|
250 * @param propertyName The name of the property to set |
|
251 * @param propertyValue The value to set |
|
252 */ |
|
253 IMPORT virtual void put(ExecState* exec, const Identifier &propertyName, JSValue* value, int attr = None); |
|
254 IMPORT virtual void put(ExecState* exec, unsigned propertyName, JSValue* value, int attr = None); |
|
255 |
|
256 /** |
|
257 * Used to check whether or not a particular property is allowed to be set |
|
258 * on an object |
|
259 * |
|
260 * See ECMA 8.6.2.3 |
|
261 * |
|
262 * @param exec The current execution state |
|
263 * @param propertyName The name of the property |
|
264 * @return true if the property can be set, otherwise false |
|
265 */ |
|
266 /** |
|
267 * Implementation of the [[CanPut]] internal property (implemented by all |
|
268 * Objects) |
|
269 */ |
|
270 IMPORT virtual bool canPut(ExecState *exec, const Identifier &propertyName) const; |
|
271 |
|
272 /** |
|
273 * Checks if a property is enumerable, that is if it doesn't have the DontEnum |
|
274 * flag set |
|
275 * |
|
276 * See ECMA 15.2.4 |
|
277 * @param exec The current execution state |
|
278 * @param propertyName The name of the property |
|
279 * @return true if the property is enumerable, otherwise false |
|
280 */ |
|
281 bool propertyIsEnumerable(ExecState *exec, const Identifier &propertyName) const; |
|
282 |
|
283 /** |
|
284 * Checks to see whether the object (or any object in it's prototype chain) |
|
285 * has a property with the specified name. |
|
286 * |
|
287 * See ECMA 8.6.2.4 |
|
288 * |
|
289 * @param exec The current execution state |
|
290 * @param propertyName The name of the property to check for |
|
291 * @return true if the object has the property, otherwise false |
|
292 */ |
|
293 IMPORT bool hasProperty(ExecState *exec, const Identifier &propertyName) const; |
|
294 bool hasProperty(ExecState *exec, unsigned propertyName) const; |
|
295 |
|
296 /** |
|
297 * Removes the specified property from the object. |
|
298 * |
|
299 * See ECMA 8.6.2.5 |
|
300 * |
|
301 * @param exec The current execution state |
|
302 * @param propertyName The name of the property to delete |
|
303 * @return true if the property was successfully deleted or did not |
|
304 * exist on the object. false if deleting the specified property is not |
|
305 * allowed. |
|
306 */ |
|
307 IMPORT virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); |
|
308 IMPORT virtual bool deleteProperty(ExecState *exec, unsigned propertyName); |
|
309 |
|
310 /** |
|
311 * Converts the object into a primitive value. The value return may differ |
|
312 * depending on the supplied hint |
|
313 * |
|
314 * See ECMA 8.6.2.6 |
|
315 * |
|
316 * @param exec The current execution state |
|
317 * @param hint The desired primitive type to convert to |
|
318 * @return A primitive value converted from the objetc. Note that the |
|
319 * type of primitive value returned may not be the same as the requested |
|
320 * hint. |
|
321 */ |
|
322 /** |
|
323 * Implementation of the [[DefaultValue]] internal property (implemented by |
|
324 * all Objects) |
|
325 */ |
|
326 IMPORT virtual JSValue *defaultValue(ExecState *exec, JSType hint) const; |
|
327 |
|
328 /** |
|
329 * Whether or not the object implements the construct() method. If this |
|
330 * returns false you should not call the construct() method on this |
|
331 * object (typically, an assertion will fail to indicate this). |
|
332 * |
|
333 * @return true if this object implements the construct() method, otherwise |
|
334 * false |
|
335 */ |
|
336 IMPORT virtual bool implementsConstruct() const; |
|
337 |
|
338 /** |
|
339 * Creates a new object based on this object. Typically this means the |
|
340 * following: |
|
341 * 1. A new object is created |
|
342 * 2. The prototype of the new object is set to the value of this object's |
|
343 * "prototype" property |
|
344 * 3. The call() method of this object is called, with the new object |
|
345 * passed as the this value |
|
346 * 4. The new object is returned |
|
347 * |
|
348 * In some cases, Host objects may differ from these semantics, although |
|
349 * this is discouraged. |
|
350 * |
|
351 * If an error occurs during construction, the execution state's exception |
|
352 * will be set. This can be tested for with ExecState::hadException(). |
|
353 * Under some circumstances, the exception object may also be returned. |
|
354 * |
|
355 * Note: This function should not be called if implementsConstruct() returns |
|
356 * false, in which case it will result in an assertion failure. |
|
357 * |
|
358 * @param exec The current execution state |
|
359 * @param args The arguments to be passed to call() once the new object has |
|
360 * been created |
|
361 * @return The newly created & initialized object |
|
362 */ |
|
363 /** |
|
364 * Implementation of the [[Construct]] internal property |
|
365 */ |
|
366 IMPORT virtual JSObject* construct(ExecState* exec, const List& args); |
|
367 IMPORT virtual JSObject* construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber); |
|
368 |
|
369 /** |
|
370 * Whether or not the object implements the call() method. If this returns |
|
371 * false you should not call the call() method on this object (typically, |
|
372 * an assertion will fail to indicate this). |
|
373 * |
|
374 * @return true if this object implements the call() method, otherwise |
|
375 * false |
|
376 */ |
|
377 IMPORT virtual bool implementsCall() const; |
|
378 |
|
379 /** |
|
380 * Calls this object as if it is a function. |
|
381 * |
|
382 * Note: This function should not be called if implementsCall() returns |
|
383 * false, in which case it will result in an assertion failure. |
|
384 * |
|
385 * See ECMA 8.6.2.3 |
|
386 * |
|
387 * @param exec The current execution state |
|
388 * @param thisObj The obj to be used as "this" within function execution. |
|
389 * Note that in most cases this will be different from the C++ "this" |
|
390 * object. For example, if the ECMAScript code "window.location->toString()" |
|
391 * is executed, call() will be invoked on the C++ object which implements |
|
392 * the toString method, with the thisObj being window.location |
|
393 * @param args List of arguments to be passed to the function |
|
394 * @return The return value from the function |
|
395 */ |
|
396 IMPORT JSValue *call(ExecState *exec, JSObject *thisObj, const List &args); |
|
397 IMPORT virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); |
|
398 |
|
399 /** |
|
400 * Whether or not the object implements the hasInstance() method. If this |
|
401 * returns false you should not call the hasInstance() method on this |
|
402 * object (typically, an assertion will fail to indicate this). |
|
403 * |
|
404 * @return true if this object implements the hasInstance() method, |
|
405 * otherwise false |
|
406 */ |
|
407 IMPORT virtual bool implementsHasInstance() const; |
|
408 |
|
409 /** |
|
410 * Checks whether value delegates behavior to this object. Used by the |
|
411 * instanceof operator. |
|
412 * |
|
413 * @param exec The current execution state |
|
414 * @param value The value to check |
|
415 * @return true if value delegates behavior to this object, otherwise |
|
416 * false |
|
417 */ |
|
418 IMPORT virtual bool hasInstance(ExecState *exec, JSValue *value); |
|
419 |
|
420 IMPORT virtual void getPropertyNames(ExecState*, PropertyNameArray&); |
|
421 |
|
422 virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const; |
|
423 IMPORT virtual bool toBoolean(ExecState *exec) const; |
|
424 IMPORT virtual double toNumber(ExecState *exec) const; |
|
425 IMPORT virtual UString toString(ExecState *exec) const; |
|
426 IMPORT virtual JSObject *toObject(ExecState *exec) const; |
|
427 |
|
428 bool getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const; |
|
429 |
|
430 // WebCore uses this to make document.all and style.filter undetectable |
|
431 virtual bool masqueradeAsUndefined() const { return false; } |
|
432 |
|
433 // This get function only looks at the property map. |
|
434 // This is used e.g. by lookupOrCreateFunction (to cache a function, we don't want |
|
435 // to look up in the prototype, it might already exist there) |
|
436 JSValue *getDirect(const Identifier& propertyName) const |
|
437 { return _prop.get(propertyName); } |
|
438 JSValue **getDirectLocation(const Identifier& propertyName) |
|
439 { return _prop.getLocation(propertyName); } |
|
440 IMPORT void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0); |
|
441 IMPORT void putDirect(const Identifier &propertyName, int value, int attr = 0); |
|
442 IMPORT void removeDirect(const Identifier &propertyName); |
|
443 |
|
444 // convenience to add a function property under the function's own built-in name |
|
445 void putDirectFunction(InternalFunctionImp*, int attr = 0); |
|
446 |
|
447 IMPORT void fillGetterPropertySlot(PropertySlot& slot, JSValue **location); |
|
448 |
|
449 void defineGetter(ExecState *exec, const Identifier& propertyName, JSObject *getterFunc); |
|
450 void defineSetter(ExecState *exec, const Identifier& propertyName, JSObject *setterFunc); |
|
451 |
|
452 bool checkStackDepthTooDeep(); |
|
453 |
|
454 /** |
|
455 * Remove all properties from this object. |
|
456 * This doesn't take DontDelete into account, and isn't in the ECMA spec. |
|
457 * It's simply a quick way to remove everything stored in the property map. |
|
458 */ |
|
459 void clearProperties() { _prop.clear(); } |
|
460 |
|
461 void saveProperties(SavedProperties &p) const { _prop.save(p); } |
|
462 void restoreProperties(const SavedProperties &p) { _prop.restore(p); } |
|
463 |
|
464 virtual bool isActivation() { return false; } |
|
465 protected: |
|
466 PropertyMap _prop; |
|
467 private: |
|
468 const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const; |
|
469 JSValue *_proto; |
|
470 }; |
|
471 |
|
472 /** |
|
473 * Types of Native Errors available. For custom errors, GeneralError |
|
474 * should be used. |
|
475 */ |
|
476 enum ErrorType { GeneralError = 0, |
|
477 EvalError = 1, |
|
478 RangeError = 2, |
|
479 ReferenceError = 3, |
|
480 SyntaxError = 4, |
|
481 TypeError = 5, |
|
482 URIError = 6}; |
|
483 |
|
484 /** |
|
485 * @short Factory methods for error objects. |
|
486 */ |
|
487 class Error { |
|
488 public: |
|
489 /** |
|
490 * Factory method for error objects. |
|
491 * |
|
492 * @param exec The current execution state |
|
493 * @param errtype Type of error. |
|
494 * @param message Optional error message. |
|
495 * @param lineNumber Optional line number. |
|
496 * @param sourceId Optional source id. |
|
497 * @param sourceURL Optional source URL. |
|
498 */ |
|
499 static JSObject *create(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL); |
|
500 static JSObject *create(ExecState *, ErrorType, const char *message); |
|
501 |
|
502 /** |
|
503 * Array of error names corresponding to ErrorType |
|
504 */ |
|
505 static const char * const * const errorNames; |
|
506 }; |
|
507 |
|
508 JSObject *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL); |
|
509 IMPORT JSObject *throwError(ExecState *, ErrorType, const UString &message); |
|
510 IMPORT JSObject *throwError(ExecState *, ErrorType, const char *message); |
|
511 IMPORT JSObject *throwError(ExecState *, ErrorType); |
|
512 |
|
513 inline JSObject::JSObject(JSValue* proto) |
|
514 : _proto(proto) |
|
515 { |
|
516 assert(proto); |
|
517 } |
|
518 |
|
519 inline JSObject::JSObject() |
|
520 : _proto(jsNull()) |
|
521 { |
|
522 } |
|
523 |
|
524 inline JSValue *JSObject::prototype() const |
|
525 { |
|
526 return _proto; |
|
527 } |
|
528 |
|
529 inline void JSObject::setPrototype(JSValue *proto) |
|
530 { |
|
531 assert(proto); |
|
532 _proto = proto; |
|
533 } |
|
534 |
|
535 inline bool JSObject::inherits(const ClassInfo *info) const |
|
536 { |
|
537 for (const ClassInfo *ci = classInfo(); ci; ci = ci->parentClass) |
|
538 if (ci == info) |
|
539 return true; |
|
540 return false; |
|
541 } |
|
542 |
|
543 // this method is here to be after the inline declaration of JSObject::inherits |
|
544 inline bool JSCell::isObject(const ClassInfo *info) const |
|
545 { |
|
546 return isObject() && static_cast<const JSObject *>(this)->inherits(info); |
|
547 } |
|
548 |
|
549 // this method is here to be after the inline declaration of JSCell::isObject |
|
550 inline bool JSValue::isObject(const ClassInfo *c) const |
|
551 { |
|
552 return !JSImmediate::isImmediate(this) && asCell()->isObject(c); |
|
553 } |
|
554 |
|
555 // It may seem crazy to inline a function this large but it makes a big difference |
|
556 // since this is function very hot in variable lookup |
|
557 inline bool JSObject::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) |
|
558 { |
|
559 JSObject *object = this; |
|
560 while (true) { |
|
561 if (object->getOwnPropertySlot(exec, propertyName, slot)) |
|
562 return true; |
|
563 |
|
564 JSValue *proto = object->_proto; |
|
565 if (!proto->isObject()) |
|
566 return false; |
|
567 |
|
568 object = static_cast<JSObject *>(proto); |
|
569 } |
|
570 } |
|
571 |
|
572 // It may seem crazy to inline a function this large, especially a virtual function, |
|
573 // but it makes a big difference to property lookup that derived classes can inline their |
|
574 // base class call to this. |
|
575 ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) |
|
576 { |
|
577 if (JSValue **location = getDirectLocation(propertyName)) { |
|
578 if (_prop.hasGetterSetterProperties() && location[0]->type() == GetterSetterType) |
|
579 fillGetterPropertySlot(slot, location); |
|
580 else |
|
581 slot.setValueSlot(this, location); |
|
582 return true; |
|
583 } |
|
584 |
|
585 // non-standard Netscape extension |
|
586 if (propertyName == exec->propertyNames().underscoreProto) { |
|
587 slot.setValueSlot(this, &_proto); |
|
588 return true; |
|
589 } |
|
590 |
|
591 return false; |
|
592 } |
|
593 |
|
594 |
|
595 inline bool JSObject::checkStackDepthTooDeep() |
|
596 { |
|
597 #if PLATFORM(SYMBIAN) |
|
598 unsigned int approxSPvar; // keep this as first item in func so it's allocated at approx SP location |
|
599 void * sp = &approxSPvar; |
|
600 if((unsigned int)sp < Collector::CallStackGrowthThresh) |
|
601 { |
|
602 Collector::recursivelyOrphanedMarkTops.append(this); |
|
603 return true; |
|
604 } |
|
605 else |
|
606 { |
|
607 return false; |
|
608 } |
|
609 #else |
|
610 return false; |
|
611 #endif // PLATFORM(SYMBIAN) |
|
612 } |
|
613 |
|
614 // FIXME: Put this function in a separate file named something like scope_chain_mark.h -- can't put it in scope_chain.h since it depends on JSObject. |
|
615 |
|
616 inline void ScopeChain::mark() |
|
617 { |
|
618 for (ScopeChainNode *n = _node; n; n = n->next) { |
|
619 JSObject *o = n->object; |
|
620 if (!o->marked()) |
|
621 o->mark(); |
|
622 } |
|
623 } |
|
624 |
|
625 inline void ScopeChain::release() |
|
626 { |
|
627 // This function is only called by deref(), |
|
628 // Deref ensures these conditions are true. |
|
629 assert(_node && _node->refCount == 0); |
|
630 ScopeChainNode *n = _node; |
|
631 do { |
|
632 ScopeChainNode *next = n->next; |
|
633 delete n; |
|
634 n = next; |
|
635 } while (n && --n->refCount == 0); |
|
636 } |
|
637 |
|
638 inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const |
|
639 { |
|
640 return defaultValue(exec, preferredType); |
|
641 } |
|
642 |
|
643 } // namespace |
|
644 |
|
645 #endif // KJS_OBJECT_H |