LCOV - code coverage report
Current view: directory - js/src - jsobj.h (source / functions) Found Hit Coverage
Test: app.info Lines: 78 78 100.0 %
Date: 2012-04-07 Functions: 46 46 100.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=8 sw=4 et tw=78:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla Communicator client code, released
      18                 :  * March 31, 1998.
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  * Netscape Communications Corporation.
      22                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      23                 :  * the Initial Developer. All Rights Reserved.
      24                 :  *
      25                 :  * Contributor(s):
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #ifndef jsobj_h___
      42                 : #define jsobj_h___
      43                 : 
      44                 : /*
      45                 :  * JS object definitions.
      46                 :  *
      47                 :  * A JS object consists of a possibly-shared object descriptor containing
      48                 :  * ordered property names, called the map; and a dense vector of property
      49                 :  * values, called slots.  The map/slot pointer pair is GC'ed, while the map
      50                 :  * is reference counted and the slot vector is malloc'ed.
      51                 :  */
      52                 : #include "jsapi.h"
      53                 : #include "jsatom.h"
      54                 : #include "jsclass.h"
      55                 : #include "jsfriendapi.h"
      56                 : #include "jsinfer.h"
      57                 : #include "jshash.h"
      58                 : #include "jspubtd.h"
      59                 : #include "jsprvtd.h"
      60                 : #include "jslock.h"
      61                 : #include "jscell.h"
      62                 : 
      63                 : #include "gc/Barrier.h"
      64                 : 
      65                 : #include "vm/ObjectImpl.h"
      66                 : #include "vm/String.h"
      67                 : 
      68                 : namespace js {
      69                 : 
      70                 : class AutoPropDescArrayRooter;
      71                 : class ProxyHandler;
      72                 : class CallObject;
      73                 : struct GCMarker;
      74                 : struct NativeIterator;
      75                 : 
      76                 : namespace mjit { class Compiler; }
      77                 : 
      78                 : static inline PropertyOp
      79          299145 : CastAsPropertyOp(JSObject *object)
      80                 : {
      81          299145 :     return JS_DATA_TO_FUNC_PTR(PropertyOp, object);
      82                 : }
      83                 : 
      84                 : static inline StrictPropertyOp
      85          298947 : CastAsStrictPropertyOp(JSObject *object)
      86                 : {
      87          298947 :     return JS_DATA_TO_FUNC_PTR(StrictPropertyOp, object);
      88                 : }
      89                 : 
      90                 : inline JSObject *
      91            2036 : CastAsObject(PropertyOp op)
      92                 : {
      93            2036 :     return JS_FUNC_TO_DATA_PTR(JSObject *, op);
      94                 : }
      95                 : 
      96                 : inline JSObject *
      97              72 : CastAsObject(StrictPropertyOp op)
      98                 : {
      99              72 :     return JS_FUNC_TO_DATA_PTR(JSObject *, op);
     100                 : }
     101                 : 
     102                 : inline Value
     103            2009 : CastAsObjectJsval(PropertyOp op)
     104                 : {
     105            2009 :     return ObjectOrNullValue(CastAsObject(op));
     106                 : }
     107                 : 
     108                 : inline Value
     109              63 : CastAsObjectJsval(StrictPropertyOp op)
     110                 : {
     111              63 :     return ObjectOrNullValue(CastAsObject(op));
     112                 : }
     113                 : 
     114                 : /*
     115                 :  * JSPropertySpec uses JSAPI JSPropertyOp and JSStrictPropertyOp in function
     116                 :  * signatures, but with JSPROP_NATIVE_ACCESSORS the actual values must be
     117                 :  * JSNatives. To avoid widespread casting, have JS_PSG and JS_PSGS perform
     118                 :  * type-safe casts.
     119                 :  */
     120                 : #define JS_PSG(name,getter,flags)                                             \
     121                 :     {name, 0, (flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS,              \
     122                 :      (JSPropertyOp)getter, NULL}
     123                 : #define JS_PSGS(name,getter,setter,flags)                                     \
     124                 :     {name, 0, (flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS,              \
     125                 :      (JSPropertyOp)getter, (JSStrictPropertyOp)setter}
     126                 : #define JS_PS_END {0, 0, 0, 0, 0}
     127                 : 
     128                 : /******************************************************************************/
     129                 : 
     130                 : /*
     131                 :  * A representation of ECMA-262 ed. 5's internal Property Descriptor data
     132                 :  * structure.
     133                 :  */
     134          301709 : struct PropDesc {
     135                 :     /*
     136                 :      * Original object from which this descriptor derives, passed through for
     137                 :      * the benefit of proxies.
     138                 :      */
     139                 :     js::Value pd;
     140                 : 
     141                 :     js::Value value, get, set;
     142                 : 
     143                 :     /* Property descriptor boolean fields. */
     144                 :     uint8_t attrs;
     145                 : 
     146                 :     /* Bits indicating which values are set. */
     147                 :     bool hasGet : 1;
     148                 :     bool hasSet : 1;
     149                 :     bool hasValue : 1;
     150                 :     bool hasWritable : 1;
     151                 :     bool hasEnumerable : 1;
     152                 :     bool hasConfigurable : 1;
     153                 : 
     154                 :     friend class js::AutoPropDescArrayRooter;
     155                 : 
     156                 :     PropDesc();
     157                 : 
     158                 :     /*
     159                 :      * 8.10.5 ToPropertyDescriptor(Obj)
     160                 :      *
     161                 :      * If checkAccessors is false, skip steps 7.b and 8.b, which throw a
     162                 :      * TypeError if .get or .set is neither a callable object nor undefined.
     163                 :      *
     164                 :      * (DebuggerObject_defineProperty uses this: the .get and .set properties
     165                 :      * are expected to be Debugger.Object wrappers of functions, which are not
     166                 :      * themselves callable.)
     167                 :      */
     168                 :     bool initialize(JSContext* cx, const js::Value &v, bool checkAccessors=true);
     169                 : 
     170                 :     /*
     171                 :      * 8.10.4 FromPropertyDescriptor(Desc)
     172                 :      *
     173                 :      * initFromPropertyDescriptor sets pd to undefined and populates all the
     174                 :      * other fields of this PropDesc from desc.
     175                 :      *
     176                 :      * makeObject populates pd based on the other fields of *this, creating a
     177                 :      * new property descriptor JSObject and defining properties on it.
     178                 :      */
     179                 :     void initFromPropertyDescriptor(const PropertyDescriptor &desc);
     180                 :     bool makeObject(JSContext *cx);
     181                 : 
     182                 :     /* 8.10.1 IsAccessorDescriptor(desc) */
     183          594893 :     bool isAccessorDescriptor() const {
     184          594893 :         return hasGet || hasSet;
     185                 :     }
     186                 : 
     187                 :     /* 8.10.2 IsDataDescriptor(desc) */
     188          299746 :     bool isDataDescriptor() const {
     189          299746 :         return hasValue || hasWritable;
     190                 :     }
     191                 : 
     192                 :     /* 8.10.3 IsGenericDescriptor(desc) */
     193          297775 :     bool isGenericDescriptor() const {
     194          297775 :         return !isAccessorDescriptor() && !isDataDescriptor();
     195                 :     }
     196                 : 
     197             108 :     bool configurable() const {
     198             108 :         return (attrs & JSPROP_PERMANENT) == 0;
     199                 :     }
     200                 : 
     201               9 :     bool enumerable() const {
     202               9 :         return (attrs & JSPROP_ENUMERATE) != 0;
     203                 :     }
     204                 : 
     205              27 :     bool writable() const {
     206              27 :         return (attrs & JSPROP_READONLY) == 0;
     207                 :     }
     208                 : 
     209          298659 :     JSObject* getterObject() const {
     210          298659 :         return get.isUndefined() ? NULL : &get.toObject();
     211                 :     }
     212          298785 :     JSObject* setterObject() const {
     213          298785 :         return set.isUndefined() ? NULL : &set.toObject();
     214                 :     }
     215                 : 
     216               9 :     const js::Value &getterValue() const {
     217               9 :         return get;
     218                 :     }
     219             153 :     const js::Value &setterValue() const {
     220             153 :         return set;
     221                 :     }
     222                 : 
     223          298659 :     PropertyOp getter() const {
     224          298659 :         return js::CastAsPropertyOp(getterObject());
     225                 :     }
     226          298785 :     StrictPropertyOp setter() const {
     227          298785 :         return js::CastAsStrictPropertyOp(setterObject());
     228                 :     }
     229                 : 
     230                 :     /*
     231                 :      * Throw a TypeError if a getter/setter is present and is neither callable
     232                 :      * nor undefined. These methods do exactly the type checks that are skipped
     233                 :      * by passing false as the checkAccessors parameter of initialize.
     234                 :      */
     235                 :     inline bool checkGetter(JSContext *cx);
     236                 :     inline bool checkSetter(JSContext *cx);
     237                 : };
     238                 : 
     239                 : typedef Vector<PropDesc, 1> PropDescArray;
     240                 : 
     241                 : } /* namespace js */
     242                 : 
     243                 : /*
     244                 :  * On success, and if id was found, return true with *objp non-null and with a
     245                 :  * property of *objp stored in *propp. If successful but id was not found,
     246                 :  * return true with both *objp and *propp null.
     247                 :  */
     248                 : extern JS_FRIEND_API(JSBool)
     249                 : js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
     250                 :                   JSProperty **propp);
     251                 : 
     252                 : namespace js {
     253                 : 
     254                 : inline bool
     255                 : LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
     256                 :                JSObject **objp, JSProperty **propp)
     257                 : {
     258                 :     return js_LookupProperty(cx, obj, ATOM_TO_JSID(name), objp, propp);
     259                 : }
     260                 : 
     261                 : }
     262                 : 
     263                 : extern JS_FRIEND_API(JSBool)
     264                 : js_LookupElement(JSContext *cx, JSObject *obj, uint32_t index,
     265                 :                  JSObject **objp, JSProperty **propp);
     266                 : 
     267                 : extern JSBool
     268                 : js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
     269                 :                   JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
     270                 : 
     271                 : extern JSBool
     272                 : js_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, const js::Value *value,
     273                 :                  JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
     274                 : 
     275                 : extern JSBool
     276                 : js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, js::Value *vp);
     277                 : 
     278                 : extern JSBool
     279                 : js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t, js::Value *vp);
     280                 : 
     281                 : inline JSBool
     282            1617 : js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp)
     283                 : {
     284            1617 :     return js_GetProperty(cx, obj, obj, id, vp);
     285                 : }
     286                 : 
     287                 : inline JSBool
     288                 : js_GetElement(JSContext *cx, JSObject *obj, uint32_t index, js::Value *vp)
     289                 : {
     290                 :     return js_GetElement(cx, obj, obj, index, vp);
     291                 : }
     292                 : 
     293                 : namespace js {
     294                 : 
     295                 : extern JSBool
     296                 : GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp);
     297                 : 
     298                 : } /* namespace js */
     299                 : 
     300                 : extern JSBool
     301                 : js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
     302                 :                      js::Value *vp, JSBool strict);
     303                 : 
     304                 : namespace js {
     305                 : 
     306                 : inline bool
     307                 : SetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, unsigned defineHow,
     308                 :                   Value *vp, JSBool strict)
     309                 : {
     310                 :     return !!js_SetPropertyHelper(cx, obj, ATOM_TO_JSID(name), defineHow, vp, strict);
     311                 : }
     312                 : 
     313                 : } /* namespace js */
     314                 : 
     315                 : extern JSBool
     316                 : js_SetElementHelper(JSContext *cx, JSObject *obj, uint32_t index, unsigned defineHow,
     317                 :                     js::Value *vp, JSBool strict);
     318                 : 
     319                 : extern JSBool
     320                 : js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
     321                 : 
     322                 : extern JSBool
     323                 : js_GetElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
     324                 : 
     325                 : extern JSBool
     326                 : js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
     327                 : 
     328                 : extern JSBool
     329                 : js_SetElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
     330                 : 
     331                 : extern JSBool
     332                 : js_DeleteProperty(JSContext *cx, JSObject *obj, js::PropertyName *name, js::Value *rval, JSBool strict);
     333                 : 
     334                 : extern JSBool
     335                 : js_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index, js::Value *rval, JSBool strict);
     336                 : 
     337                 : extern JSBool
     338                 : js_DeleteSpecial(JSContext *cx, JSObject *obj, js::SpecialId sid, js::Value *rval, JSBool strict);
     339                 : 
     340                 : extern JSBool
     341                 : js_DeleteGeneric(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict);
     342                 : 
     343                 : extern JSType
     344                 : js_TypeOf(JSContext *cx, JSObject *obj);
     345                 : 
     346                 : namespace js {
     347                 : 
     348                 : /* ES5 8.12.8. */
     349                 : extern JSBool
     350                 : DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
     351                 : 
     352                 : extern Class ArrayClass;
     353                 : extern Class ArrayBufferClass;
     354                 : extern Class BlockClass;
     355                 : extern Class BooleanClass;
     356                 : extern Class CallableObjectClass;
     357                 : extern Class DateClass;
     358                 : extern Class ErrorClass;
     359                 : extern Class ElementIteratorClass;
     360                 : extern Class GeneratorClass;
     361                 : extern Class IteratorClass;
     362                 : extern Class JSONClass;
     363                 : extern Class MathClass;
     364                 : extern Class NumberClass;
     365                 : extern Class NormalArgumentsObjectClass;
     366                 : extern Class ObjectClass;
     367                 : extern Class ProxyClass;
     368                 : extern Class RegExpClass;
     369                 : extern Class RegExpStaticsClass;
     370                 : extern Class SlowArrayClass;
     371                 : extern Class StopIterationClass;
     372                 : extern Class StringClass;
     373                 : extern Class StrictArgumentsObjectClass;
     374                 : extern Class WeakMapClass;
     375                 : extern Class WithClass;
     376                 : extern Class XMLFilterClass;
     377                 : 
     378                 : class ArgumentsObject;
     379                 : class BlockObject;
     380                 : class BooleanObject;
     381                 : class ClonedBlockObject;
     382                 : class DeclEnvObject;
     383                 : class ElementIteratorObject;
     384                 : class GlobalObject;
     385                 : class NestedScopeObject;
     386                 : class NewObjectCache;
     387                 : class NormalArgumentsObject;
     388                 : class NumberObject;
     389                 : class ScopeObject;
     390                 : class StaticBlockObject;
     391                 : class StrictArgumentsObject;
     392                 : class StringObject;
     393                 : class RegExpObject;
     394                 : class WithObject;
     395                 : 
     396                 : }  /* namespace js */
     397                 : 
     398                 : /*
     399                 :  * The public interface for an object.
     400                 :  *
     401                 :  * Implementation of the underlying structure occurs in ObjectImpl, from which
     402                 :  * this struct inherits.  This inheritance is currently public, but it will
     403                 :  * eventually be made protected.  For full details, see vm/ObjectImpl.{h,cpp}.
     404                 :  *
     405                 :  * The JSFunction struct is an extension of this struct allocated from a larger
     406                 :  * GC size-class.
     407                 :  */
     408                 : struct JSObject : public js::ObjectImpl
     409         3385370 : {
     410                 :   private:
     411                 :     friend struct js::Shape;
     412                 :     friend struct js::GCMarker;
     413                 :     friend class  js::NewObjectCache;
     414                 : 
     415                 :     /* Make the type object to use for LAZY_TYPE objects. */
     416                 :     void makeLazyType(JSContext *cx);
     417                 : 
     418                 :   public:
     419                 :     /*
     420                 :      * Update the last property, keeping the number of allocated slots in sync
     421                 :      * with the object's new slot span.
     422                 :      */
     423                 :     bool setLastProperty(JSContext *cx, const js::Shape *shape);
     424                 : 
     425                 :     /* As above, but does not change the slot span. */
     426                 :     inline void setLastPropertyInfallible(const js::Shape *shape);
     427                 : 
     428                 :     /* Make a non-array object with the specified initial state. */
     429                 :     static inline JSObject *create(JSContext *cx,
     430                 :                                    js::gc::AllocKind kind,
     431                 :                                    js::HandleShape shape,
     432                 :                                    js::HandleTypeObject type,
     433                 :                                    js::HeapSlot *slots);
     434                 : 
     435                 :     /* Make a dense array object with the specified initial state. */
     436                 :     static inline JSObject *createDenseArray(JSContext *cx,
     437                 :                                              js::gc::AllocKind kind,
     438                 :                                              js::HandleShape shape,
     439                 :                                              js::HandleTypeObject type,
     440                 :                                              uint32_t length);
     441                 : 
     442                 :     /*
     443                 :      * Remove the last property of an object, provided that it is safe to do so
     444                 :      * (the shape and previous shape do not carry conflicting information about
     445                 :      * the object itself).
     446                 :      */
     447                 :     inline void removeLastProperty(JSContext *cx);
     448                 :     inline bool canRemoveLastProperty();
     449                 : 
     450                 :     /*
     451                 :      * Update the slot span directly for a dictionary object, and allocate
     452                 :      * slots to cover the new span if necessary.
     453                 :      */
     454                 :     bool setSlotSpan(JSContext *cx, uint32_t span);
     455                 : 
     456                 :     inline bool nativeContains(JSContext *cx, jsid id);
     457                 :     inline bool nativeContains(JSContext *cx, const js::Shape &shape);
     458                 : 
     459                 :     /* Upper bound on the number of elements in an object. */
     460                 :     static const uint32_t NELEMENTS_LIMIT = JS_BIT(28);
     461                 : 
     462                 :   public:
     463                 :     inline bool setDelegate(JSContext *cx);
     464                 : 
     465                 :     inline bool isBoundFunction() const;
     466                 : 
     467                 :     /*
     468                 :      * The meaning of the system object bit is defined by the API client. It is
     469                 :      * set in JS_NewSystemObject and is queried by JS_IsSystemObject, but it
     470                 :      * has no intrinsic meaning to SpiderMonkey.
     471                 :      */
     472                 :     inline bool isSystem() const;
     473                 :     inline bool setSystem(JSContext *cx);
     474                 : 
     475                 :     inline bool hasSpecialEquality() const;
     476                 : 
     477                 :     inline bool watched() const;
     478                 :     inline bool setWatched(JSContext *cx);
     479                 : 
     480                 :     /* See StackFrame::varObj. */
     481                 :     inline bool isVarObj() const;
     482                 :     inline bool setVarObj(JSContext *cx);
     483                 : 
     484                 :     /*
     485                 :      * Objects with an uncacheable proto can have their prototype mutated
     486                 :      * without inducing a shape change on the object. Property cache entries
     487                 :      * and JIT inline caches should not be filled for lookups across prototype
     488                 :      * lookups on the object.
     489                 :      */
     490                 :     inline bool hasUncacheableProto() const;
     491                 :     inline bool setUncacheableProto(JSContext *cx);
     492                 : 
     493          286959 :     bool generateOwnShape(JSContext *cx, js::Shape *newShape = NULL) {
     494          286959 :         return replaceWithNewEquivalentShape(cx, lastProperty(), newShape);
     495                 :     }
     496                 : 
     497                 :   private:
     498                 :     js::Shape *replaceWithNewEquivalentShape(JSContext *cx, js::Shape *existingShape,
     499                 :                                              js::Shape *newShape = NULL);
     500                 : 
     501                 :     enum GenerateShape {
     502                 :         GENERATE_NONE,
     503                 :         GENERATE_SHAPE
     504                 :     };
     505                 : 
     506                 :     bool setFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag,
     507                 :                  GenerateShape generateShape = GENERATE_NONE);
     508                 : 
     509                 :   public:
     510                 :     inline bool nativeEmpty() const;
     511                 : 
     512                 :     bool shadowingShapeChange(JSContext *cx, const js::Shape &shape);
     513                 : 
     514                 :     /* Whether there may be indexed properties on this object. */
     515                 :     inline bool isIndexed() const;
     516                 : 
     517                 :     inline uint32_t propertyCount() const;
     518                 : 
     519                 :     inline bool hasPropertyTable() const;
     520                 : 
     521                 :     inline size_t computedSizeOfThisSlotsElements() const;
     522                 : 
     523                 :     inline void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf,
     524                 :                                     size_t *slotsSize, size_t *elementsSize,
     525                 :                                     size_t *miscSize) const;
     526                 : 
     527                 :     static const uint32_t MAX_FIXED_SLOTS = 16;
     528                 : 
     529                 :   public:
     530                 : 
     531                 :     /* Accessors for properties. */
     532                 : 
     533                 :     /* Whether a slot is at a fixed offset from this object. */
     534                 :     inline bool isFixedSlot(size_t slot);
     535                 : 
     536                 :     /* Index into the dynamic slots array to use for a dynamic slot. */
     537                 :     inline size_t dynamicSlotIndex(size_t slot);
     538                 : 
     539                 :     /* Get a raw pointer to the object's properties. */
     540                 :     inline const js::HeapSlot *getRawSlots();
     541                 : 
     542                 :     /*
     543                 :      * Grow or shrink slots immediately before changing the slot span.
     544                 :      * The number of allocated slots is not stored explicitly, and changes to
     545                 :      * the slots must track changes in the slot span.
     546                 :      */
     547                 :     bool growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount);
     548                 :     void shrinkSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount);
     549                 : 
     550        32433901 :     bool hasDynamicSlots() const { return slots != NULL; }
     551                 : 
     552                 :   protected:
     553                 :     inline bool updateSlotsForSpan(JSContext *cx, size_t oldSpan, size_t newSpan);
     554                 : 
     555                 :   public:
     556                 :     /*
     557                 :      * Trigger the write barrier on a range of slots that will no longer be
     558                 :      * reachable.
     559                 :      */
     560                 :     inline void prepareSlotRangeForOverwrite(size_t start, size_t end);
     561                 :     inline void prepareElementRangeForOverwrite(size_t start, size_t end);
     562                 : 
     563                 :     void rollbackProperties(JSContext *cx, uint32_t slotSpan);
     564                 : 
     565                 :     inline void nativeSetSlot(unsigned slot, const js::Value &value);
     566                 :     inline void nativeSetSlotWithType(JSContext *cx, const js::Shape *shape, const js::Value &value);
     567                 : 
     568                 :     inline const js::Value &getReservedSlot(unsigned index) const;
     569                 :     inline js::HeapSlot &getReservedSlotRef(unsigned index);
     570                 :     inline void initReservedSlot(unsigned index, const js::Value &v);
     571                 :     inline void setReservedSlot(unsigned index, const js::Value &v);
     572                 : 
     573                 :     /*
     574                 :      * Marks this object as having a singleton type, and leave the type lazy.
     575                 :      * Constructs a new, unique shape for the object.
     576                 :      */
     577                 :     inline bool setSingletonType(JSContext *cx);
     578                 : 
     579                 :     inline js::types::TypeObject *getType(JSContext *cx);
     580                 : 
     581        16486827 :     const js::HeapPtr<js::types::TypeObject> &typeFromGC() const {
     582                 :         /* Direct field access for use by GC. */
     583        16486827 :         return type_;
     584                 :     }
     585                 : 
     586                 :     inline void setType(js::types::TypeObject *newType);
     587                 : 
     588                 :     js::types::TypeObject *getNewType(JSContext *cx, JSFunction *fun = NULL);
     589                 : 
     590                 : #ifdef DEBUG
     591                 :     bool hasNewType(js::types::TypeObject *newType);
     592                 : #endif
     593                 : 
     594                 :     /*
     595                 :      * Mark an object that has been iterated over and is a singleton. We need
     596                 :      * to recover this information in the object's type information after it
     597                 :      * is purged on GC.
     598                 :      */
     599                 :     inline bool setIteratedSingleton(JSContext *cx);
     600                 : 
     601                 :     /*
     602                 :      * Mark an object as requiring its default 'new' type to have unknown
     603                 :      * properties.
     604                 :      */
     605                 :     bool setNewTypeUnknown(JSContext *cx);
     606                 : 
     607                 :     /* Set a new prototype for an object with a singleton type. */
     608                 :     bool splicePrototype(JSContext *cx, JSObject *proto);
     609                 : 
     610                 :     /*
     611                 :      * For bootstrapping, whether to splice a prototype for Function.prototype
     612                 :      * or the global object.
     613                 :      */
     614                 :     bool shouldSplicePrototype(JSContext *cx);
     615                 : 
     616                 :     /*
     617                 :      * Parents and scope chains.
     618                 :      *
     619                 :      * All script-accessible objects with a NULL parent are global objects,
     620                 :      * and all global objects have a NULL parent. Some builtin objects which
     621                 :      * are not script-accessible also have a NULL parent, such as parser
     622                 :      * created functions for non-compileAndGo scripts.
     623                 :      *
     624                 :      * Except for the non-script-accessible builtins, the global with which an
     625                 :      * object is associated can be reached by following parent links to that
     626                 :      * global (see global()).
     627                 :      *
     628                 :      * The scope chain of an object is the link in the search path when a
     629                 :      * script does a name lookup on a scope object. For JS internal scope
     630                 :      * objects --- Call, DeclEnv and block --- the chain is stored in
     631                 :      * the first fixed slot of the object, and the object's parent is the
     632                 :      * associated global. For other scope objects, the chain is stored in the
     633                 :      * object's parent.
     634                 :      *
     635                 :      * In compileAndGo code, scope chains can contain only internal scope
     636                 :      * objects with a global object at the root as the scope of the outermost
     637                 :      * non-function script. In non-compileAndGo code, the scope of the
     638                 :      * outermost non-function script might not be a global object, and can have
     639                 :      * a mix of other objects above it before the global object is reached.
     640                 :      */
     641                 : 
     642                 :     /* Access the parent link of an object. */
     643                 :     inline JSObject *getParent() const;
     644                 :     bool setParent(JSContext *cx, JSObject *newParent);
     645                 : 
     646                 :     /*
     647                 :      * Get the enclosing scope of an object. When called on non-scope object,
     648                 :      * this will just be the global (the name "enclosing scope" still applies
     649                 :      * in this situation because non-scope objects can be on the scope chain).
     650                 :      */
     651                 :     inline JSObject *enclosingScope();
     652                 : 
     653                 :     inline js::GlobalObject &global() const;
     654                 : 
     655                 :     /* N.B. Infallible: NULL means 'no principal', not an error. */
     656                 :     inline JSPrincipals *principals(JSContext *cx);
     657                 : 
     658                 :     /* Remove the type (and prototype) or parent from a new object. */
     659                 :     inline bool clearType(JSContext *cx);
     660                 :     bool clearParent(JSContext *cx);
     661                 : 
     662                 :     /*
     663                 :      * ES5 meta-object properties and operations.
     664                 :      */
     665                 : 
     666                 :   private:
     667                 :     enum ImmutabilityType { SEAL, FREEZE };
     668                 : 
     669                 :     /*
     670                 :      * The guts of Object.seal (ES5 15.2.3.8) and Object.freeze (ES5 15.2.3.9): mark the
     671                 :      * object as non-extensible, and adjust each property's attributes appropriately: each
     672                 :      * property becomes non-configurable, and if |freeze|, data properties become
     673                 :      * read-only as well.
     674                 :      */
     675                 :     bool sealOrFreeze(JSContext *cx, ImmutabilityType it);
     676                 : 
     677                 :     bool isSealedOrFrozen(JSContext *cx, ImmutabilityType it, bool *resultp);
     678                 : 
     679                 :     static inline unsigned getSealedOrFrozenAttributes(unsigned attrs, ImmutabilityType it);
     680                 : 
     681                 :   public:
     682                 :     bool preventExtensions(JSContext *cx, js::AutoIdVector *props);
     683                 : 
     684                 :     /* ES5 15.2.3.8: non-extensible, all props non-configurable */
     685             315 :     inline bool seal(JSContext *cx) { return sealOrFreeze(cx, SEAL); }
     686                 :     /* ES5 15.2.3.9: non-extensible, all properties non-configurable, all data props read-only */
     687         1219359 :     bool freeze(JSContext *cx) { return sealOrFreeze(cx, FREEZE); }
     688                 : 
     689             567 :     bool isSealed(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, SEAL, resultp); }
     690             572 :     bool isFrozen(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, FREEZE, resultp); }
     691                 : 
     692                 :     /* Accessors for elements. */
     693                 : 
     694                 :     inline bool ensureElements(JSContext *cx, unsigned cap);
     695                 :     bool growElements(JSContext *cx, unsigned cap);
     696                 :     void shrinkElements(JSContext *cx, unsigned cap);
     697                 : 
     698                 :     inline js::ElementIteratorObject *asElementIterator();
     699                 : 
     700                 :     /*
     701                 :      * Array-specific getters and setters (for both dense and slow arrays).
     702                 :      */
     703                 : 
     704                 :     bool allocateSlowArrayElements(JSContext *cx);
     705                 : 
     706                 :     inline uint32_t getArrayLength() const;
     707                 :     inline void setArrayLength(JSContext *cx, uint32_t length);
     708                 : 
     709                 :     inline uint32_t getDenseArrayCapacity();
     710                 :     inline void setDenseArrayLength(uint32_t length);
     711                 :     inline void setDenseArrayInitializedLength(uint32_t length);
     712                 :     inline void ensureDenseArrayInitializedLength(JSContext *cx, unsigned index, unsigned extra);
     713                 :     inline void setDenseArrayElement(unsigned idx, const js::Value &val);
     714                 :     inline void initDenseArrayElement(unsigned idx, const js::Value &val);
     715                 :     inline void setDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val);
     716                 :     inline void initDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val);
     717                 :     inline void copyDenseArrayElements(unsigned dstStart, const js::Value *src, unsigned count);
     718                 :     inline void initDenseArrayElements(unsigned dstStart, const js::Value *src, unsigned count);
     719                 :     inline void moveDenseArrayElements(unsigned dstStart, unsigned srcStart, unsigned count);
     720                 :     inline void moveDenseArrayElementsUnbarriered(unsigned dstStart, unsigned srcStart, unsigned count);
     721                 :     inline bool denseArrayHasInlineSlots() const;
     722                 : 
     723                 :     /* Packed information for this array. */
     724                 :     inline void markDenseArrayNotPacked(JSContext *cx);
     725                 : 
     726                 :     /*
     727                 :      * ensureDenseArrayElements ensures that the dense array can hold at least
     728                 :      * index + extra elements. It returns ED_OK on success, ED_FAILED on
     729                 :      * failure to grow the array, ED_SPARSE when the array is too sparse to
     730                 :      * grow (this includes the case of index + extra overflow). In the last
     731                 :      * two cases the array is kept intact.
     732                 :      */
     733                 :     enum EnsureDenseResult { ED_OK, ED_FAILED, ED_SPARSE };
     734                 :     inline EnsureDenseResult ensureDenseArrayElements(JSContext *cx, unsigned index, unsigned extra);
     735                 : 
     736                 :     /*
     737                 :      * Check if after growing the dense array will be too sparse.
     738                 :      * newElementsHint is an estimated number of elements to be added.
     739                 :      */
     740                 :     bool willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElementsHint);
     741                 : 
     742                 :     JSBool makeDenseArraySlow(JSContext *cx);
     743                 : 
     744                 :     /*
     745                 :      * If this array object has a data property with index i, set *vp to its
     746                 :      * value and return true. If not, do vp->setMagic(JS_ARRAY_HOLE) and return
     747                 :      * true. On OOM, report it and return false.
     748                 :      */
     749                 :     bool arrayGetOwnDataElement(JSContext *cx, size_t i, js::Value *vp);
     750                 : 
     751                 :   public:
     752                 :     bool allocateArrayBufferSlots(JSContext *cx, uint32_t size, uint8_t *contents = NULL);
     753                 :     inline uint32_t arrayBufferByteLength();
     754                 :     inline uint8_t * arrayBufferDataOffset();
     755                 : 
     756                 :   public:
     757                 :     /*
     758                 :      * Date-specific getters and setters.
     759                 :      */
     760                 : 
     761                 :     static const uint32_t JSSLOT_DATE_UTC_TIME = 0;
     762                 : 
     763                 :     /*
     764                 :      * Cached slots holding local properties of the date.
     765                 :      * These are undefined until the first actual lookup occurs
     766                 :      * and are reset to undefined whenever the date's time is modified.
     767                 :      */
     768                 :     static const uint32_t JSSLOT_DATE_COMPONENTS_START = 1;
     769                 : 
     770                 :     static const uint32_t JSSLOT_DATE_LOCAL_TIME = 1;
     771                 :     static const uint32_t JSSLOT_DATE_LOCAL_YEAR = 2;
     772                 :     static const uint32_t JSSLOT_DATE_LOCAL_MONTH = 3;
     773                 :     static const uint32_t JSSLOT_DATE_LOCAL_DATE = 4;
     774                 :     static const uint32_t JSSLOT_DATE_LOCAL_DAY = 5;
     775                 :     static const uint32_t JSSLOT_DATE_LOCAL_HOURS = 6;
     776                 :     static const uint32_t JSSLOT_DATE_LOCAL_MINUTES = 7;
     777                 :     static const uint32_t JSSLOT_DATE_LOCAL_SECONDS = 8;
     778                 : 
     779                 :     static const uint32_t DATE_CLASS_RESERVED_SLOTS = 9;
     780                 : 
     781                 :     inline const js::Value &getDateUTCTime() const;
     782                 :     inline void setDateUTCTime(const js::Value &pthis);
     783                 : 
     784                 :     /*
     785                 :      * Function-specific getters and setters.
     786                 :      */
     787                 : 
     788                 :     friend struct JSFunction;
     789                 : 
     790                 :     inline JSFunction *toFunction();
     791                 :     inline const JSFunction *toFunction() const;
     792                 : 
     793                 :   public:
     794                 :     /*
     795                 :      * Iterator-specific getters and setters.
     796                 :      */
     797                 : 
     798                 :     static const uint32_t ITER_CLASS_NFIXED_SLOTS = 1;
     799                 : 
     800                 :     inline js::NativeIterator *getNativeIterator() const;
     801                 :     inline void setNativeIterator(js::NativeIterator *);
     802                 : 
     803                 :     /*
     804                 :      * XML-related getters and setters.
     805                 :      */
     806                 : 
     807                 :     /*
     808                 :      * Slots for XML-related classes are as follows:
     809                 :      * - NamespaceClass.base reserves the *_NAME_* and *_NAMESPACE_* slots.
     810                 :      * - QNameClass.base, AttributeNameClass, AnyNameClass reserve
     811                 :      *   the *_NAME_* and *_QNAME_* slots.
     812                 :      * - Others (XMLClass, js_XMLFilterClass) don't reserve any slots.
     813                 :      */
     814                 :   private:
     815                 :     static const uint32_t JSSLOT_NAME_PREFIX          = 0;   // shared
     816                 :     static const uint32_t JSSLOT_NAME_URI             = 1;   // shared
     817                 : 
     818                 :     static const uint32_t JSSLOT_NAMESPACE_DECLARED   = 2;
     819                 : 
     820                 :     static const uint32_t JSSLOT_QNAME_LOCAL_NAME     = 2;
     821                 : 
     822                 :   public:
     823                 :     static const uint32_t NAMESPACE_CLASS_RESERVED_SLOTS = 3;
     824                 :     static const uint32_t QNAME_CLASS_RESERVED_SLOTS     = 3;
     825                 : 
     826                 :     inline JSLinearString *getNamePrefix() const;
     827                 :     inline jsval getNamePrefixVal() const;
     828                 :     inline void setNamePrefix(JSLinearString *prefix);
     829                 :     inline void clearNamePrefix();
     830                 : 
     831                 :     inline JSLinearString *getNameURI() const;
     832                 :     inline jsval getNameURIVal() const;
     833                 :     inline void setNameURI(JSLinearString *uri);
     834                 : 
     835                 :     inline jsval getNamespaceDeclared() const;
     836                 :     inline void setNamespaceDeclared(jsval decl);
     837                 : 
     838                 :     inline JSAtom *getQNameLocalName() const;
     839                 :     inline jsval getQNameLocalNameVal() const;
     840                 :     inline void setQNameLocalName(JSAtom *name);
     841                 : 
     842                 :     /*
     843                 :      * Back to generic stuff.
     844                 :      */
     845                 :     inline bool isCallable();
     846                 : 
     847                 :     inline void finish(js::FreeOp *fop);
     848                 :     JS_ALWAYS_INLINE void finalize(js::FreeOp *fop);
     849                 : 
     850                 :     inline bool hasProperty(JSContext *cx, jsid id, bool *foundp, unsigned flags = 0);
     851                 : 
     852                 :     /*
     853                 :      * Allocate and free an object slot.
     854                 :      *
     855                 :      * FIXME: bug 593129 -- slot allocation should be done by object methods
     856                 :      * after calling object-parameter-free shape methods, avoiding coupling
     857                 :      * logic across the object vs. shape module wall.
     858                 :      */
     859                 :     bool allocSlot(JSContext *cx, uint32_t *slotp);
     860                 :     void freeSlot(JSContext *cx, uint32_t slot);
     861                 : 
     862                 :   public:
     863                 :     bool reportNotConfigurable(JSContext* cx, jsid id, unsigned report = JSREPORT_ERROR);
     864                 :     bool reportNotExtensible(JSContext *cx, unsigned report = JSREPORT_ERROR);
     865                 : 
     866                 :     /*
     867                 :      * Get the property with the given id, then call it as a function with the
     868                 :      * given arguments, providing this object as |this|. If the property isn't
     869                 :      * callable a TypeError will be thrown. On success the value returned by
     870                 :      * the call is stored in *vp.
     871                 :      */
     872                 :     bool callMethod(JSContext *cx, jsid id, unsigned argc, js::Value *argv, js::Value *vp);
     873                 : 
     874                 :   private:
     875                 :     js::Shape *getChildProperty(JSContext *cx, js::Shape *parent, js::StackShape &child);
     876                 : 
     877                 :   protected:
     878                 :     /*
     879                 :      * Internal helper that adds a shape not yet mapped by this object.
     880                 :      *
     881                 :      * Notes:
     882                 :      * 1. getter and setter must be normalized based on flags (see jsscope.cpp).
     883                 :      * 2. !isExtensible() checking must be done by callers.
     884                 :      */
     885                 :     js::Shape *addPropertyInternal(JSContext *cx, jsid id,
     886                 :                                    JSPropertyOp getter, JSStrictPropertyOp setter,
     887                 :                                    uint32_t slot, unsigned attrs,
     888                 :                                    unsigned flags, int shortid, js::Shape **spp,
     889                 :                                    bool allowDictionary);
     890                 : 
     891                 :   private:
     892                 :     bool toDictionaryMode(JSContext *cx);
     893                 : 
     894                 :     struct TradeGutsReserved;
     895                 :     static bool ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
     896                 :                                     TradeGutsReserved &reserved);
     897                 : 
     898                 :     static void TradeGuts(JSContext *cx, JSObject *a, JSObject *b,
     899                 :                           TradeGutsReserved &reserved);
     900                 : 
     901                 :   public:
     902                 :     /* Add a property whose id is not yet in this scope. */
     903                 :     js::Shape *addProperty(JSContext *cx, jsid id,
     904                 :                            JSPropertyOp getter, JSStrictPropertyOp setter,
     905                 :                            uint32_t slot, unsigned attrs,
     906                 :                            unsigned flags, int shortid, bool allowDictionary = true);
     907                 : 
     908                 :     /* Add a data property whose id is not yet in this scope. */
     909          143305 :     js::Shape *addDataProperty(JSContext *cx, jsid id, uint32_t slot, unsigned attrs) {
     910          143305 :         JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
     911          143305 :         return addProperty(cx, id, NULL, NULL, slot, attrs, 0, 0);
     912                 :     }
     913                 : 
     914                 :     /* Add or overwrite a property for id in this scope. */
     915                 :     js::Shape *putProperty(JSContext *cx, jsid id,
     916                 :                            JSPropertyOp getter, JSStrictPropertyOp setter,
     917                 :                            uint32_t slot, unsigned attrs,
     918                 :                            unsigned flags, int shortid);
     919                 :     inline js::Shape *
     920            1350 :     putProperty(JSContext *cx, js::PropertyName *name,
     921                 :                 JSPropertyOp getter, JSStrictPropertyOp setter,
     922                 :                 uint32_t slot, unsigned attrs, unsigned flags, int shortid) {
     923            1350 :         return putProperty(cx, js_CheckForStringIndex(ATOM_TO_JSID(name)), getter, setter, slot, attrs, flags, shortid);
     924                 :     }
     925                 : 
     926                 :     /* Change the given property into a sibling with the same id in this scope. */
     927                 :     js::Shape *changeProperty(JSContext *cx, js::Shape *shape, unsigned attrs, unsigned mask,
     928                 :                               JSPropertyOp getter, JSStrictPropertyOp setter);
     929                 : 
     930                 :     inline bool changePropertyAttributes(JSContext *cx, js::Shape *shape, unsigned attrs);
     931                 : 
     932                 :     /* Remove the property named by id from this object. */
     933                 :     bool removeProperty(JSContext *cx, jsid id);
     934                 : 
     935                 :     /* Clear the scope, making it empty. */
     936                 :     void clear(JSContext *cx);
     937                 : 
     938                 :     inline JSBool lookupGeneric(JSContext *cx, jsid id, JSObject **objp, JSProperty **propp);
     939                 :     inline JSBool lookupProperty(JSContext *cx, js::PropertyName *name, JSObject **objp, JSProperty **propp);
     940                 :     inline JSBool lookupElement(JSContext *cx, uint32_t index,
     941                 :                                 JSObject **objp, JSProperty **propp);
     942                 :     inline JSBool lookupSpecial(JSContext *cx, js::SpecialId sid,
     943                 :                                 JSObject **objp, JSProperty **propp);
     944                 : 
     945                 :     inline JSBool defineGeneric(JSContext *cx, jsid id, const js::Value &value,
     946                 :                                 JSPropertyOp getter = JS_PropertyStub,
     947                 :                                 JSStrictPropertyOp setter = JS_StrictPropertyStub,
     948                 :                                 unsigned attrs = JSPROP_ENUMERATE);
     949                 :     inline JSBool defineProperty(JSContext *cx, js::PropertyName *name, const js::Value &value,
     950                 :                                  JSPropertyOp getter = JS_PropertyStub,
     951                 :                                  JSStrictPropertyOp setter = JS_StrictPropertyStub,
     952                 :                                  unsigned attrs = JSPROP_ENUMERATE);
     953                 : 
     954                 :     inline JSBool defineElement(JSContext *cx, uint32_t index, const js::Value &value,
     955                 :                                 JSPropertyOp getter = JS_PropertyStub,
     956                 :                                 JSStrictPropertyOp setter = JS_StrictPropertyStub,
     957                 :                                 unsigned attrs = JSPROP_ENUMERATE);
     958                 :     inline JSBool defineSpecial(JSContext *cx, js::SpecialId sid, const js::Value &value,
     959                 :                                 JSPropertyOp getter = JS_PropertyStub,
     960                 :                                 JSStrictPropertyOp setter = JS_StrictPropertyStub,
     961                 :                                 unsigned attrs = JSPROP_ENUMERATE);
     962                 : 
     963                 :     inline JSBool getGeneric(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp);
     964                 :     inline JSBool getProperty(JSContext *cx, JSObject *receiver, js::PropertyName *name,
     965                 :                               js::Value *vp);
     966                 :     inline JSBool getElement(JSContext *cx, JSObject *receiver, uint32_t index, js::Value *vp);
     967                 :     /* If element is not present (e.g. array hole) *present is set to
     968                 :        false and the contents of *vp are unusable garbage. */
     969                 :     inline JSBool getElementIfPresent(JSContext *cx, JSObject *receiver, uint32_t index,
     970                 :                                       js::Value *vp, bool *present);
     971                 :     inline JSBool getSpecial(JSContext *cx, JSObject *receiver, js::SpecialId sid, js::Value *vp);
     972                 : 
     973                 :     inline JSBool getGeneric(JSContext *cx, jsid id, js::Value *vp);
     974                 :     inline JSBool getProperty(JSContext *cx, js::PropertyName *name, js::Value *vp);
     975                 :     inline JSBool getElement(JSContext *cx, uint32_t index, js::Value *vp);
     976                 :     inline JSBool getSpecial(JSContext *cx, js::SpecialId sid, js::Value *vp);
     977                 : 
     978                 :     inline JSBool setGeneric(JSContext *cx, jsid id, js::Value *vp, JSBool strict);
     979                 :     inline JSBool setProperty(JSContext *cx, js::PropertyName *name, js::Value *vp, JSBool strict);
     980                 :     inline JSBool setElement(JSContext *cx, uint32_t index, js::Value *vp, JSBool strict);
     981                 :     inline JSBool setSpecial(JSContext *cx, js::SpecialId sid, js::Value *vp, JSBool strict);
     982                 : 
     983                 :     JSBool nonNativeSetProperty(JSContext *cx, jsid id, js::Value *vp, JSBool strict);
     984                 :     JSBool nonNativeSetElement(JSContext *cx, uint32_t index, js::Value *vp, JSBool strict);
     985                 : 
     986                 :     inline JSBool getGenericAttributes(JSContext *cx, jsid id, unsigned *attrsp);
     987                 :     inline JSBool getPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp);
     988                 :     inline JSBool getElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp);
     989                 :     inline JSBool getSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp);
     990                 : 
     991                 :     inline JSBool setGenericAttributes(JSContext *cx, jsid id, unsigned *attrsp);
     992                 :     inline JSBool setPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp);
     993                 :     inline JSBool setElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp);
     994                 :     inline JSBool setSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp);
     995                 : 
     996                 :     inline bool deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, bool strict);
     997                 :     inline bool deleteElement(JSContext *cx, uint32_t index, js::Value *rval, bool strict);
     998                 :     inline bool deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, bool strict);
     999                 :     bool deleteByValue(JSContext *cx, const js::Value &property, js::Value *rval, bool strict);
    1000                 : 
    1001                 :     inline bool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp);
    1002                 :     inline bool defaultValue(JSContext *cx, JSType hint, js::Value *vp);
    1003                 :     inline JSType typeOf(JSContext *cx);
    1004                 :     inline JSObject *thisObject(JSContext *cx);
    1005                 : 
    1006                 :     static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
    1007                 : 
    1008                 :     bool swap(JSContext *cx, JSObject *other);
    1009                 : 
    1010                 :     inline void initArrayClass();
    1011                 : 
    1012                 :     /*
    1013                 :      * In addition to the generic object interface provided by JSObject,
    1014                 :      * specific types of objects may provide additional operations. To access,
    1015                 :      * these addition operations, callers should use the pattern:
    1016                 :      *
    1017                 :      *   if (obj.isX()) {
    1018                 :      *     XObject &x = obj.asX();
    1019                 :      *     x.foo();
    1020                 :      *   }
    1021                 :      *
    1022                 :      * These XObject classes form a hierarchy. For example, for a cloned block
    1023                 :      * object, the following predicates are true: isClonedBlock, isBlock,
    1024                 :      * isNestedScope and isScope. Each of these has a respective class that
    1025                 :      * derives and adds operations.
    1026                 :      *
    1027                 :      * A class XObject is defined in a vm/XObject{.h, .cpp, -inl.h} file
    1028                 :      * triplet (along with any class YObject that derives XObject).
    1029                 :      *
    1030                 :      * Note that X represents a low-level representation and does not query the
    1031                 :      * [[Class]] property of object defined by the spec (for this, see
    1032                 :      * js::ObjectClassIs).
    1033                 :      *
    1034                 :      * SpiderMonkey has not been completely switched to the isX/asX/XObject
    1035                 :      * pattern so in some cases there is no XObject class and the engine
    1036                 :      * instead pokes directly at reserved slots and getPrivate. In such cases,
    1037                 :      * consider adding the missing XObject class.
    1038                 :      */
    1039                 : 
    1040                 :     /* Direct subtypes of JSObject: */
    1041                 :     inline bool isArguments() const;
    1042                 :     inline bool isArrayBuffer() const;
    1043                 :     inline bool isDate() const;
    1044                 :     inline bool isElementIterator() const;
    1045                 :     inline bool isError() const;
    1046                 :     inline bool isFunction() const;
    1047                 :     inline bool isGenerator() const;
    1048                 :     inline bool isGlobal() const;
    1049                 :     inline bool isIterator() const;
    1050                 :     inline bool isNamespace() const;
    1051                 :     inline bool isObject() const;
    1052                 :     inline bool isQName() const;
    1053                 :     inline bool isPrimitive() const;
    1054                 :     inline bool isProxy() const;
    1055                 :     inline bool isRegExp() const;
    1056                 :     inline bool isRegExpStatics() const;
    1057                 :     inline bool isScope() const;
    1058                 :     inline bool isScript() const;
    1059                 :     inline bool isStopIteration() const;
    1060                 :     inline bool isTypedArray() const;
    1061                 :     inline bool isWeakMap() const;
    1062                 :     inline bool isXML() const;
    1063                 :     inline bool isXMLId() const;
    1064                 : 
    1065                 :     /* Subtypes of ScopeObject. */
    1066                 :     inline bool isBlock() const;
    1067                 :     inline bool isCall() const;
    1068                 :     inline bool isDeclEnv() const;
    1069                 :     inline bool isNestedScope() const;
    1070                 :     inline bool isWith() const;
    1071                 :     inline bool isClonedBlock() const;
    1072                 :     inline bool isStaticBlock() const;
    1073                 : 
    1074                 :     /* Subtypes of PrimitiveObject. */
    1075                 :     inline bool isBoolean() const;
    1076                 :     inline bool isNumber() const;
    1077                 :     inline bool isString() const;
    1078                 : 
    1079                 :     /* Subtypes of ArgumentsObject. */
    1080                 :     inline bool isNormalArguments() const;
    1081                 :     inline bool isStrictArguments() const;
    1082                 : 
    1083                 :     /* Subtypes of Proxy. */
    1084                 :     inline bool isWrapper() const;
    1085                 :     inline bool isFunctionProxy() const;
    1086                 :     inline bool isCrossCompartmentWrapper() const;
    1087                 : 
    1088                 :     inline js::ArgumentsObject &asArguments();
    1089                 :     inline const js::ArgumentsObject &asArguments() const;
    1090                 :     inline js::BlockObject &asBlock();
    1091                 :     inline js::BooleanObject &asBoolean();
    1092                 :     inline js::CallObject &asCall();
    1093                 :     inline js::ClonedBlockObject &asClonedBlock();
    1094                 :     inline js::DeclEnvObject &asDeclEnv();
    1095                 :     inline js::GlobalObject &asGlobal();
    1096                 :     inline js::NestedScopeObject &asNestedScope();
    1097                 :     inline js::NormalArgumentsObject &asNormalArguments();
    1098                 :     inline js::NumberObject &asNumber();
    1099                 :     inline js::RegExpObject &asRegExp();
    1100                 :     inline js::ScopeObject &asScope();
    1101                 :     inline js::StrictArgumentsObject &asStrictArguments();
    1102                 :     inline js::StaticBlockObject &asStaticBlock();
    1103                 :     inline js::StringObject &asString();
    1104                 :     inline js::WithObject &asWith();
    1105                 : 
    1106                 :     static inline js::ThingRootKind rootKind() { return js::THING_ROOT_OBJECT; }
    1107                 : 
    1108                 : #ifdef DEBUG
    1109                 :     void dump();
    1110                 : #endif
    1111                 : 
    1112                 :   private:
    1113                 :     static void staticAsserts() {
    1114                 :         MOZ_STATIC_ASSERT(sizeof(JSObject) == sizeof(js::shadow::Object),
    1115                 :                           "shadow interface must match actual interface");
    1116                 :         MOZ_STATIC_ASSERT(sizeof(JSObject) == sizeof(js::ObjectImpl),
    1117                 :                           "JSObject itself must not have any fields");
    1118                 :         MOZ_STATIC_ASSERT(sizeof(JSObject) % sizeof(js::Value) == 0,
    1119                 :                           "fixed slots after an object must be aligned");
    1120                 :     }
    1121                 : };
    1122                 : 
    1123                 : /*
    1124                 :  * The only sensible way to compare JSObject with == is by identity. We use
    1125                 :  * const& instead of * as a syntactic way to assert non-null. This leads to an
    1126                 :  * abundance of address-of operators to identity. Hence this overload.
    1127                 :  */
    1128                 : static JS_ALWAYS_INLINE bool
    1129         1529830 : operator==(const JSObject &lhs, const JSObject &rhs)
    1130                 : {
    1131         1529830 :     return &lhs == &rhs;
    1132                 : }
    1133                 : 
    1134                 : static JS_ALWAYS_INLINE bool
    1135          211056 : operator!=(const JSObject &lhs, const JSObject &rhs)
    1136                 : {
    1137          211056 :     return &lhs != &rhs;
    1138                 : }
    1139                 : 
    1140                 : struct JSObject_Slots2 : JSObject { js::Value fslots[2]; };
    1141                 : struct JSObject_Slots4 : JSObject { js::Value fslots[4]; };
    1142                 : struct JSObject_Slots8 : JSObject { js::Value fslots[8]; };
    1143                 : struct JSObject_Slots12 : JSObject { js::Value fslots[12]; };
    1144         3385370 : struct JSObject_Slots16 : JSObject { js::Value fslots[16]; };
    1145                 : 
    1146                 : #define JSSLOT_FREE(clasp)  JSCLASS_RESERVED_SLOTS(clasp)
    1147                 : 
    1148                 : class JSValueArray {
    1149                 :   public:
    1150                 :     jsval *array;
    1151                 :     size_t length;
    1152                 : 
    1153           35322 :     JSValueArray(jsval *v, size_t c) : array(v), length(c) {}
    1154                 : };
    1155                 : 
    1156                 : class ValueArray {
    1157                 :   public:
    1158                 :     js::Value *array;
    1159                 :     size_t length;
    1160                 : 
    1161                 :     ValueArray(js::Value *v, size_t c) : array(v), length(c) {}
    1162                 : };
    1163                 : 
    1164                 : /* For manipulating JSContext::sharpObjectMap. */
    1165                 : extern bool
    1166                 : js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, bool *alreadySeen, bool *isSharp);
    1167                 : 
    1168                 : extern void
    1169                 : js_LeaveSharpObject(JSContext *cx, JSIdArray **idap);
    1170                 : 
    1171                 : /*
    1172                 :  * Mark objects stored in map if GC happens between js_EnterSharpObject
    1173                 :  * and js_LeaveSharpObject. GC calls this when map->depth > 0.
    1174                 :  */
    1175                 : extern void
    1176                 : js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map);
    1177                 : 
    1178                 : extern JSBool
    1179                 : js_HasOwnPropertyHelper(JSContext *cx, js::LookupGenericOp lookup, unsigned argc,
    1180                 :                         js::Value *vp);
    1181                 : 
    1182                 : extern JSBool
    1183                 : js_HasOwnProperty(JSContext *cx, js::LookupGenericOp lookup, JSObject *obj, jsid id,
    1184                 :                   JSObject **objp, JSProperty **propp);
    1185                 : 
    1186                 : extern JSBool
    1187                 : js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
    1188                 : 
    1189                 : #if JS_HAS_OBJ_PROTO_PROP
    1190                 : extern JSPropertySpec object_props[];
    1191                 : #else
    1192                 : #define object_props NULL
    1193                 : #endif
    1194                 : 
    1195                 : extern JSFunctionSpec object_methods[];
    1196                 : extern JSFunctionSpec object_static_methods[];
    1197                 : 
    1198                 : namespace js {
    1199                 : 
    1200                 : bool
    1201                 : IsStandardClassResolved(JSObject *obj, js::Class *clasp);
    1202                 : 
    1203                 : void
    1204                 : MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp);
    1205                 : 
    1206                 : /*
    1207                 :  * Cache for speeding up repetitive creation of objects in the VM.
    1208                 :  * When an object is created which matches the criteria in the 'key' section
    1209                 :  * below, an entry is filled with the resulting object.
    1210                 :  */
    1211                 : class NewObjectCache
    1212           82570 : {
    1213                 :     struct Entry
    1214         3385370 :     {
    1215                 :         /* Class of the constructed object. */
    1216                 :         Class *clasp;
    1217                 : 
    1218                 :         /*
    1219                 :          * Key with one of three possible values:
    1220                 :          *
    1221                 :          * - Global for the object. The object must have a standard class for
    1222                 :          *   which the global's prototype can be determined, and the object's
    1223                 :          *   parent will be the global.
    1224                 :          *
    1225                 :          * - Prototype for the object (cannot be global). The object's parent
    1226                 :          *   will be the prototype's parent.
    1227                 :          *
    1228                 :          * - Type for the object. The object's parent will be the type's
    1229                 :          *   prototype's parent.
    1230                 :          */
    1231                 :         gc::Cell *key;
    1232                 : 
    1233                 :         /* Allocation kind for the constructed object. */
    1234                 :         gc::AllocKind kind;
    1235                 : 
    1236                 :         /* Number of bytes to copy from the template object. */
    1237                 :         uint32_t nbytes;
    1238                 : 
    1239                 :         /*
    1240                 :          * Template object to copy from, with the initial values of fields,
    1241                 :          * fixed slots (undefined) and private data (NULL).
    1242                 :          */
    1243                 :         JSObject_Slots16 templateObject;
    1244                 :     };
    1245                 : 
    1246                 :     Entry entries[41];
    1247                 : 
    1248                 :     void staticAsserts() {
    1249                 :         JS_STATIC_ASSERT(gc::FINALIZE_OBJECT_LAST == gc::FINALIZE_OBJECT16_BACKGROUND);
    1250                 :     }
    1251                 : 
    1252                 :   public:
    1253                 : 
    1254                 :     typedef int EntryIndex;
    1255                 : 
    1256          124982 :     void reset() { PodZero(this); }
    1257                 : 
    1258                 :     /*
    1259                 :      * Get the entry index for the given lookup, return whether there was a hit
    1260                 :      * on an existing entry.
    1261                 :      */
    1262                 :     inline bool lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry);
    1263                 :     inline bool lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry);
    1264                 :     inline bool lookupType(Class *clasp, js::types::TypeObject *type, gc::AllocKind kind, EntryIndex *pentry);
    1265                 : 
    1266                 :     /* Return a new object from a cache hit produced by a lookup method. */
    1267                 :     inline JSObject *newObjectFromHit(JSContext *cx, EntryIndex entry);
    1268                 : 
    1269                 :     /* Fill an entry after a cache miss. */
    1270                 :     inline void fillProto(EntryIndex entry, Class *clasp, JSObject *proto, gc::AllocKind kind, JSObject *obj);
    1271                 :     inline void fillGlobal(EntryIndex entry, Class *clasp, js::GlobalObject *global, gc::AllocKind kind, JSObject *obj);
    1272                 :     inline void fillType(EntryIndex entry, Class *clasp, js::types::TypeObject *type, gc::AllocKind kind, JSObject *obj);
    1273                 : 
    1274                 :     /* Invalidate any entries which might produce an object with shape/proto. */
    1275                 :     void invalidateEntriesForShape(JSContext *cx, Shape *shape, JSObject *proto);
    1276                 : 
    1277                 :   private:
    1278                 :     inline bool lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry);
    1279                 :     inline void fill(EntryIndex entry, Class *clasp, gc::Cell *key, gc::AllocKind kind, JSObject *obj);
    1280                 :     static inline void copyCachedToObject(JSObject *dst, JSObject *src);
    1281                 : };
    1282                 : 
    1283                 : } /* namespace js */
    1284                 : 
    1285                 : /*
    1286                 :  * Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp.
    1287                 :  */
    1288                 : extern const char js_watch_str[];
    1289                 : extern const char js_unwatch_str[];
    1290                 : extern const char js_hasOwnProperty_str[];
    1291                 : extern const char js_isPrototypeOf_str[];
    1292                 : extern const char js_propertyIsEnumerable_str[];
    1293                 : 
    1294                 : #ifdef OLD_GETTER_SETTER_METHODS
    1295                 : extern const char js_defineGetter_str[];
    1296                 : extern const char js_defineSetter_str[];
    1297                 : extern const char js_lookupGetter_str[];
    1298                 : extern const char js_lookupSetter_str[];
    1299                 : #endif
    1300                 : 
    1301                 : extern JSBool
    1302                 : js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props);
    1303                 : 
    1304                 : /*
    1305                 :  * Fast access to immutable standard objects (constructors and prototypes).
    1306                 :  */
    1307                 : extern JSBool
    1308                 : js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
    1309                 :                   JSObject **objp);
    1310                 : 
    1311                 : /*
    1312                 :  * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is
    1313                 :  * JSProto_Null, clasp must non-null.
    1314                 :  */
    1315                 : extern JSBool
    1316                 : js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey key,
    1317                 :                    js::Value *vp, js::Class *clasp = NULL);
    1318                 : 
    1319                 : // Specialized call for constructing |this| with a known function callee,
    1320                 : // and a known prototype.
    1321                 : extern JSObject *
    1322                 : js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *proto);
    1323                 : 
    1324                 : // Specialized call for constructing |this| with a known function callee.
    1325                 : extern JSObject *
    1326                 : js_CreateThisForFunction(JSContext *cx, JSObject *callee, bool newType);
    1327                 : 
    1328                 : // Generic call for constructing |this|.
    1329                 : extern JSObject *
    1330                 : js_CreateThis(JSContext *cx, js::Class *clasp, JSObject *callee);
    1331                 : 
    1332                 : extern jsid
    1333                 : js_CheckForStringIndex(jsid id);
    1334                 : 
    1335                 : /*
    1336                 :  * Find or create a property named by id in obj's scope, with the given getter
    1337                 :  * and setter, slot, attributes, and other members.
    1338                 :  */
    1339                 : extern js::Shape *
    1340                 : js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
    1341                 :                      JSPropertyOp getter, JSStrictPropertyOp setter, uint32_t slot,
    1342                 :                      unsigned attrs, unsigned flags, int shortid);
    1343                 : 
    1344                 : extern JSBool
    1345                 : js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
    1346                 :                      const js::Value &descriptor, JSBool *bp);
    1347                 : 
    1348                 : namespace js {
    1349                 : 
    1350                 : /*
    1351                 :  * Flags for the defineHow parameter of js_DefineNativeProperty.
    1352                 :  */
    1353                 : const unsigned DNP_CACHE_RESULT = 1;   /* an interpreter call from JSOP_INITPROP */
    1354                 : const unsigned DNP_DONT_PURGE   = 2;   /* suppress js_PurgeScopeChain */
    1355                 : const unsigned DNP_UNQUALIFIED  = 4;   /* Unqualified property set.  Only used in
    1356                 :                                        the defineHow argument of
    1357                 :                                        js_SetPropertyHelper. */
    1358                 : const unsigned DNP_SKIP_TYPE    = 8;   /* Don't update type information */
    1359                 : 
    1360                 : /*
    1361                 :  * Return successfully added or changed shape or NULL on error.
    1362                 :  */
    1363                 : extern const Shape *
    1364                 : DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
    1365                 :                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
    1366                 :                      unsigned flags, int shortid, unsigned defineHow = 0);
    1367                 : 
    1368                 : inline const Shape *
    1369           57810 : DefineNativeProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value &value,
    1370                 :                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
    1371                 :                      unsigned flags, int shortid, unsigned defineHow = 0)
    1372                 : {
    1373           57810 :     return DefineNativeProperty(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs, flags,
    1374           57810 :                                 shortid, defineHow);
    1375                 : }
    1376                 : 
    1377                 : /*
    1378                 :  * Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
    1379                 :  */
    1380                 : extern bool
    1381                 : LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
    1382                 :                         JSObject **objp, JSProperty **propp);
    1383                 : 
    1384                 : inline bool
    1385           31667 : LookupPropertyWithFlags(JSContext *cx, JSObject *obj, PropertyName *name, unsigned flags,
    1386                 :                         JSObject **objp, JSProperty **propp)
    1387                 : {
    1388           31667 :     return LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(name), flags, objp, propp);
    1389                 : }
    1390                 : 
    1391                 : /*
    1392                 :  * Call the [[DefineOwnProperty]] internal method of obj.
    1393                 :  *
    1394                 :  * If obj is an array, this follows ES5 15.4.5.1.
    1395                 :  * If obj is any other native object, this follows ES5 8.12.9.
    1396                 :  * If obj is a proxy, this calls the proxy handler's defineProperty method.
    1397                 :  * Otherwise, this reports an error and returns false.
    1398                 :  */
    1399                 : extern bool
    1400                 : DefineProperty(JSContext *cx, JSObject *obj, const jsid &id, const PropDesc &desc, bool throwError,
    1401                 :                bool *rval);
    1402                 : 
    1403                 : /*
    1404                 :  * Read property descriptors from props, as for Object.defineProperties. See
    1405                 :  * ES5 15.2.3.7 steps 3-5.
    1406                 :  */
    1407                 : extern bool
    1408                 : ReadPropertyDescriptors(JSContext *cx, JSObject *props, bool checkAccessors,
    1409                 :                         AutoIdVector *ids, AutoPropDescArrayRooter *descs);
    1410                 : 
    1411                 : /*
    1412                 :  * Constant to pass to js_LookupPropertyWithFlags to infer bits from current
    1413                 :  * bytecode.
    1414                 :  */
    1415                 : static const unsigned RESOLVE_INFER = 0xffff;
    1416                 : 
    1417                 : /*
    1418                 :  * If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success.
    1419                 :  */
    1420                 : extern bool
    1421                 : FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSObject *scopeChain,
    1422                 :                    JSObject **objp, JSObject **pobjp, JSProperty **propp);
    1423                 : 
    1424                 : /*
    1425                 :  * Search for name either on the current scope chain or on the scope chain's
    1426                 :  * global object, per the global parameter.
    1427                 :  */
    1428                 : extern bool
    1429                 : FindProperty(JSContext *cx, PropertyName *name, JSObject *scopeChain,
    1430                 :              JSObject **objp, JSObject **pobjp, JSProperty **propp);
    1431                 : 
    1432                 : extern JSObject *
    1433                 : FindIdentifierBase(JSContext *cx, JSObject *scopeChain, PropertyName *name);
    1434                 : 
    1435                 : }
    1436                 : 
    1437                 : extern JSObject *
    1438                 : js_FindVariableScope(JSContext *cx, JSFunction **funp);
    1439                 : 
    1440                 : /* JSGET_CACHE_RESULT is the analogue of DNP_CACHE_RESULT for js_GetMethod. */
    1441                 : const unsigned JSGET_CACHE_RESULT = 1; // from a caching interpreter opcode
    1442                 : 
    1443                 : /*
    1444                 :  * NB: js_NativeGet and js_NativeSet are called with the scope containing shape
    1445                 :  * (pobj's scope for Get, obj's for Set) locked, and on successful return, that
    1446                 :  * scope is again locked.  But on failure, both functions return false with the
    1447                 :  * scope containing shape unlocked.
    1448                 :  */
    1449                 : extern JSBool
    1450                 : js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const js::Shape *shape, unsigned getHow,
    1451                 :              js::Value *vp);
    1452                 : 
    1453                 : extern JSBool
    1454                 : js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added,
    1455                 :              bool strict, js::Value *vp);
    1456                 : 
    1457                 : namespace js {
    1458                 : 
    1459                 : bool
    1460                 : GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, Value *vp);
    1461                 : 
    1462                 : inline bool
    1463                 : GetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, uint32_t getHow, Value *vp)
    1464                 : {
    1465                 :     return GetPropertyHelper(cx, obj, ATOM_TO_JSID(name), getHow, vp);
    1466                 : }
    1467                 : 
    1468                 : bool
    1469                 : GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, PropertyDescriptor *desc);
    1470                 : 
    1471                 : bool
    1472                 : GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, Value *vp);
    1473                 : 
    1474                 : bool
    1475                 : NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp);
    1476                 : 
    1477                 : } /* namespace js */
    1478                 : 
    1479                 : extern JSBool
    1480                 : js_GetMethod(JSContext *cx, JSObject *obj, jsid id, unsigned getHow, js::Value *vp);
    1481                 : 
    1482                 : namespace js {
    1483                 : 
    1484                 : inline bool
    1485                 : GetMethod(JSContext *cx, JSObject *obj, PropertyName *name, unsigned getHow, Value *vp)
    1486                 : {
    1487                 :     return js_GetMethod(cx, obj, ATOM_TO_JSID(name), getHow, vp);
    1488                 : }
    1489                 : 
    1490                 : } /* namespace js */
    1491                 : 
    1492                 : namespace js {
    1493                 : 
    1494                 : /*
    1495                 :  * If obj has an already-resolved data property for id, return true and
    1496                 :  * store the property value in *vp. This helper assumes the caller has already
    1497                 :  * called js_CheckForStringIndex.
    1498                 :  */
    1499                 : extern bool
    1500                 : HasDataProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp);
    1501                 : 
    1502                 : inline bool
    1503          733383 : HasDataProperty(JSContext *cx, JSObject *obj, JSAtom *atom, Value *vp)
    1504                 : {
    1505          733383 :     return HasDataProperty(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(atom)), vp);
    1506                 : }
    1507                 : 
    1508                 : extern JSBool
    1509                 : CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
    1510                 :             js::Value *vp, unsigned *attrsp);
    1511                 : 
    1512                 : } /* namespace js */
    1513                 : 
    1514                 : extern bool
    1515                 : js_IsDelegate(JSContext *cx, JSObject *obj, const js::Value &v);
    1516                 : 
    1517                 : /*
    1518                 :  * Wrap boolean, number or string as Boolean, Number or String object.
    1519                 :  * *vp must not be an object, null or undefined.
    1520                 :  */
    1521                 : extern JSBool
    1522                 : js_PrimitiveToObject(JSContext *cx, js::Value *vp);
    1523                 : 
    1524                 : extern JSBool
    1525                 : js_ValueToObjectOrNull(JSContext *cx, const js::Value &v, JSObject **objp);
    1526                 : 
    1527                 : /* Throws if v could not be converted to an object. */
    1528                 : extern JSObject *
    1529                 : js_ValueToNonNullObject(JSContext *cx, const js::Value &v);
    1530                 : 
    1531                 : namespace js {
    1532                 : 
    1533                 : /*
    1534                 :  * Invokes the ES5 ToObject algorithm on *vp, writing back the object to vp.
    1535                 :  * If *vp might already be an object, use ToObject.
    1536                 :  */
    1537                 : extern JSObject *
    1538                 : ToObjectSlow(JSContext *cx, Value *vp);
    1539                 : 
    1540                 : JS_ALWAYS_INLINE JSObject *
    1541        17558947 : ToObject(JSContext *cx, Value *vp)
    1542                 : {
    1543        17558947 :     if (vp->isObject())
    1544        17558637 :         return &vp->toObject();
    1545             310 :     return ToObjectSlow(cx, vp);
    1546                 : }
    1547                 : 
    1548                 : /* As for ToObject, but preserves the original value. */
    1549                 : inline JSObject *
    1550        88302916 : ValueToObject(JSContext *cx, const Value &v)
    1551                 : {
    1552        88302916 :     if (v.isObject())
    1553        87466867 :         return &v.toObject();
    1554          836049 :     return js_ValueToNonNullObject(cx, v);
    1555                 : }
    1556                 : 
    1557                 : } /* namespace js */
    1558                 : 
    1559                 : extern void
    1560                 : js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize);
    1561                 : 
    1562                 : extern bool
    1563                 : js_ClearNative(JSContext *cx, JSObject *obj);
    1564                 : 
    1565                 : extern JSBool
    1566                 : js_ReportGetterOnlyAssignment(JSContext *cx);
    1567                 : 
    1568                 : extern unsigned
    1569                 : js_InferFlags(JSContext *cx, unsigned defaultFlags);
    1570                 : 
    1571                 : /* Object constructor native. Exposed only so the JIT can know its address. */
    1572                 : JSBool
    1573                 : js_Object(JSContext *cx, unsigned argc, js::Value *vp);
    1574                 : 
    1575                 : /*
    1576                 :  * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is
    1577                 :  * JSProto_Null, clasp must non-null.
    1578                 :  *
    1579                 :  * If protoKey is constant and scope is non-null, use GlobalObject's prototype
    1580                 :  * methods instead.
    1581                 :  */
    1582                 : extern JS_FRIEND_API(JSBool)
    1583                 : js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey,
    1584                 :                      JSObject **protop, js::Class *clasp = NULL);
    1585                 : 
    1586                 : namespace js {
    1587                 : 
    1588                 : extern bool
    1589                 : SetProto(JSContext *cx, JSObject *obj, JSObject *proto, bool checkForCycles);
    1590                 : 
    1591                 : extern JSString *
    1592                 : obj_toStringHelper(JSContext *cx, JSObject *obj);
    1593                 : 
    1594                 : extern JSBool
    1595                 : eval(JSContext *cx, unsigned argc, Value *vp);
    1596                 : 
    1597                 : /*
    1598                 :  * Performs a direct eval for the given arguments, which must correspond to the
    1599                 :  * currently-executing stack frame, which must be a script frame. On completion
    1600                 :  * the result is returned in args.rval.
    1601                 :  */
    1602                 : extern bool
    1603                 : DirectEval(JSContext *cx, const CallArgs &args);
    1604                 : 
    1605                 : /*
    1606                 :  * True iff |v| is the built-in eval function for the global object that
    1607                 :  * corresponds to |scopeChain|.
    1608                 :  */
    1609                 : extern bool
    1610                 : IsBuiltinEvalForScope(JSObject *scopeChain, const js::Value &v);
    1611                 : 
    1612                 : /* True iff fun is a built-in eval function. */
    1613                 : extern bool
    1614                 : IsAnyBuiltinEval(JSFunction *fun);
    1615                 : 
    1616                 : /* 'call' should be for the eval/Function native invocation. */
    1617                 : extern JSPrincipals *
    1618                 : PrincipalsForCompiledCode(const CallReceiver &call, JSContext *cx);
    1619                 : 
    1620                 : extern JSObject *
    1621                 : NonNullObject(JSContext *cx, const Value &v);
    1622                 : 
    1623                 : extern const char *
    1624                 : InformalValueTypeName(const Value &v);
    1625                 : 
    1626                 : inline void
    1627                 : DestroyIdArray(FreeOp *fop, JSIdArray *ida);
    1628                 : 
    1629                 : /* Helpers for throwing. These always return false. */
    1630                 : extern bool
    1631                 : Throw(JSContext *cx, jsid id, unsigned errorNumber);
    1632                 : 
    1633                 : extern bool
    1634                 : Throw(JSContext *cx, JSObject *obj, unsigned errorNumber);
    1635                 : 
    1636                 : }  /* namespace js */
    1637                 : 
    1638                 : #endif /* jsobj_h___ */

Generated by: LCOV version 1.7