LCOV - app.info - js/src/jsobjinlines.h

LCOV - code coverage report
| Current view: | directory - js/src - jsobjinlines.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 741 | 664 | 89.6 %
| Date: | 2012-04-07 | Functions: | 193 | 179 | 92.7 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=99:
           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 jsobjinlines_h___
          42                 : #define jsobjinlines_h___
          43                 :
          44                 : #include <new>
          45                 :
          46                 : #include "jsapi.h"
          47                 : #include "jsarray.h"
          48                 : #include "jsbool.h"
          49                 : #include "jscntxt.h"
          50                 : #include "jsdate.h"
          51                 : #include "jsfun.h"
          52                 : #include "jsgcmark.h"
          53                 : #include "jsiter.h"
          54                 : #include "jslock.h"
          55                 : #include "jsnum.h"
          56                 : #include "jsobj.h"
          57                 : #include "jsprobes.h"
          58                 : #include "jspropertytree.h"
          59                 : #include "jsproxy.h"
          60                 : #include "jsscope.h"
          61                 : #include "jsstr.h"
          62                 : #include "jstypedarray.h"
          63                 : #include "jsxml.h"
          64                 : #include "jswrapper.h"
          65                 :
          66                 : #include "gc/Barrier.h"
          67                 : #include "js/TemplateLib.h"
          68                 :
          69                 : #include "vm/BooleanObject.h"
          70                 : #include "vm/GlobalObject.h"
          71                 : #include "vm/NumberObject.h"
          72                 : #include "vm/RegExpStatics.h"
          73                 : #include "vm/StringObject.h"
          74                 :
          75                 : #include "jsatominlines.h"
          76                 : #include "jsfuninlines.h"
          77                 : #include "jsgcinlines.h"
          78                 : #include "jsinferinlines.h"
          79                 : #include "jsscopeinlines.h"
          80                 : #include "jsscriptinlines.h"
          81                 :
          82                 : #include "gc/Barrier-inl.h"
          83                 :
          84                 : #include "vm/ObjectImpl-inl.h"
          85                 : #include "vm/RegExpStatics-inl.h"
          86                 : #include "vm/String-inl.h"
          87                 :
          88                 : inline bool
          89        38700612 : JSObject::enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp)
          90                 : {
          91        38700612 :     JSNewEnumerateOp op = getOps()->enumerate;
          92        38700612 :     return (op ? op : JS_EnumerateState)(cx, this, iterop, statep, idp);
          93                 : }
          94                 :
          95                 : inline bool
          96          892635 : JSObject::defaultValue(JSContext *cx, JSType hint, js::Value *vp)
          97                 : {
          98          892635 :     JSConvertOp op = getClass()->convert;
          99          892635 :     bool ok = (op == JS_ConvertStub ? js::DefaultValue : op)(cx, this, hint, vp);
         100          892635 :     JS_ASSERT_IF(ok, vp->isPrimitive());
         101          892635 :     return ok;
         102                 : }
         103                 :
         104                 : inline JSType
         105           28137 : JSObject::typeOf(JSContext *cx)
         106                 : {
         107           28137 :     js::TypeOfOp op = getOps()->typeOf;
         108           28137 :     return (op ? op : js_TypeOf)(cx, this);
         109                 : }
         110                 :
         111                 : inline JSObject *
         112         1620169 : JSObject::thisObject(JSContext *cx)
         113                 : {
         114         1620169 :     JSObjectOp op = getOps()->thisObject;
         115         1620169 :     return op ? op(cx, this) : this;
         116                 : }
         117                 :
         118                 : inline JSBool
         119         2812112 : JSObject::setGeneric(JSContext *cx, jsid id, js::Value *vp, JSBool strict)
         120                 : {
         121         2812112 :     if (getOps()->setGeneric)
         122         1761478 :         return nonNativeSetProperty(cx, id, vp, strict);
         123         1050634 :     return js_SetPropertyHelper(cx, this, id, 0, vp, strict);
         124                 : }
         125                 :
         126                 : inline JSBool
         127           14138 : JSObject::setProperty(JSContext *cx, js::PropertyName *name, js::Value *vp, JSBool strict)
         128                 : {
         129           14138 :     return setGeneric(cx, ATOM_TO_JSID(name), vp, strict);
         130                 : }
         131                 :
         132                 : inline JSBool
         133           22239 : JSObject::setElement(JSContext *cx, uint32_t index, js::Value *vp, JSBool strict)
         134                 : {
         135           22239 :     if (getOps()->setElement)
         136           22238 :         return nonNativeSetElement(cx, index, vp, strict);
         137               1 :     return js_SetElementHelper(cx, this, index, 0, vp, strict);
         138                 : }
         139                 :
         140                 : inline JSBool
         141               0 : JSObject::setSpecial(JSContext *cx, js::SpecialId sid, js::Value *vp, JSBool strict)
         142                 : {
         143               0 :     return setGeneric(cx, SPECIALID_TO_JSID(sid), vp, strict);
         144                 : }
         145                 :
         146                 : inline JSBool
         147           31914 : JSObject::setGenericAttributes(JSContext *cx, jsid id, unsigned *attrsp)
         148                 : {
         149           31914 :     js::types::MarkTypePropertyConfigured(cx, this, id);
         150           31914 :     js::GenericAttributesOp op = getOps()->setGenericAttributes;
         151           31914 :     return (op ? op : js_SetAttributes)(cx, this, id, attrsp);
         152                 : }
         153                 :
         154                 : inline JSBool
         155               0 : JSObject::setPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
         156                 : {
         157               0 :     return setGenericAttributes(cx, ATOM_TO_JSID(name), attrsp);
         158                 : }
         159                 :
         160                 : inline JSBool
         161               0 : JSObject::setElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp)
         162                 : {
         163               0 :     js::ElementAttributesOp op = getOps()->setElementAttributes;
         164               0 :     return (op ? op : js_SetElementAttributes)(cx, this, index, attrsp);
         165                 : }
         166                 :
         167                 : inline JSBool
         168               0 : JSObject::setSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp)
         169                 : {
         170               0 :     return setGenericAttributes(cx, SPECIALID_TO_JSID(sid), attrsp);
         171                 : }
         172                 :
         173                 : inline bool
         174           31914 : JSObject::changePropertyAttributes(JSContext *cx, js::Shape *shape, unsigned attrs)
         175                 : {
         176           31914 :     return !!changeProperty(cx, shape, attrs, 0, shape->getter(), shape->setter());
         177                 : }
         178                 :
         179                 : inline JSBool
         180        21028366 : JSObject::getGeneric(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp)
         181                 : {
         182        21028366 :     js::GenericIdOp op = getOps()->getGeneric;
         183        21028366 :     if (op) {
         184         2282341 :         if (!op(cx, this, receiver, id, vp))
         185              18 :             return false;
         186                 :     } else {
         187        18746025 :         if (!js_GetProperty(cx, this, receiver, id, vp))
         188              54 :             return false;
         189                 :     }
         190        21028294 :     return true;
         191                 : }
         192                 :
         193                 : inline JSBool
         194         2379523 : JSObject::getProperty(JSContext *cx, JSObject *receiver, js::PropertyName *name, js::Value *vp)
         195                 : {
         196         2379523 :     return getGeneric(cx, receiver, ATOM_TO_JSID(name), vp);
         197                 : }
         198                 :
         199                 : inline JSBool
         200        17624106 : JSObject::getGeneric(JSContext *cx, jsid id, js::Value *vp)
         201                 : {
         202        17624106 :     return getGeneric(cx, this, id, vp);
         203                 : }
         204                 :
         205                 : inline JSBool
         206         2850927 : JSObject::getProperty(JSContext *cx, js::PropertyName *name, js::Value *vp)
         207                 : {
         208         2850927 :     return getGeneric(cx, ATOM_TO_JSID(name), vp);
         209                 : }
         210                 :
         211                 : inline bool
         212            1548 : JSObject::deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, bool strict)
         213                 : {
         214            1548 :     jsid id = js_CheckForStringIndex(ATOM_TO_JSID(name));
         215            1548 :     js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
         216            1548 :     js::types::MarkTypePropertyConfigured(cx, this, id);
         217            1548 :     js::DeletePropertyOp op = getOps()->deleteProperty;
         218            1548 :     return (op ? op : js_DeleteProperty)(cx, this, name, rval, strict);
         219                 : }
         220                 :
         221                 : inline bool
         222          195138 : JSObject::deleteElement(JSContext *cx, uint32_t index, js::Value *rval, bool strict)
         223                 : {
         224                 :     jsid id;
         225          195138 :     if (!js::IndexToId(cx, index, &id))
         226               0 :         return false;
         227          195138 :     js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
         228          195138 :     js::types::MarkTypePropertyConfigured(cx, this, id);
         229          195138 :     js::DeleteElementOp op = getOps()->deleteElement;
         230          195138 :     return (op ? op : js_DeleteElement)(cx, this, index, rval, strict);
         231                 : }
         232                 :
         233                 : inline bool
         234               0 : JSObject::deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, bool strict)
         235                 : {
         236               0 :     jsid id = SPECIALID_TO_JSID(sid);
         237               0 :     js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
         238               0 :     js::types::MarkTypePropertyConfigured(cx, this, id);
         239               0 :     js::DeleteSpecialOp op = getOps()->deleteSpecial;
         240               0 :     return (op ? op : js_DeleteSpecial)(cx, this, sid, rval, strict);
         241                 : }
         242                 :
         243                 : inline void
         244        30978300 : JSObject::finalize(js::FreeOp *fop)
         245                 : {
         246        30978300 :     js::Probes::finalizeObject(this);
         247                 :
         248        30978300 :     if (!fop->onBackgroundThread()) {
         249                 :         /*
         250                 :          * Finalize obj first, in case it needs map and slots. Objects with
         251                 :          * finalize hooks are not finalized in the background, as the class is
         252                 :          * stored in the object's shape, which may have already been destroyed.
         253                 :          */
         254        30444269 :         js::Class *clasp = getClass();
         255        30444269 :         if (clasp->finalize)
         256         1831884 :             clasp->finalize(fop, this);
         257                 :     }
         258                 :
         259        30978300 :     finish(fop);
         260        30978300 : }
         261                 :
         262                 : inline JSObject *
         263      1043233097 : JSObject::getParent() const
         264                 : {
         265      1043233097 :     return lastProperty()->getObjectParent();
         266                 : }
         267                 :
         268                 : inline JSObject *
         269         1989979 : JSObject::enclosingScope()
         270                 : {
         271         1989979 :     return isScope() ? &asScope().enclosingScope() : getParent();
         272                 : }
         273                 :
         274                 : inline bool
         275           67617 : JSObject::isFixedSlot(size_t slot)
         276                 : {
         277           67617 :     JS_ASSERT(!isDenseArray());
         278           67617 :     return slot < numFixedSlots();
         279                 : }
         280                 :
         281                 : inline size_t
         282          229294 : JSObject::dynamicSlotIndex(size_t slot)
         283                 : {
         284          229294 :     JS_ASSERT(!isDenseArray() && slot >= numFixedSlots());
         285          229294 :     return slot - numFixedSlots();
         286                 : }
         287                 :
         288                 : inline void
         289           12034 : JSObject::setLastPropertyInfallible(const js::Shape *shape)
         290                 : {
         291           12034 :     JS_ASSERT(!shape->inDictionary());
         292           12034 :     JS_ASSERT(shape->compartment() == compartment());
         293           12034 :     JS_ASSERT(!inDictionaryMode());
         294           12034 :     JS_ASSERT(slotSpan() == shape->slotSpan());
         295           12034 :     JS_ASSERT(numFixedSlots() == shape->numFixedSlots());
         296                 :
         297           12034 :     shape_ = const_cast<js::Shape *>(shape);
         298           12034 : }
         299                 :
         300                 : inline void
         301            1224 : JSObject::removeLastProperty(JSContext *cx)
         302                 : {
         303            1224 :     JS_ASSERT(canRemoveLastProperty());
         304            1224 :     JS_ALWAYS_TRUE(setLastProperty(cx, lastProperty()->previous()));
         305            1224 : }
         306                 :
         307                 : inline bool
         308            2457 : JSObject::canRemoveLastProperty()
         309                 : {
         310                 :     /*
         311                 :      * Check that the information about the object stored in the last
         312                 :      * property's base shape is consistent with that stored in the previous
         313                 :      * shape. If not consistent, then the last property cannot be removed as it
         314                 :      * will induce a change in the object itself, and the object must be
         315                 :      * converted to dictionary mode instead. See BaseShape comment in jsscope.h
         316                 :      */
         317            2457 :     JS_ASSERT(!inDictionaryMode());
         318            2457 :     const js::Shape *previous = lastProperty()->previous();
         319            2457 :     return previous->getObjectParent() == lastProperty()->getObjectParent()
         320            2457 :         && previous->getObjectFlags() == lastProperty()->getObjectFlags();
         321                 : }
         322                 :
         323                 : inline const js::HeapSlot *
         324          182670 : JSObject::getRawSlots()
         325                 : {
         326          182670 :     JS_ASSERT(isGlobal());
         327          182670 :     return slots;
         328                 : }
         329                 :
         330                 : inline const js::Value &
         331        24636283 : JSObject::getReservedSlot(unsigned index) const
         332                 : {
         333        24636283 :     JS_ASSERT(index < JSSLOT_FREE(getClass()));
         334        24636283 :     return getSlot(index);
         335                 : }
         336                 :
         337                 : inline js::HeapSlot &
         338          146957 : JSObject::getReservedSlotRef(unsigned index)
         339                 : {
         340          146957 :     JS_ASSERT(index < JSSLOT_FREE(getClass()));
         341          146957 :     return getSlotRef(index);
         342                 : }
         343                 :
         344                 : inline void
         345         6111062 : JSObject::setReservedSlot(unsigned index, const js::Value &v)
         346                 : {
         347         6111062 :     JS_ASSERT(index < JSSLOT_FREE(getClass()));
         348         6111062 :     setSlot(index, v);
         349         6111062 : }
         350                 :
         351                 : inline void
         352          100595 : JSObject::initReservedSlot(unsigned index, const js::Value &v)
         353                 : {
         354          100595 :     JS_ASSERT(index < JSSLOT_FREE(getClass()));
         355          100595 :     initSlot(index, v);
         356          100595 : }
         357                 :
         358                 : inline void
         359             450 : JSObject::prepareSlotRangeForOverwrite(size_t start, size_t end)
         360                 : {
         361             900 :     for (size_t i = start; i < end; i++)
         362             450 :         getSlotAddressUnchecked(i)->js::HeapSlot::~HeapSlot();
         363             450 : }
         364                 :
         365                 : inline void
         366          558739 : JSObject::prepareElementRangeForOverwrite(size_t start, size_t end)
         367                 : {
         368          558739 :     JS_ASSERT(isDenseArray());
         369          558739 :     JS_ASSERT(end <= getDenseArrayInitializedLength());
         370          628087 :     for (size_t i = start; i < end; i++)
         371           69348 :         elements[i].js::HeapSlot::~HeapSlot();
         372          558739 : }
         373                 :
         374                 : inline uint32_t
         375        41919127 : JSObject::getArrayLength() const
         376                 : {
         377        41919127 :     JS_ASSERT(isArray());
         378        41919127 :     return getElementsHeader()->length;
         379                 : }
         380                 :
         381                 : inline void
         382         3410042 : JSObject::setArrayLength(JSContext *cx, uint32_t length)
         383                 : {
         384         3410042 :     JS_ASSERT(isArray());
         385                 :
         386         3410042 :     if (length > INT32_MAX) {
         387                 :         /*
         388                 :          * Mark the type of this object as possibly not a dense array, per the
         389                 :          * requirements of OBJECT_FLAG_NON_DENSE_ARRAY.
         390                 :          */
         391                 :         js::types::MarkTypeObjectFlags(cx, this,
         392                 :                                        js::types::OBJECT_FLAG_NON_PACKED_ARRAY |
         393              36 :                                        js::types::OBJECT_FLAG_NON_DENSE_ARRAY);
         394              36 :         jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
         395                 :         js::types::AddTypePropertyId(cx, this, lengthId,
         396              36 :                                      js::types::Type::DoubleType());
         397                 :     }
         398                 :
         399         3410042 :     getElementsHeader()->length = length;
         400         3410042 : }
         401                 :
         402                 : inline void
         403         6105891 : JSObject::setDenseArrayLength(uint32_t length)
         404                 : {
         405                 :     /* Variant of setArrayLength for use on dense arrays where the length cannot overflow int32. */
         406         6105891 :     JS_ASSERT(isDenseArray());
         407         6105891 :     JS_ASSERT(length <= INT32_MAX);
         408         6105891 :     getElementsHeader()->length = length;
         409         6105891 : }
         410                 :
         411                 : inline void
         412          558739 : JSObject::setDenseArrayInitializedLength(uint32_t length)
         413                 : {
         414          558739 :     JS_ASSERT(isDenseArray());
         415          558739 :     JS_ASSERT(length <= getDenseArrayCapacity());
         416          558739 :     prepareElementRangeForOverwrite(length, getElementsHeader()->initializedLength);
         417          558739 :     getElementsHeader()->initializedLength = length;
         418          558739 : }
         419                 :
         420                 : inline uint32_t
         421        31303295 : JSObject::getDenseArrayCapacity()
         422                 : {
         423        31303295 :     JS_ASSERT(isDenseArray());
         424        31303295 :     return getElementsHeader()->capacity;
         425                 : }
         426                 :
         427                 : inline bool
         428         2593552 : JSObject::ensureElements(JSContext *cx, uint32_t capacity)
         429                 : {
         430         2593552 :     if (capacity > getDenseArrayCapacity())
         431           24751 :         return growElements(cx, capacity);
         432         2568801 :     return true;
         433                 : }
         434                 :
         435                 : inline void
         436        23073278 : JSObject::setDenseArrayElement(unsigned idx, const js::Value &val)
         437                 : {
         438        23073278 :     JS_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
         439        23073278 :     elements[idx].set(this, idx, val);
         440        23073278 : }
         441                 :
         442                 : inline void
         443          487065 : JSObject::initDenseArrayElement(unsigned idx, const js::Value &val)
         444                 : {
         445          487065 :     JS_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
         446          487065 :     elements[idx].init(this, idx, val);
         447          487065 : }
         448                 :
         449                 : inline void
         450        23025481 : JSObject::setDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val)
         451                 : {
         452        23025481 :     js::types::AddTypePropertyId(cx, this, JSID_VOID, val);
         453        23025481 :     setDenseArrayElement(idx, val);
         454        23025481 : }
         455                 :
         456                 : inline void
         457          487065 : JSObject::initDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val)
         458                 : {
         459          487065 :     js::types::AddTypePropertyId(cx, this, JSID_VOID, val);
         460          487065 :     initDenseArrayElement(idx, val);
         461          487065 : }
         462                 :
         463                 : inline void
         464           42995 : JSObject::copyDenseArrayElements(unsigned dstStart, const js::Value *src, unsigned count)
         465                 : {
         466           42995 :     JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
         467           42995 :     JSCompartment *comp = compartment();
         468          181196 :     for (unsigned i = 0; i < count; ++i)
         469          138201 :         elements[dstStart + i].set(comp, this, dstStart + i, src[i]);
         470           42995 : }
         471                 :
         472                 : inline void
         473           43384 : JSObject::initDenseArrayElements(unsigned dstStart, const js::Value *src, unsigned count)
         474                 : {
         475           43384 :     JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
         476           43384 :     JSCompartment *comp = compartment();
         477          345103 :     for (unsigned i = 0; i < count; ++i)
         478          301719 :         elements[dstStart + i].init(comp, this, dstStart + i, src[i]);
         479           43384 : }
         480                 :
         481                 : inline void
         482            1386 : JSObject::moveDenseArrayElements(unsigned dstStart, unsigned srcStart, unsigned count)
         483                 : {
         484            1386 :     JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
         485            1386 :     JS_ASSERT(srcStart + count <= getDenseArrayInitializedLength());
         486                 :
         487                 :     /*
         488                 :      * Using memmove here would skip write barriers. Also, we need to consider
         489                 :      * an array containing [A, B, C], in the following situation:
         490                 :      *
         491                 :      * 1. Incremental GC marks slot 0 of array (i.e., A), then returns to JS code.
         492                 :      * 2. JS code moves slots 1..2 into slots 0..1, so it contains [B, C, C].
         493                 :      * 3. Incremental GC finishes by marking slots 1 and 2 (i.e., C).
         494                 :      *
         495                 :      * Since normal marking never happens on B, it is very important that the
         496                 :      * write barrier is invoked here on B, despite the fact that it exists in
         497                 :      * the array before and after the move.
         498                 :     */
         499            1386 :     JSCompartment *comp = compartment();
         500            1386 :     if (comp->needsBarrier()) {
         501              23 :         if (dstStart < srcStart) {
         502              23 :             js::HeapSlot *dst = elements + dstStart;
         503              23 :             js::HeapSlot *src = elements + srcStart;
         504              30 :             for (unsigned i = 0; i < count; i++, dst++, src++)
         505               7 :                 dst->set(comp, this, dst - elements, *src);
         506                 :         } else {
         507               0 :             js::HeapSlot *dst = elements + dstStart + count - 1;
         508               0 :             js::HeapSlot *src = elements + srcStart + count - 1;
         509               0 :             for (unsigned i = 0; i < count; i++, dst--, src--)
         510               0 :                 dst->set(comp, this, dst - elements, *src);
         511                 :         }
         512                 :     } else {
         513            1363 :         memmove(elements + dstStart, elements + srcStart, count * sizeof(js::HeapSlot));
         514            1363 :         SlotRangeWriteBarrierPost(comp, this, dstStart, count);
         515                 :     }
         516            1386 : }
         517                 :
         518                 : inline void
         519              66 : JSObject::moveDenseArrayElementsUnbarriered(unsigned dstStart, unsigned srcStart, unsigned count)
         520                 : {
         521              66 :     JS_ASSERT(!compartment()->needsBarrier());
         522                 :
         523              66 :     JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
         524              66 :     JS_ASSERT(srcStart + count <= getDenseArrayCapacity());
         525                 :
         526              66 :     memmove(elements + dstStart, elements + srcStart, count * sizeof(js::Value));
         527              66 : }
         528                 :
         529                 : inline bool
         530                 : JSObject::denseArrayHasInlineSlots() const
         531                 : {
         532                 :     JS_ASSERT(isDenseArray());
         533                 :     return elements == fixedElements();
         534                 : }
         535                 :
         536                 : namespace js {
         537                 :
         538                 : /*
         539                 :  * Any name atom for a function which will be added as a DeclEnv object to the
         540                 :  * scope chain above call objects for fun.
         541                 :  */
         542                 : static inline JSAtom *
         543          782484 : CallObjectLambdaName(JSFunction *fun)
         544                 : {
         545          782484 :     return (fun->flags & JSFUN_LAMBDA) ? fun->atom.get() : NULL;
         546                 : }
         547                 :
         548                 : } /* namespace js */
         549                 :
         550                 : inline const js::Value &
         551           91305 : JSObject::getDateUTCTime() const
         552                 : {
         553           91305 :     JS_ASSERT(isDate());
         554           91305 :     return getFixedSlot(JSSLOT_DATE_UTC_TIME);
         555                 : }
         556                 :
         557                 : inline void
         558           52158 : JSObject::setDateUTCTime(const js::Value &time)
         559                 : {
         560           52158 :     JS_ASSERT(isDate());
         561           52158 :     setFixedSlot(JSSLOT_DATE_UTC_TIME, time);
         562           52158 : }
         563                 :
         564                 : inline js::NativeIterator *
         565        31206563 : JSObject::getNativeIterator() const
         566                 : {
         567        31206563 :     return (js::NativeIterator *) getPrivate();
         568                 : }
         569                 :
         570                 : inline void
         571          397137 : JSObject::setNativeIterator(js::NativeIterator *ni)
         572                 : {
         573          397137 :     setPrivate(ni);
         574          397137 : }
         575                 :
         576                 : inline JSLinearString *
         577         4732751 : JSObject::getNamePrefix() const
         578                 : {
         579         4732751 :     JS_ASSERT(isNamespace() || isQName());
         580         4732751 :     const js::Value &v = getSlot(JSSLOT_NAME_PREFIX);
         581         4732751 :     return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
         582                 : }
         583                 :
         584                 : inline jsval
         585         4735284 : JSObject::getNamePrefixVal() const
         586                 : {
         587         4735284 :     JS_ASSERT(isNamespace() || isQName());
         588         4735284 :     return getSlot(JSSLOT_NAME_PREFIX);
         589                 : }
         590                 :
         591                 : inline void
         592         4735783 : JSObject::setNamePrefix(JSLinearString *prefix)
         593                 : {
         594         4735783 :     JS_ASSERT(isNamespace() || isQName());
         595         4735783 :     setSlot(JSSLOT_NAME_PREFIX, prefix ? js::StringValue(prefix) : js::UndefinedValue());
         596         4735783 : }
         597                 :
         598                 : inline void
         599               0 : JSObject::clearNamePrefix()
         600                 : {
         601               0 :     JS_ASSERT(isNamespace() || isQName());
         602               0 :     setSlot(JSSLOT_NAME_PREFIX, js::UndefinedValue());
         603               0 : }
         604                 :
         605                 : inline JSLinearString *
         606         4746261 : JSObject::getNameURI() const
         607                 : {
         608         4746261 :     JS_ASSERT(isNamespace() || isQName());
         609         4746261 :     const js::Value &v = getSlot(JSSLOT_NAME_URI);
         610         4746261 :     return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
         611                 : }
         612                 :
         613                 : inline jsval
         614         4735284 : JSObject::getNameURIVal() const
         615                 : {
         616         4735284 :     JS_ASSERT(isNamespace() || isQName());
         617         4735284 :     return getSlot(JSSLOT_NAME_URI);
         618                 : }
         619                 :
         620                 : inline void
         621         4735810 : JSObject::setNameURI(JSLinearString *uri)
         622                 : {
         623         4735810 :     JS_ASSERT(isNamespace() || isQName());
         624         4735810 :     setSlot(JSSLOT_NAME_URI, uri ? js::StringValue(uri) : js::UndefinedValue());
         625         4735810 : }
         626                 :
         627                 : inline jsval
         628         4720258 : JSObject::getNamespaceDeclared() const
         629                 : {
         630         4720258 :     JS_ASSERT(isNamespace());
         631         4720258 :     return getSlot(JSSLOT_NAMESPACE_DECLARED);
         632                 : }
         633                 :
         634                 : inline void
         635            2009 : JSObject::setNamespaceDeclared(jsval decl)
         636                 : {
         637            2009 :     JS_ASSERT(isNamespace());
         638            2009 :     setSlot(JSSLOT_NAMESPACE_DECLARED, decl);
         639            2009 : }
         640                 :
         641                 : inline JSAtom *
         642         2362923 : JSObject::getQNameLocalName() const
         643                 : {
         644         2362923 :     JS_ASSERT(isQName());
         645         2362923 :     const js::Value &v = getSlot(JSSLOT_QNAME_LOCAL_NAME);
         646         2362923 :     return !v.isUndefined() ? &v.toString()->asAtom() : NULL;
         647                 : }
         648                 :
         649                 : inline jsval
         650         2374457 : JSObject::getQNameLocalNameVal() const
         651                 : {
         652         2374457 :     JS_ASSERT(isQName());
         653         2374457 :     return getSlot(JSSLOT_QNAME_LOCAL_NAME);
         654                 : }
         655                 :
         656                 : inline void
         657         2374457 : JSObject::setQNameLocalName(JSAtom *name)
         658                 : {
         659         2374457 :     JS_ASSERT(isQName());
         660         2374457 :     setSlot(JSSLOT_QNAME_LOCAL_NAME, name ? js::StringValue(name) : js::UndefinedValue());
         661         2374457 : }
         662                 :
         663                 : inline bool
         664         7343372 : JSObject::setSingletonType(JSContext *cx)
         665                 : {
         666         7343372 :     if (!cx->typeInferenceEnabled())
         667         3262284 :         return true;
         668                 :
         669         4081088 :     JS_ASSERT(!hasLazyType());
         670         4081088 :     JS_ASSERT_IF(getProto(), type() == getProto()->getNewType(cx, NULL));
         671                 :
         672         4081088 :     js::types::TypeObject *type = cx->compartment->getLazyType(cx, getProto());
         673         4081088 :     if (!type)
         674               0 :         return false;
         675                 :
         676         4081088 :     type_ = type;
         677         4081088 :     return true;
         678                 : }
         679                 :
         680                 : inline js::types::TypeObject *
         681         1234446 : JSObject::getType(JSContext *cx)
         682                 : {
         683         1234446 :     if (hasLazyType())
         684           51868 :         makeLazyType(cx);
         685         1234446 :     return type_;
         686                 : }
         687                 :
         688                 : inline bool
         689            3003 : JSObject::clearType(JSContext *cx)
         690                 : {
         691            3003 :     JS_ASSERT(!hasSingletonType());
         692                 :
         693            3003 :     js::types::TypeObject *type = cx->compartment->getEmptyType(cx);
         694            3003 :     if (!type)
         695               0 :         return false;
         696                 :
         697            3003 :     type_ = type;
         698            3003 :     return true;
         699                 : }
         700                 :
         701                 : inline void
         702         4806628 : JSObject::setType(js::types::TypeObject *newType)
         703                 : {
         704                 : #ifdef DEBUG
         705         4806628 :     JS_ASSERT(newType);
         706        12351999 :     for (JSObject *obj = newType->proto; obj; obj = obj->getProto())
         707         7545371 :         JS_ASSERT(obj != this);
         708                 : #endif
         709         4806628 :     JS_ASSERT_IF(hasSpecialEquality(),
         710         4806628 :                  newType->hasAnyFlags(js::types::OBJECT_FLAG_SPECIAL_EQUALITY));
         711         4806628 :     JS_ASSERT(!hasSingletonType());
         712         4806628 :     type_ = newType;
         713         4806628 : }
         714                 :
         715           80355 : inline bool JSObject::setIteratedSingleton(JSContext *cx)
         716                 : {
         717           80355 :     return setFlag(cx, js::BaseShape::ITERATED_SINGLETON);
         718                 : }
         719                 :
         720               0 : inline bool JSObject::isSystem() const
         721                 : {
         722               0 :     return lastProperty()->hasObjectFlag(js::BaseShape::SYSTEM);
         723                 : }
         724                 :
         725               0 : inline bool JSObject::setSystem(JSContext *cx)
         726                 : {
         727               0 :     return setFlag(cx, js::BaseShape::SYSTEM);
         728                 : }
         729                 :
         730         1022851 : inline bool JSObject::setDelegate(JSContext *cx)
         731                 : {
         732         1022851 :     return setFlag(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);
         733                 : }
         734                 :
         735          201842 : inline bool JSObject::isVarObj() const
         736                 : {
         737          201842 :     return lastProperty()->hasObjectFlag(js::BaseShape::VAROBJ);
         738                 : }
         739                 :
         740           81043 : inline bool JSObject::setVarObj(JSContext *cx)
         741                 : {
         742           81043 :     return setFlag(cx, js::BaseShape::VAROBJ);
         743                 : }
         744                 :
         745            3672 : inline bool JSObject::setWatched(JSContext *cx)
         746                 : {
         747            3672 :     return setFlag(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
         748                 : }
         749                 :
         750          812081 : inline bool JSObject::hasUncacheableProto() const
         751                 : {
         752          812081 :     return lastProperty()->hasObjectFlag(js::BaseShape::UNCACHEABLE_PROTO);
         753                 : }
         754                 :
         755           31940 : inline bool JSObject::setUncacheableProto(JSContext *cx)
         756                 : {
         757           31940 :     return setFlag(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE);
         758                 : }
         759                 :
         760         1786707 : inline bool JSObject::isBoundFunction() const
         761                 : {
         762         1786707 :     return lastProperty()->hasObjectFlag(js::BaseShape::BOUND_FUNCTION);
         763                 : }
         764                 :
         765         4009507 : inline bool JSObject::isIndexed() const
         766                 : {
         767         4009507 :     return lastProperty()->hasObjectFlag(js::BaseShape::INDEXED);
         768                 : }
         769                 :
         770         4656027 : inline bool JSObject::watched() const
         771                 : {
         772         4656027 :     return lastProperty()->hasObjectFlag(js::BaseShape::WATCHED);
         773                 : }
         774                 :
         775         4919641 : inline bool JSObject::hasSpecialEquality() const
         776                 : {
         777         4919641 :     return !!getClass()->ext.equality;
         778                 : }
         779                 :
         780        23117301 : inline bool JSObject::isArguments() const { return isNormalArguments() || isStrictArguments(); }
         781           20627 : inline bool JSObject::isArrayBuffer() const { return hasClass(&js::ArrayBufferClass); }
         782        31128734 : inline bool JSObject::isBlock() const { return hasClass(&js::BlockClass); }
         783            6955 : inline bool JSObject::isBoolean() const { return hasClass(&js::BooleanClass); }
         784        29586770 : inline bool JSObject::isCall() const { return hasClass(&js::CallClass); }
         785            8717 : inline bool JSObject::isClonedBlock() const { return isBlock() && !!getProto(); }
         786          760155 : inline bool JSObject::isDate() const { return hasClass(&js::DateClass); }
         787        10472065 : inline bool JSObject::isDeclEnv() const { return hasClass(&js::DeclEnvClass); }
         788           25151 : inline bool JSObject::isElementIterator() const { return hasClass(&js::ElementIteratorClass); }
         789          113459 : inline bool JSObject::isError() const { return hasClass(&js::ErrorClass); }
         790       207372408 : inline bool JSObject::isFunction() const { return hasClass(&js::FunctionClass); }
         791                 : inline bool JSObject::isFunctionProxy() const { return hasClass(&js::FunctionProxyClass); }
         792            7510 : inline bool JSObject::isGenerator() const { return hasClass(&js::GeneratorClass); }
         793        31192408 : inline bool JSObject::isIterator() const { return hasClass(&js::IteratorClass); }
         794        33143440 : inline bool JSObject::isNamespace() const { return hasClass(&js::NamespaceClass); }
         795        10156139 : inline bool JSObject::isNestedScope() const { return isBlock() || isWith(); }
         796        23491953 : inline bool JSObject::isNormalArguments() const { return hasClass(&js::NormalArgumentsObjectClass); }
         797          160596 : inline bool JSObject::isNumber() const { return hasClass(&js::NumberClass); }
         798         2077309 : inline bool JSObject::isObject() const { return hasClass(&js::ObjectClass); }
         799                 : inline bool JSObject::isPrimitive() const { return isNumber() || isString() || isBoolean(); }
         800         3491324 : inline bool JSObject::isRegExp() const { return hasClass(&js::RegExpClass); }
         801                 : inline bool JSObject::isRegExpStatics() const { return hasClass(&js::RegExpStaticsClass); }
         802        15894602 : inline bool JSObject::isScope() const { return isCall() || isDeclEnv() || isNestedScope(); }
         803         3175370 : inline bool JSObject::isStaticBlock() const { return isBlock() && !getProto(); }
         804          197561 : inline bool JSObject::isStopIteration() const { return hasClass(&js::StopIterationClass); }
         805        21761582 : inline bool JSObject::isStrictArguments() const { return hasClass(&js::StrictArgumentsObjectClass); }
         806         1259051 : inline bool JSObject::isString() const { return hasClass(&js::StringClass); }
         807               0 : inline bool JSObject::isTypedArray() const { return IsFastTypedArrayClass(getClass()); }
         808            1463 : inline bool JSObject::isWeakMap() const { return hasClass(&js::WeakMapClass); }
         809        27346180 : inline bool JSObject::isWith() const { return hasClass(&js::WithClass); }
         810         6161199 : inline bool JSObject::isXML() const { return hasClass(&js::XMLClass); }
         811                 :
         812                 : inline bool
         813              72 : JSObject::isXMLId() const
         814                 : {
         815              72 :     return hasClass(&js::QNameClass)
         816              36 :         || hasClass(&js::AttributeNameClass)
         817             108 :         || hasClass(&js::AnyNameClass);
         818                 : }
         819                 :
         820                 : inline bool
         821        23715503 : JSObject::isQName() const
         822                 : {
         823        23715503 :     return hasClass(&js::QNameClass)
         824            1179 :         || hasClass(&js::AttributeNameClass)
         825        23716682 :         || hasClass(&js::AnyNameClass);
         826                 : }
         827                 :
         828                 : /* static */ inline JSObject *
         829         6560997 : JSObject::create(JSContext *cx, js::gc::AllocKind kind,
         830                 :                  js::HandleShape shape, js::HandleTypeObject type, js::HeapSlot *slots)
         831                 : {
         832                 :     /*
         833                 :      * Callers must use dynamicSlotsCount to size the initial slot array of the
         834                 :      * object. We can't check the allocated capacity of the dynamic slots, but
         835                 :      * make sure their presence is consistent with the shape.
         836                 :      */
         837         6560997 :     JS_ASSERT(shape && type);
         838         6560997 :     JS_ASSERT(!!dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan()) == !!slots);
         839         6560997 :     JS_ASSERT(js::gc::GetGCKindSlots(kind, shape->getObjectClass()) == shape->numFixedSlots());
         840                 :
         841         6560997 :     JSObject *obj = js_NewGCObject(cx, kind);
         842         6560997 :     if (!obj)
         843               0 :         return NULL;
         844                 :
         845         6560997 :     obj->shape_.init(shape);
         846         6560997 :     obj->type_.init(type);
         847         6560997 :     obj->slots = slots;
         848         6560997 :     obj->elements = js::emptyObjectElements;
         849                 :
         850         6560997 :     if (shape->getObjectClass()->hasPrivate())
         851         1572307 :         obj->privateRef(shape->numFixedSlots()) = NULL;
         852                 :
         853         6560997 :     if (size_t span = shape->slotSpan())
         854         1620839 :         obj->initializeSlotRange(0, span);
         855                 :
         856         6560997 :     return obj;
         857                 : }
         858                 :
         859                 : /* static */ inline JSObject *
         860          220517 : JSObject::createDenseArray(JSContext *cx, js::gc::AllocKind kind,
         861                 :                            js::HandleShape shape, js::HandleTypeObject type,
         862                 :                            uint32_t length)
         863                 : {
         864          220517 :     JS_ASSERT(shape && type);
         865          220517 :     JS_ASSERT(shape->getObjectClass() == &js::ArrayClass);
         866                 :
         867                 :     /*
         868                 :      * Dense arrays are non-native, and never have properties to store.
         869                 :      * The number of fixed slots in the shape of such objects is zero.
         870                 :      */
         871          220517 :     JS_ASSERT(shape->numFixedSlots() == 0);
         872                 :
         873                 :     /*
         874                 :      * The array initially stores its elements inline, there must be enough
         875                 :      * space for an elements header.
         876                 :      */
         877          220517 :     JS_ASSERT(js::gc::GetGCKindSlots(kind) >= js::ObjectElements::VALUES_PER_HEADER);
         878                 :
         879          220517 :     uint32_t capacity = js::gc::GetGCKindSlots(kind) - js::ObjectElements::VALUES_PER_HEADER;
         880                 :
         881          220517 :     JSObject *obj = js_NewGCObject(cx, kind);
         882          220517 :     if (!obj) {
         883               0 :         js_ReportOutOfMemory(cx);
         884               0 :         return NULL;
         885                 :     }
         886                 :
         887          220517 :     obj->shape_.init(shape);
         888          220517 :     obj->type_.init(type);
         889          220517 :     obj->slots = NULL;
         890          220517 :     obj->setFixedElements();
         891          220517 :     new (obj->getElementsHeader()) js::ObjectElements(capacity, length);
         892                 :
         893          220517 :     return obj;
         894                 : }
         895                 :
         896                 : inline void
         897        30978300 : JSObject::finish(js::FreeOp *fop)
         898                 : {
         899        30978300 :     if (hasDynamicSlots())
         900         4039887 :         fop->free_(slots);
         901        30978300 :     if (hasDynamicElements())
         902          274298 :         fop->free_(getElementsHeader());
         903        30978300 : }
         904                 :
         905                 : inline bool
         906         3099479 : JSObject::hasProperty(JSContext *cx, jsid id, bool *foundp, unsigned flags)
         907                 : {
         908                 :     JSObject *pobj;
         909                 :     JSProperty *prop;
         910         6198958 :     JSAutoResolveFlags rf(cx, flags);
         911         3099479 :     if (!lookupGeneric(cx, id, &pobj, &prop))
         912               0 :         return false;
         913         3099479 :     *foundp = !!prop;
         914         3099479 :     return true;
         915                 : }
         916                 :
         917                 : inline bool
         918         2088610 : JSObject::isCallable()
         919                 : {
         920         2088610 :     return isFunction() || getClass()->call;
         921                 : }
         922                 :
         923                 : inline JSPrincipals *
         924          106377 : JSObject::principals(JSContext *cx)
         925                 : {
         926          106377 :     if (JSObjectPrincipalsFinder find = cx->runtime->securityCallbacks->findObjectPrincipals)
         927              25 :         return find(this);
         928          106352 :     return cx->compartment ? cx->compartment->principals : NULL;
         929                 : }
         930                 :
         931                 : inline void
         932        38356032 : JSObject::nativeSetSlot(unsigned slot, const js::Value &value)
         933                 : {
         934        38356032 :     JS_ASSERT(isNative());
         935        38356032 :     JS_ASSERT(slot < slotSpan());
         936        38356032 :     return setSlot(slot, value);
         937                 : }
         938                 :
         939                 : inline void
         940        14750119 : JSObject::nativeSetSlotWithType(JSContext *cx, const js::Shape *shape, const js::Value &value)
         941                 : {
         942        14750119 :     nativeSetSlot(shape->slot(), value);
         943        14750119 :     js::types::AddTypePropertyId(cx, this, shape->propid(), value);
         944        14750119 : }
         945                 :
         946                 : inline bool
         947          146111 : JSObject::nativeContains(JSContext *cx, jsid id)
         948                 : {
         949          146111 :     return nativeLookup(cx, id) != NULL;
         950                 : }
         951                 :
         952                 : inline bool
         953        17331637 : JSObject::nativeContains(JSContext *cx, const js::Shape &shape)
         954                 : {
         955        17331637 :     return nativeLookup(cx, shape.propid()) == &shape;
         956                 : }
         957                 :
         958                 : inline bool
         959         3012027 : JSObject::nativeEmpty() const
         960                 : {
         961         3012027 :     return lastProperty()->isEmptyShape();
         962                 : }
         963                 :
         964                 : inline uint32_t
         965         1590457 : JSObject::propertyCount() const
         966                 : {
         967         1590457 :     return lastProperty()->entryCount();
         968                 : }
         969                 :
         970                 : inline bool
         971               0 : JSObject::hasPropertyTable() const
         972                 : {
         973               0 :     return lastProperty()->hasTable();
         974                 : }
         975                 :
         976                 : inline size_t
         977               0 : JSObject::computedSizeOfThisSlotsElements() const
         978                 : {
         979               0 :     size_t n = sizeOfThis();
         980                 :
         981               0 :     if (hasDynamicSlots())
         982               0 :         n += numDynamicSlots() * sizeof(js::Value);
         983                 :
         984               0 :     if (hasDynamicElements())
         985               0 :         n += (js::ObjectElements::VALUES_PER_HEADER + getElementsHeader()->capacity) *
         986               0 :              sizeof(js::Value);
         987                 :
         988               0 :     return n;
         989                 : }
         990                 :
         991                 : inline void
         992                 : JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf,
         993                 :                               size_t *slotsSize, size_t *elementsSize,
         994                 :                               size_t *miscSize) const
         995                 : {
         996                 :     *slotsSize = 0;
         997                 :     if (hasDynamicSlots()) {
         998                 :         *slotsSize += mallocSizeOf(slots);
         999                 :     }
        1000                 :
        1001                 :     *elementsSize = 0;
        1002                 :     if (hasDynamicElements()) {
        1003                 :         *elementsSize += mallocSizeOf(getElementsHeader());
        1004                 :     }
        1005                 :
        1006                 :     /* Other things may be measured in the future if DMD indicates it is worthwhile. */
        1007                 :     *miscSize = 0;
        1008                 :     if (isArguments()) {
        1009                 :         *miscSize += asArguments().sizeOfMisc(mallocSizeOf);
        1010                 :     } else if (isRegExpStatics()) {
        1011                 :         *miscSize += js::SizeOfRegExpStaticsData(this, mallocSizeOf);
        1012                 :     }
        1013                 : }
        1014                 :
        1015                 : inline JSBool
        1016         5645865 : JSObject::lookupGeneric(JSContext *cx, jsid id, JSObject **objp, JSProperty **propp)
        1017                 : {
        1018         5645865 :     js::LookupGenericOp op = getOps()->lookupGeneric;
        1019         5645865 :     return (op ? op : js_LookupProperty)(cx, this, id, objp, propp);
        1020                 : }
        1021                 :
        1022                 : inline JSBool
        1023          169734 : JSObject::lookupProperty(JSContext *cx, js::PropertyName *name, JSObject **objp, JSProperty **propp)
        1024                 : {
        1025          169734 :     return lookupGeneric(cx, ATOM_TO_JSID(name), objp, propp);
        1026                 : }
        1027                 :
        1028                 : inline JSBool
        1029        18826122 : JSObject::defineGeneric(JSContext *cx, jsid id, const js::Value &value,
        1030                 :                         JSPropertyOp getter /* = JS_PropertyStub */,
        1031                 :                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
        1032                 :                         unsigned attrs /* = JSPROP_ENUMERATE */)
        1033                 : {
        1034        18826122 :     JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
        1035        18826122 :     js::DefineGenericOp op = getOps()->defineGeneric;
        1036        18826122 :     return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs);
        1037                 : }
        1038                 :
        1039                 : inline JSBool
        1040         1267885 : JSObject::defineProperty(JSContext *cx, js::PropertyName *name, const js::Value &value,
        1041                 :                         JSPropertyOp getter /* = JS_PropertyStub */,
        1042                 :                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
        1043                 :                         unsigned attrs /* = JSPROP_ENUMERATE */)
        1044                 : {
        1045         1267885 :     return defineGeneric(cx, ATOM_TO_JSID(name), value, getter, setter, attrs);
        1046                 : }
        1047                 :
        1048                 : inline JSBool
        1049            8359 : JSObject::defineElement(JSContext *cx, uint32_t index, const js::Value &value,
        1050                 :                         JSPropertyOp getter /* = JS_PropertyStub */,
        1051                 :                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
        1052                 :                         unsigned attrs /* = JSPROP_ENUMERATE */)
        1053                 : {
        1054            8359 :     js::DefineElementOp op = getOps()->defineElement;
        1055            8359 :     return (op ? op : js_DefineElement)(cx, this, index, &value, getter, setter, attrs);
        1056                 : }
        1057                 :
        1058                 : inline JSBool
        1059             325 : JSObject::defineSpecial(JSContext *cx, js::SpecialId sid, const js::Value &value,
        1060                 :                         JSPropertyOp getter /* = JS_PropertyStub */,
        1061                 :                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
        1062                 :                         unsigned attrs /* = JSPROP_ENUMERATE */)
        1063                 : {
        1064             325 :     return defineGeneric(cx, SPECIALID_TO_JSID(sid), value, getter, setter, attrs);
        1065                 : }
        1066                 :
        1067                 : inline JSBool
        1068               0 : JSObject::lookupElement(JSContext *cx, uint32_t index, JSObject **objp, JSProperty **propp)
        1069                 : {
        1070               0 :     js::LookupElementOp op = getOps()->lookupElement;
        1071               0 :     return (op ? op : js_LookupElement)(cx, this, index, objp, propp);
        1072                 : }
        1073                 :
        1074                 : inline JSBool
        1075                 : JSObject::lookupSpecial(JSContext *cx, js::SpecialId sid, JSObject **objp, JSProperty **propp)
        1076                 : {
        1077                 :     return lookupGeneric(cx, SPECIALID_TO_JSID(sid), objp, propp);
        1078                 : }
        1079                 :
        1080                 : inline JSBool
        1081         1637345 : JSObject::getElement(JSContext *cx, JSObject *receiver, uint32_t index, js::Value *vp)
        1082                 : {
        1083         1637345 :     js::ElementIdOp op = getOps()->getElement;
        1084         1637345 :     if (op)
        1085          700755 :         return op(cx, this, receiver, index, vp);
        1086                 :
        1087                 :     jsid id;
        1088          936590 :     if (!js::IndexToId(cx, index, &id))
        1089               0 :         return false;
        1090          936590 :     return getGeneric(cx, receiver, id, vp);
        1091                 : }
        1092                 :
        1093                 : inline JSBool
        1094         1134831 : JSObject::getElement(JSContext *cx, uint32_t index, js::Value *vp)
        1095                 : {
        1096         1134831 :     return getElement(cx, this, index, vp);
        1097                 : }
        1098                 :
        1099                 : inline JSBool
        1100          505294 : JSObject::getElementIfPresent(JSContext *cx, JSObject *receiver, uint32_t index, js::Value *vp,
        1101                 :                               bool *present)
        1102                 : {
        1103          505294 :     js::ElementIfPresentOp op = getOps()->getElementIfPresent;
        1104          505294 :     if (op)
        1105             513 :         return op(cx, this, receiver, index, vp, present);
        1106                 :
        1107                 :     /* For now, do the index-to-id conversion just once, then use
        1108                 :      * lookupGeneric/getGeneric.  Once lookupElement and getElement stop both
        1109                 :      * doing index-to-id conversions, we can use those here.
        1110                 :      */
        1111                 :     jsid id;
        1112          504781 :     if (!js::IndexToId(cx, index, &id))
        1113               0 :         return false;
        1114                 :
        1115                 :     JSObject *obj2;
        1116                 :     JSProperty *prop;
        1117          504781 :     if (!lookupGeneric(cx, id, &obj2, &prop))
        1118               0 :         return false;
        1119                 :
        1120          504781 :     if (!prop) {
        1121          503134 :         *present = false;
        1122          503134 :         js::Debug_SetValueRangeToCrashOnTouch(vp, 1);
        1123          503134 :         return true;
        1124                 :     }
        1125                 :
        1126            1647 :     *present = true;
        1127            1647 :     return getGeneric(cx, receiver, id, vp);
        1128                 : }
        1129                 :
        1130                 : inline JSBool
        1131           13267 : JSObject::getSpecial(JSContext *cx, JSObject *receiver, js::SpecialId sid, js::Value *vp)
        1132                 : {
        1133           13267 :     return getGeneric(cx, receiver, SPECIALID_TO_JSID(sid), vp);
        1134                 : }
        1135                 :
        1136                 : inline JSBool
        1137           83259 : JSObject::getGenericAttributes(JSContext *cx, jsid id, unsigned *attrsp)
        1138                 : {
        1139           83259 :     js::GenericAttributesOp op = getOps()->getGenericAttributes;
        1140           83259 :     return (op ? op : js_GetAttributes)(cx, this, id, attrsp);
        1141                 : }
        1142                 :
        1143                 : inline JSBool
        1144            1127 : JSObject::getPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
        1145                 : {
        1146            1127 :     return getGenericAttributes(cx, ATOM_TO_JSID(name), attrsp);
        1147                 : }
        1148                 :
        1149                 : inline JSBool
        1150               0 : JSObject::getElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp)
        1151                 : {
        1152                 :     jsid id;
        1153               0 :     if (!js::IndexToId(cx, index, &id))
        1154               0 :         return false;
        1155               0 :     return getGenericAttributes(cx, id, attrsp);
        1156                 : }
        1157                 :
        1158                 : inline JSBool
        1159               0 : JSObject::getSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp)
        1160                 : {
        1161               0 :     return getGenericAttributes(cx, SPECIALID_TO_JSID(sid), attrsp);
        1162                 : }
        1163                 :
        1164                 : inline bool
        1165        49848464 : JSObject::isProxy() const
        1166                 : {
        1167        49848464 :     return js::IsProxy(this);
        1168                 : }
        1169                 :
        1170                 : inline bool
        1171           66044 : JSObject::isCrossCompartmentWrapper() const
        1172                 : {
        1173           66044 :     return js::IsCrossCompartmentWrapper(this);
        1174                 : }
        1175                 :
        1176                 : inline bool
        1177        59282117 : JSObject::isWrapper() const
        1178                 : {
        1179        59282117 :     return js::IsWrapper(this);
        1180                 : }
        1181                 :
        1182                 : inline js::GlobalObject &
        1183       998848527 : JSObject::global() const
        1184                 : {
        1185       998848527 :     JSObject *obj = const_cast<JSObject *>(this);
        1186      1059866463 :     while (JSObject *parent = obj->getParent())
        1187        30508968 :         obj = parent;
        1188       998848527 :     return obj->asGlobal();
        1189                 : }
        1190                 :
        1191                 : static inline bool
        1192         2372375 : js_IsCallable(const js::Value &v)
        1193                 : {
        1194         2372375 :     return v.isObject() && v.toObject().isCallable();
        1195                 : }
        1196                 :
        1197                 : namespace js {
        1198                 :
        1199                 : inline void
        1200          512198 : OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
        1201                 : {
        1202          512198 :     if (JSObjectOp op = obj->getClass()->ext.innerObject)
        1203               0 :         obj = op(cx, obj);
        1204          512198 : }
        1205                 :
        1206                 : inline void
        1207           97865 : OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
        1208                 : {
        1209           97865 :     if (JSObjectOp op = obj->getClass()->ext.outerObject)
        1210               0 :         obj = op(cx, obj);
        1211           97865 : }
        1212                 :
        1213                 : /*
        1214                 :  * Methods to test whether an object or a value is of type "xml" (per typeof).
        1215                 :  */
        1216                 :
        1217                 : #define VALUE_IS_XML(v)      (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isXML())
        1218                 :
        1219                 : static inline bool
        1220         9602804 : IsXML(const js::Value &v)
        1221                 : {
        1222         9602804 :     return v.isObject() && v.toObject().isXML();
        1223                 : }
        1224                 :
        1225                 : static inline bool
        1226            3362 : IsStopIteration(const js::Value &v)
        1227                 : {
        1228            3362 :     return v.isObject() && v.toObject().isStopIteration();
        1229                 : }
        1230                 :
        1231                 : /* ES5 9.1 ToPrimitive(input). */
        1232                 : static JS_ALWAYS_INLINE bool
        1233        25267777 : ToPrimitive(JSContext *cx, Value *vp)
        1234                 : {
        1235        25267777 :     if (vp->isPrimitive())
        1236        24735260 :         return true;
        1237          532517 :     return vp->toObject().defaultValue(cx, JSTYPE_VOID, vp);
        1238                 : }
        1239                 :
        1240                 : /* ES5 9.1 ToPrimitive(input, PreferredType). */
        1241                 : static JS_ALWAYS_INLINE bool
        1242        10576798 : ToPrimitive(JSContext *cx, JSType preferredType, Value *vp)
        1243                 : {
        1244        10576798 :     JS_ASSERT(preferredType != JSTYPE_VOID); /* Use the other ToPrimitive! */
        1245        10576798 :     if (vp->isPrimitive())
        1246        10216680 :         return true;
        1247          360118 :     return vp->toObject().defaultValue(cx, preferredType, vp);
        1248                 : }
        1249                 :
        1250                 : /*
        1251                 :  * Return true if this is a compiler-created internal function accessed by
        1252                 :  * its own object. Such a function object must not be accessible to script
        1253                 :  * or embedding code.
        1254                 :  */
        1255                 : inline bool
        1256          951597 : IsInternalFunctionObject(JSObject *funobj)
        1257                 : {
        1258          951597 :     JSFunction *fun = funobj->toFunction();
        1259          951597 :     return (fun->flags & JSFUN_LAMBDA) && !funobj->getParent();
        1260                 : }
        1261                 :
        1262                 : class AutoPropDescArrayRooter : private AutoGCRooter
        1263          301484 : {
        1264                 :   public:
        1265          301484 :     AutoPropDescArrayRooter(JSContext *cx)
        1266          301484 :       : AutoGCRooter(cx, DESCRIPTORS), descriptors(cx)
        1267          301484 :     { }
        1268                 :
        1269          301529 :     PropDesc *append() {
        1270          301529 :         if (!descriptors.append(PropDesc()))
        1271               0 :             return NULL;
        1272          301529 :         return &descriptors.back();
        1273                 :     }
        1274                 :
        1275             549 :     PropDesc& operator[](size_t i) {
        1276             549 :         JS_ASSERT(i < descriptors.length());
        1277             549 :         return descriptors[i];
        1278                 :     }
        1279                 :
        1280                 :     friend void AutoGCRooter::trace(JSTracer *trc);
        1281                 :
        1282                 :   private:
        1283                 :     PropDescArray descriptors;
        1284                 : };
        1285                 :
        1286                 : class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescriptor
        1287           14960 : {
        1288                 :   public:
        1289           14933 :     AutoPropertyDescriptorRooter(JSContext *cx) : AutoGCRooter(cx, DESCRIPTOR) {
        1290           14933 :         obj = NULL;
        1291           14933 :         attrs = 0;
        1292           14933 :         getter = (PropertyOp) NULL;
        1293           14933 :         setter = (StrictPropertyOp) NULL;
        1294           14933 :         value.setUndefined();
        1295           14933 :     }
        1296                 :
        1297              27 :     AutoPropertyDescriptorRooter(JSContext *cx, PropertyDescriptor *desc)
        1298              27 :       : AutoGCRooter(cx, DESCRIPTOR)
        1299                 :     {
        1300              27 :         obj = desc->obj;
        1301              27 :         attrs = desc->attrs;
        1302              27 :         getter = desc->getter;
        1303              27 :         setter = desc->setter;
        1304              27 :         value = desc->value;
        1305              27 :     }
        1306                 :
        1307                 :     friend void AutoGCRooter::trace(JSTracer *trc);
        1308                 : };
        1309                 :
        1310                 : inline bool
        1311        19896288 : NewObjectCache::lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry)
        1312                 : {
        1313        19896288 :     uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind;
        1314        19896288 :     *pentry = hash % js::ArrayLength(entries);
        1315                 :
        1316        19896288 :     Entry *entry = &entries[*pentry];
        1317                 :
        1318                 :     /* N.B. Lookups with the same clasp/key but different kinds map to different entries. */
        1319        19896288 :     return (entry->clasp == clasp && entry->key == key);
        1320                 : }
        1321                 :
        1322                 : inline bool
        1323         2090502 : NewObjectCache::lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
        1324                 : {
        1325         2090502 :     JS_ASSERT(!proto->isGlobal());
        1326         2090502 :     return lookup(clasp, proto, kind, pentry);
        1327                 : }
        1328                 :
        1329                 : inline bool
        1330        15279767 : NewObjectCache::lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry)
        1331                 : {
        1332        15279767 :     return lookup(clasp, global, kind, pentry);
        1333                 : }
        1334                 :
        1335                 : inline bool
        1336         2526019 : NewObjectCache::lookupType(Class *clasp, js::types::TypeObject *type, gc::AllocKind kind, EntryIndex *pentry)
        1337                 : {
        1338         2526019 :     return lookup(clasp, type, kind, pentry);
        1339                 : }
        1340                 :
        1341                 : inline void
        1342          825038 : NewObjectCache::fill(EntryIndex entry_, Class *clasp, gc::Cell *key, gc::AllocKind kind, JSObject *obj)
        1343                 : {
        1344          825038 :     JS_ASSERT(unsigned(entry_) < ArrayLength(entries));
        1345          825038 :     Entry *entry = &entries[entry_];
        1346                 :
        1347          825038 :     JS_ASSERT(!obj->hasDynamicSlots() && !obj->hasDynamicElements());
        1348                 :
        1349          825038 :     entry->clasp = clasp;
        1350          825038 :     entry->key = key;
        1351          825038 :     entry->kind = kind;
        1352                 :
        1353          825038 :     entry->nbytes = obj->sizeOfThis();
        1354          825038 :     js_memcpy(&entry->templateObject, obj, entry->nbytes);
        1355          825038 : }
        1356                 :
        1357                 : inline void
        1358          281973 : NewObjectCache::fillProto(EntryIndex entry, Class *clasp, JSObject *proto, gc::AllocKind kind, JSObject *obj)
        1359                 : {
        1360          281973 :     JS_ASSERT(!proto->isGlobal());
        1361          281973 :     JS_ASSERT(obj->getProto() == proto);
        1362          281973 :     return fill(entry, clasp, proto, kind, obj);
        1363                 : }
        1364                 :
        1365                 : inline void
        1366          539777 : NewObjectCache::fillGlobal(EntryIndex entry, Class *clasp, js::GlobalObject *global, gc::AllocKind kind, JSObject *obj)
        1367                 : {
        1368                 :     //JS_ASSERT(global == obj->getGlobal());
        1369          539777 :     return fill(entry, clasp, global, kind, obj);
        1370                 : }
        1371                 :
        1372                 : inline void
        1373            3288 : NewObjectCache::fillType(EntryIndex entry, Class *clasp, js::types::TypeObject *type, gc::AllocKind kind, JSObject *obj)
        1374                 : {
        1375            3288 :     JS_ASSERT(obj->type() == type);
        1376            3288 :     return fill(entry, clasp, type, kind, obj);
        1377                 : }
        1378                 :
        1379                 : inline void
        1380        19052049 : NewObjectCache::copyCachedToObject(JSObject *dst, JSObject *src)
        1381                 : {
        1382        19052049 :     js_memcpy(dst, src, dst->sizeOfThis());
        1383                 : #ifdef JSGC_GENERATIONAL
        1384                 :     Shape::writeBarrierPost(dst->shape_, &dst->shape_);
        1385                 :     types::TypeObject::writeBarrierPost(dst->type_, &dst->type_);
        1386                 : #endif
        1387        19052049 : }
        1388                 :
        1389                 : inline JSObject *
        1390        19052050 : NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_)
        1391                 : {
        1392        19052050 :     JS_ASSERT(unsigned(entry_) < ArrayLength(entries));
        1393        19052050 :     Entry *entry = &entries[entry_];
        1394                 :
        1395        19052050 :     JSObject *obj = js_TryNewGCObject(cx, entry->kind);
        1396        19052050 :     if (obj) {
        1397        18808869 :         copyCachedToObject(obj, &entry->templateObject);
        1398        18808869 :         Probes::createObject(cx, obj);
        1399        18808869 :         return obj;
        1400                 :     }
        1401                 :
        1402                 :     /* Copy the entry to the stack first in case it is purged by a GC. */
        1403          243181 :     size_t nbytes = entry->nbytes;
        1404                 :     char stackObject[sizeof(JSObject_Slots16)];
        1405          243181 :     JS_ASSERT(nbytes <= sizeof(stackObject));
        1406          243181 :     js_memcpy(&stackObject, &entry->templateObject, nbytes);
        1407                 :
        1408          243181 :     JSObject *baseobj = (JSObject *) stackObject;
        1409          486362 :     RootShape shapeRoot(cx, (Shape **) baseobj->addressOfShape());
        1410          486362 :     RootTypeObject typeRoot(cx, (types::TypeObject **) baseobj->addressOfType());
        1411                 :
        1412          243181 :     obj = js_NewGCObject(cx, entry->kind);
        1413          243181 :     if (obj) {
        1414          243180 :         copyCachedToObject(obj, baseobj);
        1415          243180 :         Probes::createObject(cx, obj);
        1416          243180 :         return obj;
        1417                 :     }
        1418                 :
        1419               1 :     return NULL;
        1420                 : }
        1421                 :
        1422                 : static inline bool
        1423        24221252 : CanBeFinalizedInBackground(gc::AllocKind kind, Class *clasp)
        1424                 : {
        1425                 : #ifdef JS_THREADSAFE
        1426        24221252 :     JS_ASSERT(kind <= gc::FINALIZE_OBJECT_LAST);
        1427                 :     /* If the class has no finalizer or a finalizer that is safe to call on
        1428                 :      * a different thread, we change the finalize kind. For example,
        1429                 :      * FINALIZE_OBJECT0 calls the finalizer on the main thread,
        1430                 :      * FINALIZE_OBJECT0_BACKGROUND calls the finalizer on the gcHelperThread.
        1431                 :      * IsBackgroundAllocKind is called to prevent recursively incrementing
        1432                 :      * the finalize kind; kind may already be a background finalize kind.
        1433                 :      */
        1434        24221252 :     if (!gc::IsBackgroundAllocKind(kind) && !clasp->finalize)
        1435        12487056 :         return true;
        1436                 : #endif
        1437        11734196 :     return false;
        1438                 : }
        1439                 :
        1440                 : /*
        1441                 :  * Make an object with the specified prototype. If parent is null, it will
        1442                 :  * default to the prototype's global if the prototype is non-null.
        1443                 :  */
        1444                 : JSObject *
        1445                 : NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
        1446                 :                         gc::AllocKind kind);
        1447                 :
        1448                 : inline JSObject *
        1449          508924 : NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
        1450                 : {
        1451          508924 :     gc::AllocKind kind = gc::GetGCObjectKind(clasp);
        1452          508924 :     return NewObjectWithGivenProto(cx, clasp, proto, parent, kind);
        1453                 : }
        1454                 :
        1455                 : inline JSProtoKey
        1456        21839267 : GetClassProtoKey(js::Class *clasp)
        1457                 : {
        1458        21839267 :     JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
        1459        21839267 :     if (key != JSProto_Null)
        1460        21306285 :         return key;
        1461          532982 :     if (clasp->flags & JSCLASS_IS_ANONYMOUS)
        1462             846 :         return JSProto_Object;
        1463          532136 :     return JSProto_Null;
        1464                 : }
        1465                 :
        1466                 : inline bool
        1467         4679669 : FindProto(JSContext *cx, js::Class *clasp, HandleObject parent, JSObject **proto)
        1468                 : {
        1469         4679669 :     JSProtoKey protoKey = GetClassProtoKey(clasp);
        1470         4679669 :     if (!js_GetClassPrototype(cx, parent, protoKey, proto, clasp))
        1471               0 :         return false;
        1472         4679669 :     if (!(*proto) && !js_GetClassPrototype(cx, parent, JSProto_Object, proto))
        1473               0 :         return false;
        1474         4679669 :     return true;
        1475                 : }
        1476                 :
        1477                 : /*
        1478                 :  * Make an object with the prototype set according to the specified prototype or class:
        1479                 :  *
        1480                 :  * if proto is non-null:
        1481                 :  *   use the specified proto
        1482                 :  * for a built-in class:
        1483                 :  *   use the memoized original value of the class constructor .prototype
        1484                 :  *   property object
        1485                 :  * else if available
        1486                 :  *   the current value of .prototype
        1487                 :  * else
        1488                 :  *   Object.prototype.
        1489                 :  *
        1490                 :  * The class prototype will be fetched from the parent's global. If global is
        1491                 :  * null, the context's active global will be used, and the resulting object's
        1492                 :  * parent will be that global.
        1493                 :  */
        1494                 : JSObject *
        1495                 : NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
        1496                 :                         gc::AllocKind kind);
        1497                 :
        1498                 : inline JSObject *
        1499         2075669 : NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
        1500                 : {
        1501         2075669 :     gc::AllocKind kind = gc::GetGCObjectKind(clasp);
        1502         2075669 :     return NewObjectWithClassProto(cx, clasp, proto, parent, kind);
        1503                 : }
        1504                 :
        1505                 : /*
        1506                 :  * Create a native instance of the given class with parent and proto set
        1507                 :  * according to the context's active global.
        1508                 :  */
        1509                 : inline JSObject *
        1510         8868435 : NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::AllocKind kind)
        1511                 : {
        1512         8868435 :     return NewObjectWithClassProto(cx, clasp, NULL, NULL, kind);
        1513                 : }
        1514                 :
        1515                 : inline JSObject *
        1516         6234114 : NewBuiltinClassInstance(JSContext *cx, Class *clasp)
        1517                 : {
        1518         6234114 :     gc::AllocKind kind = gc::GetGCObjectKind(clasp);
        1519         6234114 :     return NewBuiltinClassInstance(cx, clasp, kind);
        1520                 : }
        1521                 :
        1522                 : inline GlobalObject *
        1523        11315326 : GetCurrentGlobal(JSContext *cx)
        1524                 : {
        1525        11315326 :     JSObject *scopeChain = (cx->hasfp()) ? &cx->fp()->scopeChain() : cx->globalObject;
        1526        11315326 :     return scopeChain ? &scopeChain->global() : NULL;
        1527                 : }
        1528                 :
        1529                 : bool
        1530                 : FindClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, JSObject **protop,
        1531                 :                    Class *clasp);
        1532                 :
        1533                 : /*
        1534                 :  * Create a plain object with the specified type. This bypasses getNewType to
        1535                 :  * avoid losing creation site information for objects made by scripted 'new'.
        1536                 :  */
        1537                 : JSObject *
        1538                 : NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent, gc::AllocKind kind);
        1539                 :
        1540                 : /* Make an object with pregenerated shape from a NEWOBJECT bytecode. */
        1541                 : static inline JSObject *
        1542         2614024 : CopyInitializerObject(JSContext *cx, JSObject *baseobj)
        1543                 : {
        1544         2614024 :     JS_ASSERT(baseobj->getClass() == &ObjectClass);
        1545         2614024 :     JS_ASSERT(!baseobj->inDictionaryMode());
        1546                 :
        1547         2614024 :     gc::AllocKind kind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots());
        1548                 : #ifdef JS_THREADSAFE
        1549         2614024 :     kind = gc::GetBackgroundAllocKind(kind);
        1550                 : #endif
        1551         2614024 :     JS_ASSERT(kind == baseobj->getAllocKind());
        1552         2614024 :     JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
        1553                 :
        1554         2614024 :     if (!obj)
        1555               1 :         return NULL;
        1556                 :
        1557         2614023 :     if (!obj->setLastProperty(cx, baseobj->lastProperty()))
        1558               0 :         return NULL;
        1559                 :
        1560         2614023 :     return obj;
        1561                 : }
        1562                 :
        1563                 : JSObject *
        1564                 : NewReshapedObject(JSContext *cx, js::types::TypeObject *type, JSObject *parent,
        1565                 :                   gc::AllocKind kind, const Shape *shape);
        1566                 :
        1567                 : /*
        1568                 :  * As for gc::GetGCObjectKind, where numSlots is a guess at the final size of
        1569                 :  * the object, zero if the final size is unknown. This should only be used for
        1570                 :  * objects that do not require any fixed slots.
        1571                 :  */
        1572                 : static inline gc::AllocKind
        1573           15211 : GuessObjectGCKind(size_t numSlots)
        1574                 : {
        1575           15211 :     if (numSlots)
        1576            8443 :         return gc::GetGCObjectKind(numSlots);
        1577            6768 :     return gc::FINALIZE_OBJECT4;
        1578                 : }
        1579                 :
        1580                 : static inline gc::AllocKind
        1581         2266237 : GuessArrayGCKind(size_t numSlots)
        1582                 : {
        1583         2266237 :     if (numSlots)
        1584         2124663 :         return gc::GetGCArrayKind(numSlots);
        1585          141574 :     return gc::FINALIZE_OBJECT8;
        1586                 : }
        1587                 :
        1588                 : /*
        1589                 :  * Get the GC kind to use for scripted 'new' on the given class.
        1590                 :  * FIXME bug 547327: estimate the size from the allocation site.
        1591                 :  */
        1592                 : static inline gc::AllocKind
        1593         2172923 : NewObjectGCKind(JSContext *cx, js::Class *clasp)
        1594                 : {
        1595         2172923 :     if (clasp == &ArrayClass || clasp == &SlowArrayClass)
        1596               0 :         return gc::FINALIZE_OBJECT8;
        1597         2172923 :     if (clasp == &FunctionClass)
        1598               0 :         return gc::FINALIZE_OBJECT2;
        1599         2172923 :     return gc::FINALIZE_OBJECT4;
        1600                 : }
        1601                 :
        1602                 : /*
        1603                 :  * Fill slots with the initial slot array to use for a newborn object which
        1604                 :  * may or may not need dynamic slots.
        1605                 :  */
        1606                 : inline bool
        1607         5689289 : PreallocateObjectDynamicSlots(JSContext *cx, Shape *shape, HeapSlot **slots)
        1608                 : {
        1609         5689289 :     if (size_t count = JSObject::dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan())) {
        1610           32975 :         *slots = (HeapSlot *) cx->malloc_(count * sizeof(HeapSlot));
        1611           32975 :         if (!*slots)
        1612               0 :             return false;
        1613           32975 :         Debug_SetSlotRangeToCrashOnTouch(*slots, count);
        1614           32975 :         return true;
        1615                 :     }
        1616         5656314 :     *slots = NULL;
        1617         5656314 :     return true;
        1618                 : }
        1619                 :
        1620                 : inline bool
        1621           70814 : DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global,
        1622                 :                               JSProtoKey key, JSObject *ctor, JSObject *proto)
        1623                 : {
        1624           70814 :     JS_ASSERT(!global->nativeEmpty()); /* reserved slots already allocated */
        1625           70814 :     JS_ASSERT(ctor);
        1626           70814 :     JS_ASSERT(proto);
        1627                 :
        1628           70814 :     jsid id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]);
        1629           70814 :     JS_ASSERT(!global->nativeLookup(cx, id));
        1630                 :
        1631                 :     /* Set these first in case AddTypePropertyId looks for this class. */
        1632           70814 :     global->setSlot(key, ObjectValue(*ctor));
        1633           70814 :     global->setSlot(key + JSProto_LIMIT, ObjectValue(*proto));
        1634           70814 :     global->setSlot(key + JSProto_LIMIT * 2, ObjectValue(*ctor));
        1635                 :
        1636           70814 :     types::AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
        1637           70814 :     if (!global->addDataProperty(cx, id, key + JSProto_LIMIT * 2, 0)) {
        1638               0 :         global->setSlot(key, UndefinedValue());
        1639               0 :         global->setSlot(key + JSProto_LIMIT, UndefinedValue());
        1640               0 :         global->setSlot(key + JSProto_LIMIT * 2, UndefinedValue());
        1641               0 :         return false;
        1642                 :     }
        1643                 :
        1644           70814 :     return true;
        1645                 : }
        1646                 :
        1647                 : bool
        1648          299098 : PropDesc::checkGetter(JSContext *cx)
        1649                 : {
        1650          299098 :     if (hasGet && !js_IsCallable(get) && !get.isUndefined()) {
        1651                 :         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GET_SET_FIELD,
        1652              18 :                              js_getter_str);
        1653              18 :         return false;
        1654                 :     }
        1655          299080 :     return true;
        1656                 : }
        1657                 :
        1658                 : bool
        1659            4313 : PropDesc::checkSetter(JSContext *cx)
        1660                 : {
        1661            4313 :     if (hasSet && !js_IsCallable(set) && !set.isUndefined()) {
        1662                 :         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GET_SET_FIELD,
        1663               0 :                              js_setter_str);
        1664               0 :         return false;
        1665                 :     }
        1666            4313 :     return true;
        1667                 : }
        1668                 :
        1669                 : inline bool
        1670          726168 : ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx)
        1671                 : {
        1672          726168 :     if (JS_UNLIKELY(obj.isProxy()))
        1673             594 :         return Proxy::objectClassIs(&obj, classValue, cx);
        1674                 :
        1675          725574 :     switch (classValue) {
        1676            1081 :       case ESClass_Array: return obj.isArray();
        1677             378 :       case ESClass_Number: return obj.isNumber();
        1678             369 :       case ESClass_String: return obj.isString();
        1679             342 :       case ESClass_Boolean: return obj.isBoolean();
        1680          723404 :       case ESClass_RegExp: return obj.isRegExp();
        1681                 :     }
        1682               0 :     JS_NOT_REACHED("bad classValue");
        1683                 :     return false;
        1684                 : }
        1685                 :
        1686                 : inline bool
        1687          918829 : IsObjectWithClass(const Value &v, ESClassValue classValue, JSContext *cx)
        1688                 : {
        1689          918829 :     if (!v.isObject())
        1690          556722 :         return false;
        1691          362107 :     return ObjectClassIs(v.toObject(), classValue, cx);
        1692                 : }
        1693                 :
        1694                 : static JS_ALWAYS_INLINE bool
        1695         3207311 : ValueIsSpecial(JSObject *obj, Value *propval, SpecialId *sidp, JSContext *cx)
        1696                 : {
        1697         3207311 :     if (!propval->isObject())
        1698         3207074 :         return false;
        1699                 :
        1700                 : #if JS_HAS_XML_SUPPORT
        1701             237 :     if (obj->isXML()) {
        1702               0 :         *sidp = SpecialId(propval->toObject());
        1703               0 :         return true;
        1704                 :     }
        1705                 :
        1706             237 :     JSObject &propobj = propval->toObject();
        1707                 :     JSAtom *name;
        1708             237 :     if (propobj.isQName() && GetLocalNameFromFunctionQName(&propobj, &name, cx)) {
        1709               0 :         propval->setString(name);
        1710               0 :         return false;
        1711                 :     }
        1712                 : #endif
        1713                 :
        1714             237 :     return false;
        1715                 : }
        1716                 :
        1717                 : JSObject *
        1718                 : DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, HandleAtom atom,
        1719                 :                               JSObject *protoProto, Class *clasp,
        1720                 :                               Native constructor, unsigned nargs,
        1721                 :                               JSPropertySpec *ps, JSFunctionSpec *fs,
        1722                 :                               JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
        1723                 :                               JSObject **ctorp = NULL,
        1724                 :                               gc::AllocKind ctorKind = JSFunction::FinalizeKind);
        1725                 :
        1726                 : } /* namespace js */
        1727                 :
        1728                 : extern JSObject *
        1729                 : js_InitClass(JSContext *cx, js::HandleObject obj, JSObject *parent_proto,
        1730                 :              js::Class *clasp, JSNative constructor, unsigned nargs,
        1731                 :              JSPropertySpec *ps, JSFunctionSpec *fs,
        1732                 :              JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
        1733                 :              JSObject **ctorp = NULL,
        1734                 :              js::gc::AllocKind ctorKind = JSFunction::FinalizeKind);
        1735                 :
        1736                 : inline JSObject *
        1737        20620590 : js_GetProtoIfDenseArray(JSObject *obj)
        1738                 : {
        1739        20620590 :     return obj->isDenseArray() ? obj->getProto() : obj;
        1740                 : }
        1741                 :
        1742                 : /*
        1743                 :  * js_PurgeScopeChain does nothing if obj is not itself a prototype or parent
        1744                 :  * scope, else it reshapes the scope and prototype chains it links. It calls
        1745                 :  * js_PurgeScopeChainHelper, which asserts that obj is flagged as a delegate
        1746                 :  * (i.e., obj has ever been on a prototype or parent chain).
        1747                 :  */
        1748                 : extern bool
        1749                 : js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id);
        1750                 :
        1751                 : inline bool
        1752        31574075 : js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id)
        1753                 : {
        1754        31574075 :     if (obj->isDelegate())
        1755          626973 :         return js_PurgeScopeChainHelper(cx, obj, id);
        1756        30947102 :     return true;
        1757                 : }
        1758                 :
        1759                 : inline void
        1760           25246 : js::DestroyIdArray(FreeOp *fop, JSIdArray *ida)
        1761                 : {
        1762           25246 :     fop->free_(ida);
        1763           25246 : }
        1764                 :
        1765                 : #endif /* jsobjinlines_h___ */

Generated by: LCOV version 1.7