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