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

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

mercurial