2013-04-16 13:47:10 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
2012-12-05 17:44:49 -08:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2013-06-19 17:59:46 -07:00
|
|
|
#ifndef jscompartmentinlines_h
|
|
|
|
#define jscompartmentinlines_h
|
2012-12-05 17:44:49 -08:00
|
|
|
|
2013-04-23 23:44:36 -07:00
|
|
|
#include "jscompartment.h"
|
|
|
|
|
2013-03-16 20:36:37 -07:00
|
|
|
inline void
|
|
|
|
JSCompartment::initGlobal(js::GlobalObject &global)
|
|
|
|
{
|
|
|
|
JS_ASSERT(global.compartment() == this);
|
|
|
|
JS_ASSERT(!global_);
|
|
|
|
global_ = &global;
|
|
|
|
}
|
|
|
|
|
2012-12-05 17:44:49 -08:00
|
|
|
js::GlobalObject *
|
|
|
|
JSCompartment::maybeGlobal() const
|
|
|
|
{
|
|
|
|
JS_ASSERT_IF(global_, global_->compartment() == this);
|
|
|
|
return global_;
|
|
|
|
}
|
|
|
|
|
2013-07-19 07:06:02 -07:00
|
|
|
js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSObject *target)
|
2012-12-05 17:44:49 -08:00
|
|
|
: cx_(cx),
|
2013-07-19 07:06:02 -07:00
|
|
|
origin_(cx->compartment_)
|
2012-12-05 17:44:49 -08:00
|
|
|
{
|
|
|
|
cx_->enterCompartment(target->compartment());
|
|
|
|
}
|
|
|
|
|
2013-07-17 11:53:52 -07:00
|
|
|
js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSCompartment *target)
|
2013-07-19 07:06:02 -07:00
|
|
|
: cx_(cx),
|
|
|
|
origin_(cx_->compartment_)
|
2013-07-17 11:53:52 -07:00
|
|
|
{
|
|
|
|
cx_->enterCompartment(target);
|
|
|
|
}
|
|
|
|
|
2012-12-05 17:44:49 -08:00
|
|
|
js::AutoCompartment::~AutoCompartment()
|
|
|
|
{
|
|
|
|
cx_->leaveCompartment(origin_);
|
|
|
|
}
|
|
|
|
|
2013-08-26 09:46:21 -07:00
|
|
|
inline bool
|
|
|
|
JSCompartment::wrap(JSContext *cx, JS::MutableHandleValue vp, JS::HandleObject existing)
|
|
|
|
{
|
|
|
|
JS_ASSERT_IF(existing, vp.isObject());
|
|
|
|
|
|
|
|
/* Only GC things have to be wrapped or copied. */
|
|
|
|
if (!vp.isMarkable())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/* Handle strings. */
|
|
|
|
if (vp.isString()) {
|
2013-08-27 15:16:03 -07:00
|
|
|
JS::RootedString str(cx, vp.toString());
|
|
|
|
if (!wrap(cx, str.address()))
|
2013-08-26 09:46:21 -07:00
|
|
|
return false;
|
|
|
|
vp.setString(str);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
JS_ASSERT(vp.isObject());
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All that's left are objects.
|
|
|
|
*
|
|
|
|
* Object wrapping isn't the fastest thing in the world, in part because
|
|
|
|
* we have to unwrap and invoke the prewrap hook to find the identity
|
|
|
|
* object before we even start checking the cache. Neither of these
|
|
|
|
* operations are needed in the common case, where we're just wrapping
|
|
|
|
* a plain JS object from the wrappee's side of the membrane to the
|
|
|
|
* wrapper's side.
|
|
|
|
*
|
|
|
|
* To optimize this, we note that the cache should only ever contain
|
|
|
|
* identity objects - that is to say, objects that serve as the
|
|
|
|
* canonical representation for a unique object identity observable by
|
|
|
|
* script. Unwrap and prewrap are both steps that we take to get to the
|
|
|
|
* identity of an incoming objects, and as such, they shuld never map
|
|
|
|
* one identity object to another object. This means that we can safely
|
|
|
|
* check the cache immediately, and only risk false negatives. Do this
|
|
|
|
* in opt builds, and do both in debug builds so that we can assert
|
|
|
|
* that we get the same answer.
|
|
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
|
|
JS::RootedObject cacheResult(cx);
|
|
|
|
#endif
|
|
|
|
JS::RootedValue v(cx, vp);
|
|
|
|
if (js::WrapperMap::Ptr p = crossCompartmentWrappers.lookup(v)) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
cacheResult = &p->value.get().toObject();
|
|
|
|
#else
|
|
|
|
vp.set(p->value);
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
JS::RootedObject obj(cx, &vp.toObject());
|
|
|
|
if (!wrap(cx, &obj, existing))
|
|
|
|
return false;
|
|
|
|
vp.setObject(*obj);
|
|
|
|
JS_ASSERT_IF(cacheResult, obj == cacheResult);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-06-19 17:59:46 -07:00
|
|
|
#endif /* jscompartmentinlines_h */
|