File indexing completed on 2024-05-12 15:43:31

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
0004  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
0005  *  Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
0006  *
0007  *  This library is free software; you can redistribute it and/or
0008  *  modify it under the terms of the GNU Library General Public
0009  *  License as published by the Free Software Foundation; either
0010  *  version 2 of the License, or (at your option) any later version.
0011  *
0012  *  This library is distributed in the hope that it will be useful,
0013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  *  Library General Public License for more details.
0016  *
0017  *  You should have received a copy of the GNU Library General Public License
0018  *  along with this library; see the file COPYING.LIB.  If not, write to
0019  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  *  Boston, MA 02110-1301, USA.
0021  *
0022  */
0023 
0024 #ifndef KJS_OBJECT_H
0025 #define KJS_OBJECT_H
0026 
0027 #include "global.h"
0028 #include "JSType.h"
0029 #include "interpreter.h"
0030 #include "property_map.h"
0031 #include "property_slot.h"
0032 #include "scope_chain.h"
0033 #include <wtf/AlwaysInline.h>
0034 #include "propertydescriptor.h"
0035 
0036 namespace KJS
0037 {
0038 
0039 struct HashTable;
0040 struct HashEntry;
0041 struct ListImp;
0042 class InternalFunctionImp;
0043 class PropertyNameArray;
0044 
0045 /**
0046  * Class Information
0047  */
0048 struct ClassInfo {
0049     /**
0050      * A string denoting the class name. Example: "Window".
0051      */
0052     const char *className;
0053     /**
0054      * Pointer to the class information of the base class.
0055      * 0L if there is none.
0056      */
0057     const ClassInfo *parentClass;
0058     /**
0059      * Static hash-table of properties.
0060      */
0061     const HashTable *propHashTable;
0062     /**
0063      * Reserved for future extension.
0064      */
0065     void *dummy;
0066 };
0067 
0068 // This is an internal value object which stores getter and setter functions
0069 // for a property.
0070 class GetterSetterImp : public JSCell
0071 {
0072 public:
0073     JSType type() const override
0074     {
0075         return GetterSetterType;
0076     }
0077 
0078     GetterSetterImp() : getter(nullptr), setter(nullptr) { }
0079 
0080     JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const override;
0081     bool getPrimitiveNumber(ExecState *, double &number, JSValue *&value) override;
0082     bool toBoolean(ExecState *exec) const override;
0083     double toNumber(ExecState *exec) const override;
0084     UString toString(ExecState *exec) const override;
0085     JSObject *toObject(ExecState *exec) const override;
0086 
0087     void mark() override;
0088 
0089     JSObject *getGetter()
0090     {
0091         return getter;
0092     }
0093     void setGetter(JSObject *g)
0094     {
0095         getter = g;
0096     }
0097     JSObject *getSetter()
0098     {
0099         return setter;
0100     }
0101     void setSetter(JSObject *s)
0102     {
0103         setter = s;
0104     }
0105 
0106 private:
0107     JSObject *getter;
0108     JSObject *setter;
0109 };
0110 
0111 class KJS_EXPORT JSObject : public JSCell
0112 {
0113 public:
0114     /**
0115      * Creates a new JSObject with the specified prototype
0116      *
0117      * @param proto The prototype
0118      */
0119     explicit JSObject(JSValue *proto);
0120 
0121     /**
0122      * Creates a new JSObject with a prototype of jsNull()
0123      * (that is, the ECMAScript "null" value, not a null object pointer).
0124      */
0125     explicit JSObject();
0126 
0127     void mark() override;
0128     JSType type() const override;
0129 
0130     /**
0131      * A pointer to a ClassInfo struct for this class. This provides a basic
0132      * facility for run-time type information, and can be used to check an
0133      * object's class an inheritance (see inherits()). This should
0134      * always return a statically declared pointer, or 0 to indicate that
0135      * there is no class information.
0136      *
0137      * This is primarily useful if you have application-defined classes that you
0138      * wish to check against for casting purposes.
0139      *
0140      * For example, to specify the class info for classes FooImp and BarImp,
0141      * where FooImp inherits from BarImp, you would add the following in your
0142      * class declarations:
0143      *
0144      * \code
0145      *   class BarImp : public JSObject {
0146      *     virtual const ClassInfo *classInfo() const { return &info; }
0147      *     static const ClassInfo info;
0148      *     // ...
0149      *   };
0150      *
0151      *   class FooImp : public JSObject {
0152      *     virtual const ClassInfo *classInfo() const { return &info; }
0153      *     static const ClassInfo info;
0154      *     // ...
0155      *   };
0156      * \endcode
0157      *
0158      * And in your source file:
0159      *
0160      * \code
0161      *   const ClassInfo BarImp::info = {"Bar", 0, 0, 0}; // no parent class
0162      *   const ClassInfo FooImp::info = {"Foo", &BarImp::info, 0, 0};
0163      * \endcode
0164      *
0165      * @see inherits()
0166      */
0167     virtual const ClassInfo *classInfo() const;
0168 
0169     /**
0170      * Checks whether this object inherits from the class with the specified
0171      * classInfo() pointer. This requires that both this class and the other
0172      * class return a non-NULL pointer for their classInfo() methods (otherwise
0173      * it will return false).
0174      *
0175      * For example, for two JSObject pointers obj1 and obj2, you can check
0176      * if obj1's class inherits from obj2's class using the following:
0177      *
0178      *   if (obj1->inherits(obj2->classInfo())) {
0179      *     // ...
0180      *   }
0181      *
0182      * If you have a handle to a statically declared ClassInfo, such as in the
0183      * classInfo() example, you can check for inheritance without needing
0184      * an instance of the other class:
0185      *
0186      *   if (obj1->inherits(FooImp::info)) {
0187      *     // ...
0188      *   }
0189      *
0190      * @param cinfo The ClassInfo pointer for the class you want to check
0191      * inheritance against.
0192      * @return true if this object's class inherits from class with the
0193      * ClassInfo pointer specified in cinfo
0194      */
0195     bool inherits(const ClassInfo *cinfo) const;
0196 
0197     // internal properties (ECMA 262-3 8.6.2)
0198 
0199     /**
0200      * Returns the prototype of this object. Note that this is not the same as
0201      * the "prototype" property.
0202      *
0203      * See ECMA 8.6.2
0204      *
0205      * @return The object's prototype
0206      */
0207     JSValue *prototype() const;
0208     void setPrototype(JSValue *proto);
0209 
0210     /**
0211      * Returns the class name of the object
0212      *
0213      * See ECMA 8.6.2
0214      *
0215      * @return The object's class name
0216      */
0217     /**
0218      * Implementation of the [[Class]] internal property (implemented by all
0219      * Objects)
0220      *
0221      * The default implementation uses classInfo().
0222      * You should either implement classInfo(), or
0223      * if you simply need a classname, you can reimplement className()
0224      * instead.
0225      */
0226     virtual UString className() const;
0227 
0228     /**
0229      * Retrieves the specified property from the object. If neither the object
0230      * or any other object in its prototype chain have the property, this
0231      * function will return Undefined.
0232      *
0233      * See ECMA 8.6.2.1
0234      *
0235      * @param exec The current execution state
0236      * @param propertyName The name of the property to retrieve
0237      *
0238      * @return The specified property, or Undefined
0239      */
0240     JSValue *get(ExecState *exec, const Identifier &propertyName) const;
0241     JSValue *get(ExecState *exec, unsigned propertyName) const;
0242 
0243     bool getPropertySlot(ExecState *, const Identifier &, PropertySlot &);
0244     bool getPropertySlot(ExecState *, unsigned, PropertySlot &);
0245     // Fills the PropertyDescriptor looking the ownPropertys and all prototypes until found.
0246     bool getPropertyDescriptor(ExecState *, const Identifier &propertyName, PropertyDescriptor &);
0247 
0248     virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot &);
0249     virtual bool getOwnPropertySlot(ExecState *, unsigned index, PropertySlot &);
0250     virtual bool getOwnPropertyDescriptor(ExecState *, const Identifier &, PropertyDescriptor &);
0251 
0252     /**
0253      * Sets the specified property.
0254      *
0255      * See ECMA 8.6.2.2
0256      *
0257      * @param exec The current execution state
0258      * @param propertyName The name of the property to set
0259      * @param value The value to set
0260      * @param attr The attributes of the property
0261      */
0262     virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
0263     virtual void put(ExecState *exec, unsigned propertyName, JSValue *value, int attr = None);
0264 
0265     /**
0266      * Used to check whether or not a particular property is allowed to be set
0267      * on an object
0268      *
0269      * See ECMA 8.6.2.3
0270      *
0271      * @param exec The current execution state
0272      * @param propertyName The name of the property
0273      * @return true if the property can be set, otherwise false
0274      */
0275     /**
0276      * Implementation of the [[CanPut]] internal property (implemented by all
0277      * Objects)
0278      */
0279     virtual bool canPut(ExecState *exec, const Identifier &propertyName) const;
0280 
0281     /**
0282      * Checks if a property is enumerable, that is if it doesn't have the DontEnum
0283      * flag set
0284      *
0285      * See ECMA 15.2.4
0286      * @param exec The current execution state
0287      * @param propertyName The name of the property
0288      * @return true if the property is enumerable, otherwise false
0289      */
0290     bool propertyIsEnumerable(ExecState *exec, const Identifier &propertyName) const;
0291 
0292     /**
0293      * Checks to see whether the object (or any object in its prototype chain)
0294      * has a property with the specified name.
0295      *
0296      * See ECMA 8.6.2.4
0297      *
0298      * @param exec The current execution state
0299      * @param propertyName The name of the property to check for
0300      * @return true if the object has the property, otherwise false
0301      */
0302     bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
0303     bool hasProperty(ExecState *exec, unsigned propertyName) const;
0304 
0305     /**
0306      * Removes the specified property from the object.
0307      *
0308      * See ECMA 8.6.2.5
0309      *
0310      * @param exec The current execution state
0311      * @param propertyName The name of the property to delete
0312      * @return true if the property was successfully deleted or did not
0313      * exist on the object. false if deleting the specified property is not
0314      * allowed.
0315      */
0316     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
0317     virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
0318 
0319     /**
0320      * Converts the object into a primitive value. The value return may differ
0321      * depending on the supplied hint
0322      *
0323      * See ECMA 8.6.2.6
0324      *
0325      * @param exec The current execution state
0326      * @param hint The desired primitive type to convert to
0327      * @return A primitive value converted from the object. Note that the
0328      * type of primitive value returned may not be the same as the requested
0329      * hint.
0330      */
0331     /**
0332      * Implementation of the [[DefaultValue]] internal property (implemented by
0333      * all Objects)
0334      */
0335     virtual JSValue *defaultValue(ExecState *exec, JSType hint) const;
0336 
0337     /**
0338      * Whether or not the object implements the construct() method. If this
0339      * returns false you should not call the construct() method on this
0340      * object (typically, an assertion will fail to indicate this).
0341      *
0342      * @return true if this object implements the construct() method, otherwise
0343      * false
0344      */
0345     virtual bool implementsConstruct() const;
0346 
0347     /**
0348      * Creates a new object based on this object. Typically this means the
0349      * following:
0350      * 1. A new object is created
0351      * 2. The prototype of the new object is set to the value of this object's
0352      *    "prototype" property
0353      * 3. The call() method of this object is called, with the new object
0354      *    passed as the this value
0355      * 4. The new object is returned
0356      *
0357      * In some cases, Host objects may differ from these semantics, although
0358      * this is discouraged.
0359      *
0360      * If an error occurs during construction, the execution state's exception
0361      * will be set. This can be tested for with ExecState::hadException().
0362      * Under some circumstances, the exception object may also be returned.
0363      *
0364      * Note: This function should not be called if implementsConstruct() returns
0365      * false, in which case it will result in an assertion failure.
0366      *
0367      * @param exec The current execution state
0368      * @param args The arguments to be passed to call() once the new object has
0369      * been created
0370      * @return The newly created &amp; initialized object
0371      */
0372     /**
0373      * Implementation of the [[Construct]] internal property
0374      */
0375     virtual JSObject *construct(ExecState *exec, const List &args);
0376     virtual JSObject *construct(ExecState *exec, const List &args, const Identifier &functionName, const UString &sourceURL, int lineNumber);
0377 
0378     /**
0379      * If this object represents a value, e.g. is a wrapper around a primitive,
0380      * a regexp or a date this will return a fresh object with the same value
0381      * (without cloning properties). Otherwise, returns 0
0382      *
0383      * The returned objects will use default prototypes from targetCtx
0384      */
0385     virtual JSObject *valueClone(Interpreter *targetCtx) const;
0386 
0387     /**
0388      * Whether or not this object should be considered a function for the purpose
0389      * of the typeof operator. Normally this is the same as implementsCall(),
0390      * which is what the default implementation delegates too,
0391      * but in some cases compatibility dictates that the object both be callable
0392      * and call itself an object and not a function. In this case, this method should
0393      * be overridden as well
0394     */
0395     virtual bool isFunctionType() const;
0396 
0397     /**
0398      * Calls this object as if it is a function.
0399      *
0400      * Note: This function should not be called if implementsCall() returns
0401      * false, in which case it will result in an assertion failure.
0402      *
0403      * See ECMA 8.6.2.3
0404      *
0405      * @param exec The current execution state
0406      * @param thisObj The obj to be used as "this" within function execution.
0407      * Note that in most cases this will be different from the C++ "this"
0408      * object. For example, if the ECMAScript code "window.location->toString()"
0409      * is executed, call() will be invoked on the C++ object which implements
0410      * the toString method, with the thisObj being window.location
0411      * @param args List of arguments to be passed to the function
0412      * @return The return value from the function
0413      */
0414     JSValue *call(ExecState *exec, JSObject *thisObj, const List &args); // ### TODO: consolidate with below
0415     virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
0416 
0417     /**
0418      * Whether or not the object implements the hasInstance() method. If this
0419      * returns false you should not call the hasInstance() method on this
0420      * object (typically, an assertion will fail to indicate this).
0421      *
0422      * @return true if this object implements the hasInstance() method,
0423      * otherwise false
0424      */
0425     virtual bool implementsHasInstance() const;
0426 
0427     /**
0428      * Checks whether value delegates behavior to this object. Used by the
0429      * instanceof operator.
0430      *
0431      * @param exec The current execution state
0432      * @param value The value to check
0433      * @return true if value delegates behavior to this object, otherwise
0434      * false
0435      */
0436     virtual bool hasInstance(ExecState *exec, JSValue *value);
0437 
0438     void getPropertyNames(ExecState *, PropertyNameArray &, PropertyMap::PropertyMode mode = PropertyMap::ExcludeDontEnumProperties);
0439     virtual void getOwnPropertyNames(ExecState *, PropertyNameArray &, PropertyMap::PropertyMode mode);
0440 
0441     JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const override;
0442     bool getPrimitiveNumber(ExecState *, double &number, JSValue *&value) override;
0443     bool toBoolean(ExecState *exec) const override;
0444     double toNumber(ExecState *exec) const override;
0445     UString toString(ExecState *exec) const override;
0446     JSObject *toObject(ExecState *exec) const override;
0447 
0448     virtual bool getPropertyAttributes(const Identifier &propertyName, unsigned &attributes) const;
0449 
0450     // Returns whether the object should be treated as undefined when doing equality comparisons
0451     virtual bool masqueradeAsUndefined() const
0452     {
0453         return false;
0454     }
0455 
0456     // This get function only looks at the property map for Object.
0457     // It is virtual because for all custom-data classes we want to by-pass
0458     // the prototype and get it directly. For example called from
0459     // Object::defineOwnProperty to directly get GetterSetterImp and update it.
0460     // This is used e.g. by lookupOrCreateFunction (to cache a function, we don't want
0461     // to look up in the prototype, it might already exist there)
0462     virtual JSValue *getDirect(const Identifier &propertyName) const
0463     {
0464         return _prop.get(propertyName);
0465     }
0466     JSValue **getDirectLocation(const Identifier &propertyName)
0467     {
0468         return _prop.getLocation(propertyName);
0469     }
0470 
0471     // If this method returns non-0, there is already a property
0472     // with name propertyName that's not readonly and not a setter-getter
0473     // which can be updated via the returned pointer.
0474     JSValue **getDirectWriteLocation(const Identifier &propertyName)
0475     {
0476         return _prop.getWriteLocation(propertyName);
0477     }
0478 
0479     // This function is virtual to directly store, by-pass the prototype, values
0480     // for all custom-data classes like the Array. For example an Array with a prototype
0481     // to store values via getter/setter. It would be impossible to store a value
0482     // by-passing the getter/setter prototype.
0483     // This is for example called in Object::defineOwnProperty to directly store the values.
0484     // Same for removeDirect.
0485     virtual void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0)
0486     {
0487         _prop.put(propertyName, value, attr);
0488     }
0489     virtual void putDirect(const Identifier &propertyName, int value, int attr = 0);
0490     virtual void removeDirect(const Identifier &propertyName);
0491 
0492     // convenience to add a function property under the function's own built-in name
0493     void putDirectFunction(InternalFunctionImp *, int attr = 0);
0494 
0495     void fillGetterPropertySlot(PropertySlot &slot, JSValue **location);
0496     void fillDirectLocationSlot(PropertySlot &slot, JSValue **location);
0497 
0498     void defineGetter(ExecState *exec, const Identifier &propertyName, JSObject *getterFunc);
0499     void defineSetter(ExecState *exec, const Identifier &propertyName, JSObject *setterFunc);
0500 
0501     virtual bool defineOwnProperty(ExecState *exec, const Identifier &propertyName, PropertyDescriptor &desc, bool shouldThrow);
0502 
0503     void preventExtensions();
0504     bool isExtensible()
0505     {
0506         return _prop.isExtensible();
0507     }
0508 
0509     /**
0510      * Remove all properties from this object.
0511      * This doesn't take DontDelete into account, and isn't in the ECMA spec.
0512      * It's simply a quick way to remove everything stored in the property map.
0513      */
0514     void clearProperties()
0515     {
0516         _prop.clear();
0517     }
0518 
0519     void saveProperties(SavedProperties &p) const
0520     {
0521         _prop.save(p);
0522     }
0523     void restoreProperties(const SavedProperties &p)
0524     {
0525         _prop.restore(p);
0526     }
0527 
0528     virtual bool isActivation()   const
0529     {
0530         return false;
0531     }
0532     virtual bool isGlobalObject() const
0533     {
0534         return false;
0535     }
0536 
0537     // This is used to keep track of whether scope object have local
0538     // variables introduced by something other than 'var'
0539     bool isLocalInjected()  const
0540     {
0541         return _prop.m_objLocalInjected;
0542     }
0543     void setLocalInjected()
0544     {
0545         _prop.m_objLocalInjected = true;
0546     }
0547 
0548 protected:
0549     PropertyMap _prop;
0550 private:
0551 
0552     const HashEntry *findPropertyHashEntry(const Identifier &propertyName) const;
0553     JSValue *_proto;
0554 #ifdef _WIN32
0555     JSObject(const JSObject &);
0556     JSObject &operator=(const JSObject &);
0557 #endif
0558 };
0559 
0560 /**
0561  * Types of Native Errors available. For custom errors, GeneralError
0562  * should be used.
0563  */
0564 enum ErrorType { GeneralError   = 0,
0565                  EvalError      = 1,
0566                  RangeError     = 2,
0567                  ReferenceError = 3,
0568                  SyntaxError    = 4,
0569                  TypeError      = 5,
0570                  URIError       = 6
0571                };
0572 
0573 /**
0574  * @short Factory methods for error objects.
0575  */
0576 class KJS_EXPORT Error
0577 {
0578 public:
0579     /**
0580      * Factory method for error objects.
0581      *
0582      * @param exec The current execution state
0583      * @param errtype Type of error.
0584      * @param message Optional error message.
0585      * @param lineNumber Optional line number.
0586      * @param sourceId Optional source id.
0587      * @param sourceURL Optional source URL.
0588      */
0589     static JSObject *create(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL);
0590     static JSObject *create(ExecState *, ErrorType, const char *message);
0591 
0592     /**
0593      * Array of error names corresponding to ErrorType
0594      */
0595     static const char *const *const errorNames;
0596 };
0597 
0598 KJS_EXPORT JSObject *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL);
0599 KJS_EXPORT JSObject *throwError(ExecState *, ErrorType, const UString &message);
0600 KJS_EXPORT JSObject *throwError(ExecState *, ErrorType, const char *message);
0601 KJS_EXPORT JSObject *throwError(ExecState *, ErrorType);
0602 
0603 inline JSObject::JSObject(JSValue *proto)
0604     : _proto(proto)
0605 {
0606     assert(proto);
0607 }
0608 
0609 inline JSObject::JSObject()
0610     : _proto(jsNull())
0611 {}
0612 
0613 inline JSValue *JSObject::prototype() const
0614 {
0615     return _proto;
0616 }
0617 
0618 inline void JSObject::setPrototype(JSValue *proto)
0619 {
0620     assert(proto);
0621     _proto = proto;
0622 }
0623 
0624 inline bool JSObject::inherits(const ClassInfo *info) const
0625 {
0626     for (const ClassInfo *ci = classInfo(); ci; ci = ci->parentClass)
0627         if (ci == info) {
0628             return true;
0629         }
0630     return false;
0631 }
0632 
0633 inline void JSObject::fillDirectLocationSlot(PropertySlot &slot,
0634         JSValue **location)
0635 {
0636     if (_prop.hasGetterSetterProperties() &&
0637             JSValue::type(*location) == GetterSetterType) {
0638         fillGetterPropertySlot(slot, location);
0639     } else {
0640         slot.setValueSlot(this, location);
0641     }
0642 }
0643 
0644 // this method is here to be after the inline declaration of JSObject::inherits
0645 inline bool JSCell::isObject(const ClassInfo *info) const
0646 {
0647     return isObject() && static_cast<const JSObject *>(this)->inherits(info);
0648 }
0649 
0650 // this method is here to be after the inline declaration of JSCell::isObject
0651 inline bool JSValue::isObject(const ClassInfo *c) const
0652 {
0653     return isObject(this, c);
0654 }
0655 
0656 inline bool JSValue::isObject(const JSValue *value, const ClassInfo *c)
0657 {
0658     return !JSImmediate::isImmediate(value) && value->asCell()->isObject(c);
0659 }
0660 
0661 // It may seem crazy to inline a function this large but it makes a big difference
0662 // since this is function very hot in variable lookup
0663 inline bool JSObject::getPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
0664 {
0665     JSObject *object = this;
0666     while (true) {
0667         if (object->getOwnPropertySlot(exec, propertyName, slot)) {
0668             return true;
0669         }
0670 
0671         JSValue *proto = object->_proto;
0672         if (!JSValue::isObject(proto)) {
0673             return false;
0674         }
0675 
0676         object = static_cast<JSObject *>(proto);
0677     }
0678 }
0679 
0680 inline void JSObject::getPropertyNames(ExecState *exec, PropertyNameArray &propertyNames, PropertyMap::PropertyMode mode)
0681 {
0682     for (JSObject *cur = this; cur; cur = JSValue::getObject(cur->_proto)) {
0683         cur->getOwnPropertyNames(exec, propertyNames, mode);
0684     }
0685 }
0686 
0687 inline JSValue *JSObject::toPrimitive(ExecState *exec, JSType preferredType) const
0688 {
0689     return defaultValue(exec, preferredType);
0690 }
0691 
0692 inline JSValue *JSObject::call(ExecState *exec, JSObject *thisObj, const List &args)
0693 {
0694     return callAsFunction(exec, thisObj, args);
0695 }
0696 
0697 } // namespace
0698 
0699 #endif // KJS_OBJECT_H