LCOV - code coverage report
Current view: top level - js/src - jscompartmentinlines.h (source / functions) Hit Total Coverage
Test: output.info Lines: 65 70 92.9 %
Date: 2017-07-14 16:53:18 Functions: 15 28 53.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jscompartmentinlines_h
       8             : #define jscompartmentinlines_h
       9             : 
      10             : #include "jscompartment.h"
      11             : #include "jsiter.h"
      12             : 
      13             : #include "gc/Barrier.h"
      14             : 
      15             : #include "jscntxtinlines.h"
      16             : 
      17             : inline void
      18         311 : JSCompartment::initGlobal(js::GlobalObject& global)
      19             : {
      20         311 :     MOZ_ASSERT(global.compartment() == this);
      21         311 :     MOZ_ASSERT(!global_);
      22         311 :     global_.set(&global);
      23         311 : }
      24             : 
      25             : js::GlobalObject*
      26       15613 : JSCompartment::maybeGlobal() const
      27             : {
      28       15613 :     MOZ_ASSERT_IF(global_, global_->compartment() == this);
      29       15613 :     return global_;
      30             : }
      31             : 
      32             : js::GlobalObject*
      33      124745 : JSCompartment::unsafeUnbarrieredMaybeGlobal() const
      34             : {
      35      124745 :     return *global_.unsafeGet();
      36             : }
      37             : 
      38             : template <typename T>
      39       21012 : js::AutoCompartment::AutoCompartment(JSContext* cx, const T& target)
      40             :   : cx_(cx),
      41       21012 :     origin_(cx->compartment()),
      42       42024 :     maybeLock_(nullptr)
      43             : {
      44       21012 :     cx_->enterCompartmentOf(target);
      45       21012 : }
      46             : 
      47             : // Protected constructor that bypasses assertions in enterCompartmentOf. Used
      48             : // only for entering the atoms compartment.
      49       62625 : js::AutoCompartment::AutoCompartment(JSContext* cx, JSCompartment* target,
      50       62625 :                                      js::AutoLockForExclusiveAccess& lock)
      51             :   : cx_(cx),
      52       62625 :     origin_(cx->compartment()),
      53      125250 :     maybeLock_(&lock)
      54             : {
      55       62625 :     MOZ_ASSERT(target->isAtomsCompartment());
      56       62625 :     cx_->enterAtomsCompartment(target, lock);
      57       62625 : }
      58             : 
      59             : // Protected constructor that bypasses assertions in enterCompartmentOf. Should
      60             : // not be used to enter the atoms compartment.
      61       13101 : js::AutoCompartment::AutoCompartment(JSContext* cx, JSCompartment* target)
      62             :   : cx_(cx),
      63       13101 :     origin_(cx->compartment()),
      64       26202 :     maybeLock_(nullptr)
      65             : {
      66       13101 :     MOZ_ASSERT(!target->isAtomsCompartment());
      67       13101 :     cx_->enterNonAtomsCompartment(target);
      68       13101 : }
      69             : 
      70      193483 : js::AutoCompartment::~AutoCompartment()
      71             : {
      72       96740 :     cx_->leaveCompartment(origin_, maybeLock_);
      73       96743 : }
      74             : 
      75       62625 : js::AutoAtomsCompartment::AutoAtomsCompartment(JSContext* cx,
      76       62625 :                                                js::AutoLockForExclusiveAccess& lock)
      77       62625 :   : AutoCompartment(cx, cx->atomsCompartment(lock), lock)
      78       62625 : {}
      79             : 
      80       13101 : js::AutoCompartmentUnchecked::AutoCompartmentUnchecked(JSContext* cx, JSCompartment* target)
      81       13101 :   : AutoCompartment(cx, target)
      82       13101 : {}
      83             : 
      84             : inline bool
      85       40415 : JSCompartment::wrap(JSContext* cx, JS::MutableHandleValue vp)
      86             : {
      87             :     /* Only GC things have to be wrapped or copied. */
      88       40415 :     if (!vp.isGCThing())
      89       11180 :         return true;
      90             : 
      91             :     /*
      92             :      * Symbols are GC things, but never need to be wrapped or copied because
      93             :      * they are always allocated in the atoms compartment. They still need to
      94             :      * be marked in the new compartment's zone, however.
      95             :      */
      96       29235 :     if (vp.isSymbol()) {
      97           0 :         cx->markAtomValue(vp);
      98           0 :         return true;
      99             :     }
     100             : 
     101             :     /* Handle strings. */
     102       29235 :     if (vp.isString()) {
     103       10894 :         JS::RootedString str(cx, vp.toString());
     104        5447 :         if (!wrap(cx, &str))
     105           0 :             return false;
     106        5447 :         vp.setString(str);
     107        5447 :         return true;
     108             :     }
     109             : 
     110       23788 :     MOZ_ASSERT(vp.isObject());
     111             : 
     112             :     /*
     113             :      * All that's left are objects.
     114             :      *
     115             :      * Object wrapping isn't the fastest thing in the world, in part because
     116             :      * we have to unwrap and invoke the prewrap hook to find the identity
     117             :      * object before we even start checking the cache. Neither of these
     118             :      * operations are needed in the common case, where we're just wrapping
     119             :      * a plain JS object from the wrappee's side of the membrane to the
     120             :      * wrapper's side.
     121             :      *
     122             :      * To optimize this, we note that the cache should only ever contain
     123             :      * identity objects - that is to say, objects that serve as the
     124             :      * canonical representation for a unique object identity observable by
     125             :      * script. Unwrap and prewrap are both steps that we take to get to the
     126             :      * identity of an incoming objects, and as such, they shuld never map
     127             :      * one identity object to another object. This means that we can safely
     128             :      * check the cache immediately, and only risk false negatives. Do this
     129             :      * in opt builds, and do both in debug builds so that we can assert
     130             :      * that we get the same answer.
     131             :      */
     132             : #ifdef DEBUG
     133       23788 :     MOZ_ASSERT(JS::ValueIsNotGray(vp));
     134       47576 :     JS::RootedObject cacheResult(cx);
     135             : #endif
     136       47576 :     JS::RootedValue v(cx, vp);
     137       23788 :     if (js::WrapperMap::Ptr p = crossCompartmentWrappers.lookup(js::CrossCompartmentKey(v))) {
     138             : #ifdef DEBUG
     139        5607 :         cacheResult = &p->value().get().toObject();
     140             : #else
     141             :         vp.set(p->value().get());
     142             :         return true;
     143             : #endif
     144             :     }
     145             : 
     146       47576 :     JS::RootedObject obj(cx, &vp.toObject());
     147       23788 :     if (!wrap(cx, &obj))
     148           0 :         return false;
     149       23788 :     vp.setObject(*obj);
     150       23788 :     MOZ_ASSERT_IF(cacheResult, obj == cacheResult);
     151       23788 :     return true;
     152             : }
     153             : 
     154             : MOZ_ALWAYS_INLINE bool
     155         888 : JSCompartment::objectMaybeInIteration(JSObject* obj)
     156             : {
     157         888 :     MOZ_ASSERT(obj->compartment() == this);
     158             : 
     159             :     // If the list is empty we're not iterating any objects.
     160         888 :     js::NativeIterator* next = enumerators->next();
     161         888 :     if (enumerators == next)
     162         882 :         return false;
     163             : 
     164             :     // If the list contains a single object, check if it's |obj|.
     165           6 :     if (next->next() == enumerators)
     166           6 :         return next->obj == obj;
     167             : 
     168           0 :     return true;
     169             : }
     170             : 
     171             : #endif /* jscompartmentinlines_h */

Generated by: LCOV version 1.13