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.h"
14 #include "jscntxtinlines.h"
17 JSCompartment::initGlobal(js::GlobalObject
& global
)
19 MOZ_ASSERT(global
.compartment() == this);
25 JSCompartment::maybeGlobal() const
27 MOZ_ASSERT_IF(global_
, global_
->compartment() == this);
32 JSCompartment::unsafeUnbarrieredMaybeGlobal() const
34 return *global_
.unsafeGet();
37 js::AutoCompartment::AutoCompartment(ExclusiveContext
* cx
, JSObject
* target
)
39 origin_(cx
->compartment_
)
41 cx_
->enterCompartment(target
->compartment());
44 js::AutoCompartment::AutoCompartment(ExclusiveContext
* cx
, JSCompartment
* target
)
46 origin_(cx_
->compartment_
)
48 cx_
->enterCompartment(target
);
51 js::AutoCompartment::~AutoCompartment()
53 cx_
->leaveCompartment(origin_
);
57 JSCompartment::wrap(JSContext
* cx
, JS::MutableHandleValue vp
, JS::HandleObject existing
)
59 MOZ_ASSERT_IF(existing
, vp
.isObject());
61 /* Only GC things have to be wrapped or copied. */
66 * Symbols are GC things, but never need to be wrapped or copied because
67 * they are always allocated in the atoms compartment.
74 JS::RootedString
str(cx
, vp
.toString());
81 MOZ_ASSERT(vp
.isObject());
84 * All that's left are objects.
86 * Object wrapping isn't the fastest thing in the world, in part because
87 * we have to unwrap and invoke the prewrap hook to find the identity
88 * object before we even start checking the cache. Neither of these
89 * operations are needed in the common case, where we're just wrapping
90 * a plain JS object from the wrappee's side of the membrane to the
93 * To optimize this, we note that the cache should only ever contain
94 * identity objects - that is to say, objects that serve as the
95 * canonical representation for a unique object identity observable by
96 * script. Unwrap and prewrap are both steps that we take to get to the
97 * identity of an incoming objects, and as such, they shuld never map
98 * one identity object to another object. This means that we can safely
99 * check the cache immediately, and only risk false negatives. Do this
100 * in opt builds, and do both in debug builds so that we can assert
101 * that we get the same answer.
104 JS::RootedObject
cacheResult(cx
);
106 JS::RootedValue
v(cx
, vp
);
107 if (js::WrapperMap::Ptr p
= crossCompartmentWrappers
.lookup(js::CrossCompartmentKey(v
))) {
109 cacheResult
= &p
->value().get().toObject();
116 JS::RootedObject
obj(cx
, &vp
.toObject());
117 if (!wrap(cx
, &obj
, existing
))
120 MOZ_ASSERT_IF(cacheResult
, obj
== cacheResult
);
124 #endif /* jscompartmentinlines_h */