js/src/jscompartmentinlines.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     7 #ifndef jscompartmentinlines_h
     8 #define jscompartmentinlines_h
    10 #include "jscompartment.h"
    12 #include "gc/Barrier-inl.h"
    14 inline void
    15 JSCompartment::initGlobal(js::GlobalObject &global)
    16 {
    17     JS_ASSERT(global.compartment() == this);
    18     JS_ASSERT(!global_);
    19     global_ = &global;
    20 }
    22 js::GlobalObject *
    23 JSCompartment::maybeGlobal() const
    24 {
    25     JS_ASSERT_IF(global_, global_->compartment() == this);
    26     return global_;
    27 }
    29 js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSObject *target)
    30   : cx_(cx),
    31     origin_(cx->compartment_)
    32 {
    33     cx_->enterCompartment(target->compartment());
    34 }
    36 js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSCompartment *target)
    37   : cx_(cx),
    38     origin_(cx_->compartment_)
    39 {
    40     cx_->enterCompartment(target);
    41 }
    43 js::AutoCompartment::~AutoCompartment()
    44 {
    45     cx_->leaveCompartment(origin_);
    46 }
    48 inline bool
    49 JSCompartment::wrap(JSContext *cx, JS::MutableHandleValue vp, JS::HandleObject existing)
    50 {
    51     JS_ASSERT_IF(existing, vp.isObject());
    53     /* Only GC things have to be wrapped or copied. */
    54     if (!vp.isMarkable())
    55         return true;
    57     /* Handle strings. */
    58     if (vp.isString()) {
    59         JS::RootedString str(cx, vp.toString());
    60         if (!wrap(cx, str.address()))
    61             return false;
    62         vp.setString(str);
    63         return true;
    64     }
    66     JS_ASSERT(vp.isObject());
    68     /*
    69      * All that's left are objects.
    70      *
    71      * Object wrapping isn't the fastest thing in the world, in part because
    72      * we have to unwrap and invoke the prewrap hook to find the identity
    73      * object before we even start checking the cache. Neither of these
    74      * operations are needed in the common case, where we're just wrapping
    75      * a plain JS object from the wrappee's side of the membrane to the
    76      * wrapper's side.
    77      *
    78      * To optimize this, we note that the cache should only ever contain
    79      * identity objects - that is to say, objects that serve as the
    80      * canonical representation for a unique object identity observable by
    81      * script. Unwrap and prewrap are both steps that we take to get to the
    82      * identity of an incoming objects, and as such, they shuld never map
    83      * one identity object to another object. This means that we can safely
    84      * check the cache immediately, and only risk false negatives. Do this
    85      * in opt builds, and do both in debug builds so that we can assert
    86      * that we get the same answer.
    87      */
    88 #ifdef DEBUG
    89     JS::RootedObject cacheResult(cx);
    90 #endif
    91     JS::RootedValue v(cx, vp);
    92     if (js::WrapperMap::Ptr p = crossCompartmentWrappers.lookup(v)) {
    93 #ifdef DEBUG
    94         cacheResult = &p->value().get().toObject();
    95 #else
    96         vp.set(p->value());
    97         return true;
    98 #endif
    99     }
   101     JS::RootedObject obj(cx, &vp.toObject());
   102     if (!wrap(cx, &obj, existing))
   103         return false;
   104     vp.setObject(*obj);
   105     JS_ASSERT_IF(cacheResult, obj == cacheResult);
   106     return true;
   107 }
   109 #endif /* jscompartmentinlines_h */

mercurial