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

LCOV - code coverage report
| Current view: | directory - js/src - jsscopeinlines.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 210 | 208 | 99.0 %
| Date: | 2012-04-21 | Functions: | 29 | 29 | 100.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  *
           3                 :  * ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is Mozilla Communicator client code, released
          17                 :  * March 31, 1998.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * Netscape Communications Corporation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #ifndef jsscopeinlines_h___
          41                 : #define jsscopeinlines_h___
          42                 :
          43                 : #include <new>
          44                 :
          45                 : #include "jsarray.h"
          46                 : #include "jsbool.h"
          47                 : #include "jscntxt.h"
          48                 : #include "jsdbgapi.h"
          49                 : #include "jsfun.h"
          50                 : #include "jsobj.h"
          51                 : #include "jsscope.h"
          52                 : #include "jsgc.h"
          53                 : #include "jsgcmark.h"
          54                 :
          55                 : #include "vm/ArgumentsObject.h"
          56                 : #include "vm/ScopeObject.h"
          57                 : #include "vm/StringObject.h"
          58                 :
          59                 : #include "jscntxtinlines.h"
          60                 : #include "jsgcinlines.h"
          61                 : #include "jsobjinlines.h"
          62                 :
          63                 : #include "vm/ScopeObject-inl.h"
          64                 :
          65                 : namespace js {
          66                 :
          67                 : inline
          68                 : BaseShape::BaseShape(Class *clasp, JSObject *parent, uint32_t objectFlags)
          69                 : {
          70                 :     JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK));
          71                 :     PodZero(this);
          72                 :     this->clasp = clasp;
          73                 :     this->parent = parent;
          74                 :     this->flags = objectFlags;
          75                 : }
          76                 :
          77                 : inline
          78                 : BaseShape::BaseShape(Class *clasp, JSObject *parent, uint32_t objectFlags,
          79                 :                      uint8_t attrs, js::PropertyOp rawGetter, js::StrictPropertyOp rawSetter)
          80                 : {
          81                 :     JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK));
          82                 :     PodZero(this);
          83                 :     this->clasp = clasp;
          84                 :     this->parent = parent;
          85                 :     this->flags = objectFlags;
          86                 :     this->rawGetter = rawGetter;
          87                 :     this->rawSetter = rawSetter;
          88                 :     if ((attrs & JSPROP_GETTER) && rawGetter) {
          89                 :         this->flags |= HAS_GETTER_OBJECT;
          90                 :         JSObject::writeBarrierPost(this->getterObj, &this->getterObj);
          91                 :     }
          92                 :     if ((attrs & JSPROP_SETTER) && rawSetter) {
          93                 :         this->flags |= HAS_SETTER_OBJECT;
          94                 :         JSObject::writeBarrierPost(this->setterObj, &this->setterObj);
          95                 :     }
          96                 : }
          97                 :
          98                 : inline
          99         7193180 : BaseShape::BaseShape(const StackBaseShape &base)
         100                 : {
         101         7193180 :     PodZero(this);
         102         7193180 :     this->clasp = base.clasp;
         103         7193180 :     this->parent = base.parent;
         104         7193180 :     this->flags = base.flags;
         105         7193180 :     this->rawGetter = base.rawGetter;
         106         7193180 :     this->rawSetter = base.rawSetter;
         107         7193180 :     if ((base.flags & HAS_GETTER_OBJECT) && base.rawGetter) {
         108         2419163 :         JSObject::writeBarrierPost(this->getterObj, &this->getterObj);
         109                 :     }
         110         7193180 :     if ((base.flags & HAS_SETTER_OBJECT) && base.rawSetter) {
         111          432409 :         JSObject::writeBarrierPost(this->setterObj, &this->setterObj);
         112                 :     }
         113         7193180 : }
         114                 :
         115                 : inline BaseShape &
         116         4795528 : BaseShape::operator=(const BaseShape &other)
         117                 : {
         118         4795528 :     clasp = other.clasp;
         119         4795528 :     parent = other.parent;
         120         4795528 :     flags = other.flags;
         121         4795528 :     slotSpan_ = other.slotSpan_;
         122         4795528 :     if (flags & HAS_GETTER_OBJECT) {
         123          362510 :         getterObj = other.getterObj;
         124          362510 :         JSObject::writeBarrierPost(getterObj, &getterObj);
         125                 :     } else {
         126         4433018 :         rawGetter = other.rawGetter;
         127                 :     }
         128         4795528 :     if (flags & HAS_SETTER_OBJECT) {
         129           11130 :         setterObj = other.setterObj;
         130           11130 :         JSObject::writeBarrierPost(setterObj, &setterObj);
         131                 :     } else {
         132         4784398 :         rawSetter = other.rawSetter;
         133                 :     }
         134         4795528 :     return *this;
         135                 : }
         136                 :
         137                 : inline bool
         138        40885909 : BaseShape::matchesGetterSetter(PropertyOp rawGetter, StrictPropertyOp rawSetter) const
         139                 : {
         140        40885909 :     return rawGetter == this->rawGetter && rawSetter == this->rawSetter;
         141                 : }
         142                 :
         143                 : inline
         144         5396193 : StackBaseShape::StackBaseShape(Shape *shape)
         145         5396193 :   : flags(shape->getObjectFlags()),
         146         5396193 :     clasp(shape->getObjectClass()),
         147        10792386 :     parent(shape->getObjectParent())
         148                 : {
         149         5396193 :     updateGetterSetter(shape->attrs, shape->getter(), shape->setter());
         150         5396193 : }
         151                 :
         152                 : inline void
         153        29037065 : StackBaseShape::updateGetterSetter(uint8_t attrs,
         154                 :                                    PropertyOp rawGetter,
         155                 :                                    StrictPropertyOp rawSetter)
         156                 : {
         157        29037065 :     flags &= ~(BaseShape::HAS_GETTER_OBJECT | BaseShape::HAS_SETTER_OBJECT);
         158        29037065 :     if ((attrs & JSPROP_GETTER) && rawGetter)
         159         2442974 :         flags |= BaseShape::HAS_GETTER_OBJECT;
         160        29037065 :     if ((attrs & JSPROP_SETTER) && rawSetter)
         161          452280 :         flags |= BaseShape::HAS_SETTER_OBJECT;
         162                 :
         163        29037065 :     this->rawGetter = rawGetter;
         164        29037065 :     this->rawSetter = rawSetter;
         165        29037065 : }
         166                 :
         167                 : inline void
         168         4795528 : BaseShape::adoptUnowned(UnownedBaseShape *other)
         169                 : {
         170                 :     /*
         171                 :      * This is a base shape owned by a dictionary object, update it to reflect the
         172                 :      * unowned base shape of a new last property.
         173                 :      */
         174         4795528 :     JS_ASSERT(isOwned());
         175         9591056 :     DebugOnly<uint32_t> flags = getObjectFlags();
         176         4795528 :     JS_ASSERT((flags & other->getObjectFlags()) == flags);
         177                 :
         178         4795528 :     uint32_t span = slotSpan();
         179         4795528 :     PropertyTable *table = &this->table();
         180                 :
         181         4795528 :     *this = *other;
         182         4795528 :     setOwned(other);
         183         4795528 :     setTable(table);
         184         4795528 :     setSlotSpan(span);
         185                 :
         186         4795528 :     assertConsistency();
         187         4795528 : }
         188                 :
         189                 : inline void
         190         5150107 : BaseShape::setOwned(UnownedBaseShape *unowned)
         191                 : {
         192         5150107 :     flags |= OWNED_SHAPE;
         193         5150107 :     this->unowned_ = unowned;
         194         5150107 : }
         195                 :
         196                 : inline void
         197        20542154 : BaseShape::assertConsistency()
         198                 : {
         199                 : #ifdef DEBUG
         200        20542154 :     if (isOwned()) {
         201         6375984 :         UnownedBaseShape *unowned = baseUnowned();
         202         6375984 :         JS_ASSERT(hasGetterObject() == unowned->hasGetterObject());
         203         6375984 :         JS_ASSERT(hasSetterObject() == unowned->hasSetterObject());
         204         6375984 :         JS_ASSERT_IF(hasGetterObject(), getterObject() == unowned->getterObject());
         205         6375984 :         JS_ASSERT_IF(hasSetterObject(), setterObject() == unowned->setterObject());
         206         6375984 :         JS_ASSERT(getObjectParent() == unowned->getObjectParent());
         207         6375984 :         JS_ASSERT(getObjectFlags() == unowned->getObjectFlags());
         208                 :     }
         209                 : #endif
         210        20542154 : }
         211                 :
         212                 : inline
         213        28994900 : Shape::Shape(const StackShape &other, uint32_t nfixed)
         214                 :   : base_(other.base),
         215                 :     propid_(other.propid),
         216        28994900 :     slotInfo(other.maybeSlot() | (nfixed << FIXED_SLOTS_SHIFT)),
         217                 :     attrs(other.attrs),
         218                 :     flags(other.flags),
         219                 :     shortid_(other.shortid),
         220        57989800 :     parent(NULL)
         221                 : {
         222        28994900 :     kids.setNull();
         223        28994900 : }
         224                 :
         225                 : inline
         226         4726967 : Shape::Shape(UnownedBaseShape *base, uint32_t nfixed)
         227                 :   : base_(base),
         228                 :     propid_(JSID_EMPTY),
         229                 :     slotInfo(SHAPE_INVALID_SLOT | (nfixed << FIXED_SLOTS_SHIFT)),
         230                 :     attrs(JSPROP_SHARED),
         231                 :     flags(0),
         232                 :     shortid_(0),
         233         4726967 :     parent(NULL)
         234                 : {
         235         4726967 :     JS_ASSERT(base);
         236         4726967 :     kids.setNull();
         237         4726967 : }
         238                 :
         239                 : inline JSDHashNumber
         240        12359296 : StackShape::hash() const
         241                 : {
         242        12359296 :     JSDHashNumber hash = uintptr_t(base);
         243                 :
         244                 :     /* Accumulate from least to most random so the low bits are most random. */
         245        12359296 :     hash = JS_ROTATE_LEFT32(hash, 4) ^ (flags & Shape::PUBLIC_FLAGS);
         246        12359296 :     hash = JS_ROTATE_LEFT32(hash, 4) ^ attrs;
         247        12359296 :     hash = JS_ROTATE_LEFT32(hash, 4) ^ shortid;
         248        12359296 :     hash = JS_ROTATE_LEFT32(hash, 4) ^ slot_;
         249        12359296 :     hash = JS_ROTATE_LEFT32(hash, 4) ^ JSID_BITS(propid);
         250        12359296 :     return hash;
         251                 : }
         252                 :
         253                 : inline bool
         254          972994 : Shape::matches(const js::Shape *other) const
         255                 : {
         256          972994 :     return propid_.get() == other->propid_.get() &&
         257                 :            matchesParamsAfterId(other->base(), other->maybeSlot(), other->attrs,
         258          972994 :                                 other->flags, other->shortid_);
         259                 : }
         260                 :
         261                 : inline bool
         262        26463102 : Shape::matches(const StackShape &other) const
         263                 : {
         264        26463102 :     return propid_.get() == other.propid &&
         265        26463102 :            matchesParamsAfterId(other.base, other.slot_, other.attrs, other.flags, other.shortid);
         266                 : }
         267                 :
         268                 : inline bool
         269        29249614 : Shape::matchesParamsAfterId(BaseShape *base, uint32_t aslot,
         270                 :                             unsigned aattrs, unsigned aflags, int ashortid) const
         271                 : {
         272        29249614 :     return base->unowned() == this->base()->unowned() &&
         273        27887165 :            maybeSlot() == aslot &&
         274                 :            attrs == aattrs &&
         275                 :            ((flags ^ aflags) & PUBLIC_FLAGS) == 0 &&
         276        57136779 :            shortid_ == ashortid;
         277                 : }
         278                 :
         279                 : inline bool
         280         5392367 : Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const
         281                 : {
         282         5392367 :     JS_ASSERT(!hasDefaultGetter());
         283                 :
         284         5392367 :     if (hasGetterValue()) {
         285         3290567 :         JS_ASSERT(!isMethod());
         286         3290567 :         js::Value fval = getterValue();
         287         3290567 :         return js::InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
         288                 :     }
         289                 :
         290         2101800 :     if (isMethod()) {
         291            2279 :         vp->setObject(*pobj->nativeGetMethod(this));
         292            2279 :         return pobj->methodReadBarrier(cx, *this, vp);
         293                 :     }
         294                 :
         295                 :     /*
         296                 :      * |with (it) color;| ends up here, as do XML filter-expressions.
         297                 :      * Avoid exposing the With object to native getters.
         298                 :      */
         299         2099521 :     if (obj->isWith())
         300               0 :         obj = &obj->asWith().object();
         301         2099521 :     return js::CallJSPropertyOp(cx, getterOp(), receiver, getUserId(), vp);
         302                 : }
         303                 :
         304                 : inline bool
         305          348921 : Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const
         306                 : {
         307          348921 :     JS_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
         308                 :
         309          348921 :     if (attrs & JSPROP_SETTER) {
         310          145701 :         js::Value fval = setterValue();
         311          145701 :         return js::InvokeGetterOrSetter(cx, obj, fval, 1, vp, vp);
         312                 :     }
         313                 :
         314          203220 :     if (attrs & JSPROP_GETTER)
         315              12 :         return js_ReportGetterOnlyAssignment(cx);
         316                 :
         317                 :     /* See the comment in js::Shape::get as to why we check for With. */
         318          203208 :     if (obj->isWith())
         319               0 :         obj = &obj->asWith().object();
         320          203208 :     return js::CallJSPropertyOpSetter(cx, setterOp(), obj, getUserId(), strict, vp);
         321                 : }
         322                 :
         323                 : inline void
         324        28994900 : Shape::setParent(js::Shape *p)
         325                 : {
         326        62423683 :     JS_ASSERT_IF(p && !p->hasMissingSlot() && !inDictionary(),
         327        91418583 :                  p->maybeSlot() <= maybeSlot());
         328        65458110 :     JS_ASSERT_IF(p && !inDictionary(),
         329        94453010 :                  hasSlot() == (p->maybeSlot() != maybeSlot()));
         330        28994900 :     parent = p;
         331        28994900 : }
         332                 :
         333                 : inline void
         334         1510736 : Shape::removeFromDictionary(JSObject *obj)
         335                 : {
         336         1510736 :     JS_ASSERT(inDictionary());
         337         1510736 :     JS_ASSERT(obj->inDictionaryMode());
         338         1510736 :     JS_ASSERT(listp);
         339                 :
         340         1510736 :     JS_ASSERT(obj->shape_->inDictionary());
         341         1510736 :     JS_ASSERT(obj->shape_->listp == &obj->shape_);
         342                 :
         343         1510736 :     if (parent)
         344         1494087 :         parent->listp = listp;
         345         1510736 :     *listp = parent;
         346         1510736 :     listp = NULL;
         347         1510736 : }
         348                 :
         349                 : inline void
         350         8717032 : Shape::insertIntoDictionary(HeapPtrShape *dictp)
         351                 : {
         352                 :     /*
         353                 :      * Don't assert inDictionaryMode() here because we may be called from
         354                 :      * JSObject::toDictionaryMode via JSObject::newDictionaryShape.
         355                 :      */
         356         8717032 :     JS_ASSERT(inDictionary());
         357         8717032 :     JS_ASSERT(!listp);
         358                 :
         359         8717032 :     JS_ASSERT_IF(*dictp, (*dictp)->inDictionary());
         360         8717032 :     JS_ASSERT_IF(*dictp, (*dictp)->listp == dictp);
         361         8717032 :     JS_ASSERT_IF(*dictp, compartment() == (*dictp)->compartment());
         362                 :
         363         8717032 :     setParent(*dictp);
         364         8717032 :     if (parent)
         365         4624506 :         parent->listp = &parent;
         366         8717032 :     listp = (HeapPtrShape *) dictp;
         367         8717032 :     *dictp = this;
         368         8717032 : }
         369                 :
         370                 : void
         371         8717032 : Shape::initDictionaryShape(const StackShape &child, uint32_t nfixed, HeapPtrShape *dictp)
         372                 : {
         373         8717032 :     new (this) Shape(child, nfixed);
         374         8717032 :     this->flags |= IN_DICTIONARY;
         375                 :
         376         8717032 :     this->listp = NULL;
         377         8717032 :     insertIntoDictionary(dictp);
         378         8717032 : }
         379                 :
         380                 : inline
         381         3695434 : EmptyShape::EmptyShape(UnownedBaseShape *base, uint32_t nfixed)
         382         3695434 :   : js::Shape(base, nfixed)
         383                 : {
         384                 :     /* Only empty shapes can be NON_NATIVE. */
         385         3695434 :     if (!getObjectClass()->isNative())
         386           83986 :         flags |= NON_NATIVE;
         387         3695434 : }
         388                 :
         389                 : inline void
         390       101252043 : Shape::writeBarrierPre(const js::Shape *shape)
         391                 : {
         392                 : #ifdef JSGC_INCREMENTAL
         393       101252043 :     if (!shape)
         394        42722645 :         return;
         395                 :
         396        58529398 :     JSCompartment *comp = shape->compartment();
         397        58529398 :     if (comp->needsBarrier()) {
         398           11173 :         Shape *tmp = const_cast<Shape *>(shape);
         399           11173 :         MarkShapeUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
         400           11173 :         JS_ASSERT(tmp == shape);
         401                 :     }
         402                 : #endif
         403                 : }
         404                 :
         405                 : inline void
         406       146981991 : Shape::writeBarrierPost(const js::Shape *shape, void *addr)
         407                 : {
         408       146981991 : }
         409                 :
         410                 : inline void
         411       105170785 : Shape::readBarrier(const Shape *shape)
         412                 : {
         413                 : #ifdef JSGC_INCREMENTAL
         414       105170785 :     JSCompartment *comp = shape->compartment();
         415       105170785 :     if (comp->needsBarrier()) {
         416           20650 :         Shape *tmp = const_cast<Shape *>(shape);
         417           20650 :         MarkShapeUnbarriered(comp->barrierTracer(), &tmp, "read barrier");
         418           20650 :         JS_ASSERT(tmp == shape);
         419                 :     }
         420                 : #endif
         421       105170785 : }
         422                 :
         423                 : inline void
         424         3699693 : Shape::markChildren(JSTracer *trc)
         425                 : {
         426         3699693 :     MarkBaseShape(trc, &base_, "base");
         427         3699693 :     gc::MarkId(trc, &propidRef(), "propid");
         428         3699693 :     if (parent)
         429         3201079 :         MarkShape(trc, &parent, "parent");
         430         3699693 : }
         431                 :
         432                 : inline void
         433        15232782 : BaseShape::writeBarrierPre(BaseShape *base)
         434                 : {
         435                 : #ifdef JSGC_INCREMENTAL
         436        15232782 :     if (!base)
         437          354579 :         return;
         438                 :
         439        14878203 :     JSCompartment *comp = base->compartment();
         440        14878203 :     if (comp->needsBarrier()) {
         441            4026 :         BaseShape *tmp = base;
         442            4026 :         MarkBaseShapeUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
         443            4026 :         JS_ASSERT(tmp == base);
         444                 :     }
         445                 : #endif
         446                 : }
         447                 :
         448                 : inline void
         449        49309228 : BaseShape::writeBarrierPost(BaseShape *shape, void *addr)
         450                 : {
         451        49309228 : }
         452                 :
         453                 : inline void
         454        64098418 : BaseShape::readBarrier(BaseShape *base)
         455                 : {
         456                 : #ifdef JSGC_INCREMENTAL
         457        64098418 :     JSCompartment *comp = base->compartment();
         458        64098418 :     if (comp->needsBarrier()) {
         459            2498 :         BaseShape *tmp = base;
         460            2498 :         MarkBaseShapeUnbarriered(comp->barrierTracer(), &tmp, "read barrier");
         461            2498 :         JS_ASSERT(tmp == base);
         462                 :     }
         463                 : #endif
         464        64098418 : }
         465                 :
         466                 : inline void
         467         1144121 : BaseShape::markChildren(JSTracer *trc)
         468                 : {
         469         1144121 :     if (hasGetterObject())
         470          268265 :         MarkObjectUnbarriered(trc, &getterObj, "getter");
         471                 :
         472         1144121 :     if (hasSetterObject())
         473           64516 :         MarkObjectUnbarriered(trc, &setterObj, "setter");
         474                 :
         475         1144121 :     if (isOwned())
         476           38231 :         MarkBaseShape(trc, &unowned_, "base");
         477                 :
         478         1144121 :     if (parent)
         479         1095001 :         MarkObject(trc, &parent, "parent");
         480         1144121 : }
         481                 :
         482                 : } /* namespace js */
         483                 :
         484                 : #endif /* jsscopeinlines_h___ */

Generated by: LCOV version 1.7