webengine/osswebengine/JavaScriptCore/kjs/object.h
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     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 &amp; 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