Thu, 15 Jan 2015 15:55:04 +0100
Back out 97036ab72558 which inappropriately compared turds to third parties.
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 */