mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 205f8fa00772 (bug 1055755) for Android debug jsreftest permafail.
CLOSED TREE
This commit is contained in:
parent
50ef0a650b
commit
5119aa2dd9
@ -44,7 +44,8 @@ PreWrap(JSContext *cx, JS::HandleObject scope, JS::HandleObject obj,
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
Wrap(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent)
|
||||
Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj,
|
||||
JS::HandleObject parent)
|
||||
{
|
||||
return js::Wrapper::New(cx, obj, parent, &js::CrossCompartmentWrapper::singleton);
|
||||
}
|
||||
|
@ -801,10 +801,15 @@ typedef bool
|
||||
/*
|
||||
* Callback used to ask the embedding for the cross compartment wrapper handler
|
||||
* that implements the desired prolicy for this kind of object in the
|
||||
* destination compartment. |obj| is the object to be wrapped.
|
||||
* destination compartment. |obj| is the object to be wrapped. If |existing| is
|
||||
* non-nullptr, it will point to an existing wrapper object that should be
|
||||
* re-used if possible. |existing| is guaranteed to be a cross-compartment
|
||||
* wrapper with a lazily-defined prototype and the correct global. It is
|
||||
* guaranteed not to wrap a function.
|
||||
*/
|
||||
typedef JSObject *
|
||||
(* JSWrapObjectCallback)(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent);
|
||||
(* JSWrapObjectCallback)(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj,
|
||||
JS::HandleObject parent);
|
||||
|
||||
/*
|
||||
* Callback used by the wrap hook to ask the embedding to prepare an object
|
||||
|
@ -343,10 +343,12 @@ JSCompartment::wrap(JSContext *cx, MutableHandleString strp)
|
||||
}
|
||||
|
||||
bool
|
||||
JSCompartment::wrap(JSContext *cx, MutableHandleObject obj)
|
||||
JSCompartment::wrap(JSContext *cx, MutableHandleObject obj, HandleObject existingArg)
|
||||
{
|
||||
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(this));
|
||||
MOZ_ASSERT(cx->compartment() == this);
|
||||
MOZ_ASSERT_IF(existingArg, existingArg->compartment() == cx->compartment());
|
||||
MOZ_ASSERT_IF(existingArg, IsDeadProxyObject(existingArg));
|
||||
|
||||
if (!obj)
|
||||
return true;
|
||||
@ -419,7 +421,20 @@ JSCompartment::wrap(JSContext *cx, MutableHandleObject obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
obj.set(cb->wrap(cx, obj, global));
|
||||
RootedObject existing(cx, existingArg);
|
||||
if (existing) {
|
||||
// Is it possible to reuse |existing|?
|
||||
if (!existing->getTaggedProto().isLazy() ||
|
||||
// Note: Class asserted above, so all that's left to check is callability
|
||||
existing->isCallable() ||
|
||||
existing->getParent() != global ||
|
||||
obj->isCallable())
|
||||
{
|
||||
existing = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
obj.set(cb->wrap(cx, existing, obj, global));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -355,10 +355,12 @@ struct JSCompartment
|
||||
/* Mark cross-compartment wrappers. */
|
||||
void markCrossCompartmentWrappers(JSTracer *trc);
|
||||
|
||||
inline bool wrap(JSContext *cx, JS::MutableHandleValue vp);
|
||||
inline bool wrap(JSContext *cx, JS::MutableHandleValue vp,
|
||||
JS::HandleObject existing = js::NullPtr());
|
||||
|
||||
bool wrap(JSContext *cx, js::MutableHandleString strp);
|
||||
bool wrap(JSContext *cx, JS::MutableHandleObject obj);
|
||||
bool wrap(JSContext *cx, JS::MutableHandleObject obj,
|
||||
JS::HandleObject existingArg = js::NullPtr());
|
||||
bool wrap(JSContext *cx, JS::MutableHandle<js::PropertyDescriptor> desc);
|
||||
bool wrap(JSContext *cx, JS::MutableHandle<js::PropDesc> desc);
|
||||
|
||||
|
@ -54,8 +54,10 @@ js::AutoCompartment::~AutoCompartment()
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSCompartment::wrap(JSContext *cx, JS::MutableHandleValue vp)
|
||||
JSCompartment::wrap(JSContext *cx, JS::MutableHandleValue vp, JS::HandleObject existing)
|
||||
{
|
||||
MOZ_ASSERT_IF(existing, vp.isObject());
|
||||
|
||||
/* Only GC things have to be wrapped or copied. */
|
||||
if (!vp.isMarkable())
|
||||
return true;
|
||||
@ -112,7 +114,7 @@ JSCompartment::wrap(JSContext *cx, JS::MutableHandleValue vp)
|
||||
}
|
||||
|
||||
JS::RootedObject obj(cx, &vp.toObject());
|
||||
if (!wrap(cx, &obj))
|
||||
if (!wrap(cx, &obj, existing))
|
||||
return false;
|
||||
vp.setObject(*obj);
|
||||
MOZ_ASSERT_IF(cacheResult, obj == cacheResult);
|
||||
|
@ -72,7 +72,7 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
||||
static JSObject *New(JSContext *cx, JSObject *obj, JSObject *parent, const Wrapper *handler,
|
||||
const WrapperOptions &options = WrapperOptions());
|
||||
|
||||
static JSObject *Renew(JSContext *cx, JSObject *obj, const Wrapper *handler);
|
||||
static JSObject *Renew(JSContext *cx, JSObject *existing, JSObject *obj, const Wrapper *handler);
|
||||
|
||||
static const Wrapper *wrapperHandler(JSObject *wrapper);
|
||||
|
||||
@ -217,7 +217,8 @@ typedef SecurityWrapper<Wrapper> SameCompartmentSecurityWrapper;
|
||||
typedef SecurityWrapper<CrossCompartmentWrapper> CrossCompartmentSecurityWrapper;
|
||||
|
||||
extern JSObject *
|
||||
TransparentObjectWrapper(JSContext *cx, HandleObject obj, HandleObject parent);
|
||||
TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
|
||||
HandleObject parent);
|
||||
|
||||
inline bool
|
||||
IsWrapper(JSObject *obj)
|
||||
|
@ -526,17 +526,25 @@ js::RemapWrapper(JSContext *cx, JSObject *wobjArg, JSObject *newTargetArg)
|
||||
// immediately cease to be a cross-compartment wrapper. Neuter it.
|
||||
NukeCrossCompartmentWrapper(cx, wobj);
|
||||
|
||||
// First, we wrap it in the new compartment.
|
||||
// First, we wrap it in the new compartment. We try to use the existing
|
||||
// wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
|
||||
// the choice to reuse |wobj| or not.
|
||||
RootedObject tobj(cx, newTarget);
|
||||
AutoCompartment ac(cx, wobj);
|
||||
if (!wcompartment->wrap(cx, &tobj))
|
||||
if (!wcompartment->wrap(cx, &tobj, wobj))
|
||||
MOZ_CRASH();
|
||||
|
||||
// Now, because we need to maintain object identity, we do a brain
|
||||
// transplant on the old object so that it contains the contents of the
|
||||
// new one.
|
||||
if (!JSObject::swap(cx, wobj, tobj))
|
||||
MOZ_CRASH();
|
||||
// If wrap() reused |wobj|, it will have overwritten it and returned with
|
||||
// |tobj == wobj|. Otherwise, |tobj| will point to a new wrapper and |wobj|
|
||||
// will still be nuked. In the latter case, we replace |wobj| with the
|
||||
// contents of the new wrapper in |tobj|.
|
||||
if (tobj != wobj) {
|
||||
// Now, because we need to maintain object identity, we do a brain
|
||||
// transplant on the old object so that it contains the contents of the
|
||||
// new one.
|
||||
if (!JSObject::swap(cx, wobj, tobj))
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
// Before swapping, this wrapper came out of wrap(), which enforces the
|
||||
// invariant that the wrapper in the map points directly to the key.
|
||||
|
@ -833,6 +833,21 @@ js::NewProxyObject(JSContext *cx, const BaseProxyHandler *handler, HandleValue p
|
||||
options);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyObject::renew(JSContext *cx, const BaseProxyHandler *handler, Value priv)
|
||||
{
|
||||
MOZ_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this));
|
||||
MOZ_ASSERT(getParent() == cx->global());
|
||||
MOZ_ASSERT(getClass() == &ProxyObject::class_);
|
||||
MOZ_ASSERT(!getClass()->ext.innerObject);
|
||||
MOZ_ASSERT(hasLazyPrototype());
|
||||
|
||||
setHandler(handler);
|
||||
setCrossCompartmentPrivate(priv);
|
||||
setExtra(0, UndefinedValue());
|
||||
setExtra(1, UndefinedValue());
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_InitProxyClass(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
|
@ -42,6 +42,13 @@ Wrapper::New(JSContext *cx, JSObject *obj, JSObject *parent, const Wrapper *hand
|
||||
return NewProxyObject(cx, handler, priv, options.proto(), parent, options);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
Wrapper::Renew(JSContext *cx, JSObject *existing, JSObject *obj, const Wrapper *handler)
|
||||
{
|
||||
existing->as<ProxyObject>().renew(cx, handler, ObjectValue(*obj));
|
||||
return existing;
|
||||
}
|
||||
|
||||
const Wrapper *
|
||||
Wrapper::wrapperHandler(JSObject *wrapper)
|
||||
{
|
||||
@ -120,7 +127,8 @@ JSObject *Wrapper::defaultProto = TaggedProto::LazyProto;
|
||||
/* Compartments. */
|
||||
|
||||
extern JSObject *
|
||||
js::TransparentObjectWrapper(JSContext *cx, HandleObject obj, HandleObject parent)
|
||||
js::TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
|
||||
HandleObject parent)
|
||||
{
|
||||
// Allow wrapping outer window proxies.
|
||||
MOZ_ASSERT(!obj->is<WrapperObject>() || obj->getClass()->ext.innerObject);
|
||||
|
@ -99,6 +99,8 @@ class ProxyObject : public JSObject
|
||||
public:
|
||||
static unsigned grayLinkExtraSlot(JSObject *obj);
|
||||
|
||||
void renew(JSContext *cx, const BaseProxyHandler *handler, Value priv);
|
||||
|
||||
static void trace(JSTracer *trc, JSObject *obj);
|
||||
|
||||
void nuke(const BaseProxyHandler *handler);
|
||||
|
@ -382,7 +382,8 @@ SelectAddonWrapper(JSContext *cx, HandleObject obj, const Wrapper *wrapper)
|
||||
}
|
||||
|
||||
JSObject *
|
||||
WrapperFactory::Rewrap(JSContext *cx, HandleObject obj, HandleObject parent)
|
||||
WrapperFactory::Rewrap(JSContext *cx, HandleObject existing, HandleObject obj,
|
||||
HandleObject parent)
|
||||
{
|
||||
MOZ_ASSERT(!IsWrapper(obj) ||
|
||||
GetProxyHandler(obj) == &XrayWaiver ||
|
||||
@ -495,6 +496,9 @@ WrapperFactory::Rewrap(JSContext *cx, HandleObject obj, HandleObject parent)
|
||||
|
||||
DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target);
|
||||
|
||||
if (existing)
|
||||
return Wrapper::Renew(cx, existing, obj, wrapper);
|
||||
|
||||
return Wrapper::New(cx, obj, parent, wrapper);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ class WrapperFactory {
|
||||
|
||||
// Rewrap an object that is about to cross compartment boundaries.
|
||||
static JSObject *Rewrap(JSContext *cx,
|
||||
JS::HandleObject existing,
|
||||
JS::HandleObject obj,
|
||||
JS::HandleObject parent);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user