mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
163762c085
--HG-- extra : rebase_source : d4faf130a8022f335ae0ddcd4e02fdc59109d47d
110 lines
3.2 KiB
C
110 lines
3.2 KiB
C
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
* 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/. */
|
|
|
|
#ifndef jscompartmentinlines_h
|
|
#define jscompartmentinlines_h
|
|
|
|
#include "jscompartment.h"
|
|
|
|
#include "gc/Barrier-inl.h"
|
|
|
|
inline void
|
|
JSCompartment::initGlobal(js::GlobalObject &global)
|
|
{
|
|
JS_ASSERT(global.compartment() == this);
|
|
JS_ASSERT(!global_);
|
|
global_ = &global;
|
|
}
|
|
|
|
js::GlobalObject *
|
|
JSCompartment::maybeGlobal() const
|
|
{
|
|
JS_ASSERT_IF(global_, global_->compartment() == this);
|
|
return global_;
|
|
}
|
|
|
|
js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSObject *target)
|
|
: cx_(cx),
|
|
origin_(cx->compartment_)
|
|
{
|
|
cx_->enterCompartment(target->compartment());
|
|
}
|
|
|
|
js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSCompartment *target)
|
|
: cx_(cx),
|
|
origin_(cx_->compartment_)
|
|
{
|
|
cx_->enterCompartment(target);
|
|
}
|
|
|
|
js::AutoCompartment::~AutoCompartment()
|
|
{
|
|
cx_->leaveCompartment(origin_);
|
|
}
|
|
|
|
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()) {
|
|
JS::RootedString str(cx, vp.toString());
|
|
if (!wrap(cx, str.address()))
|
|
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;
|
|
}
|
|
|
|
#endif /* jscompartmentinlines_h */
|