mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1131802 part 2. Allocate functions with reserved slots for DOM Xrays so we can store the Xray wrapper reference in those slots instead of as the function parent. r=peterv
This commit is contained in:
parent
50c7447b70
commit
a94ca36434
@ -981,6 +981,27 @@ GetNativePropertyHooks(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
return ifaceAndProtoJSClass->mNativeHooks;
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
XrayCreateFunction(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JSNativeWrapper native, unsigned nargs, JS::Handle<jsid> id)
|
||||
{
|
||||
JSFunction* fun = js::NewFunctionByIdWithReserved(cx, native.op, nargs, 0,
|
||||
/* parent = */nullptr, id);
|
||||
if (!fun) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SET_JITINFO(fun, native.info);
|
||||
JSObject* obj = JS_GetFunctionObject(fun);
|
||||
js::SetFunctionNativeReserved(obj, XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT,
|
||||
JS::ObjectValue(*wrapper));
|
||||
#ifdef DEBUG
|
||||
js::SetFunctionNativeReserved(obj, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF,
|
||||
JS::ObjectValue(*obj));
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
static bool
|
||||
XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
@ -1003,23 +1024,18 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
// way to do this is wrap them up as functions ourselves.
|
||||
desc.setAttributes(attrSpec.flags);
|
||||
// They all have getters, so we can just make it.
|
||||
JS::Rooted<JSFunction*> fun(cx,
|
||||
JS_NewFunctionById(cx, attrSpec.getter.native.op,
|
||||
0, 0, wrapper, id));
|
||||
if (!fun)
|
||||
JS::Rooted<JSObject*> funobj(cx,
|
||||
XrayCreateFunction(cx, wrapper, attrSpec.getter.native, 0, id));
|
||||
if (!funobj)
|
||||
return false;
|
||||
SET_JITINFO(fun, attrSpec.getter.native.info);
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
desc.setGetterObject(funobj);
|
||||
desc.attributesRef() |= JSPROP_GETTER;
|
||||
if (attrSpec.setter.native.op) {
|
||||
// We have a setter! Make it.
|
||||
fun = JS_NewFunctionById(cx, attrSpec.setter.native.op, 1, 0,
|
||||
wrapper, id);
|
||||
if (!fun)
|
||||
funobj =
|
||||
XrayCreateFunction(cx, wrapper, attrSpec.setter.native, 1, id);
|
||||
if (!funobj)
|
||||
return false;
|
||||
SET_JITINFO(fun, attrSpec.setter.native.info);
|
||||
funobj = JS_GetFunctionObject(fun);
|
||||
desc.setSetterObject(funobj);
|
||||
desc.attributesRef() |= JSPROP_SETTER;
|
||||
} else {
|
||||
@ -1054,22 +1070,24 @@ XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
cacheOnHolder = true;
|
||||
|
||||
const JSFunctionSpec& methodSpec = methodSpecs[i];
|
||||
JSFunction *fun;
|
||||
JSObject *funobj;
|
||||
if (methodSpec.selfHostedName) {
|
||||
fun = JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id, methodSpec.nargs);
|
||||
JSFunction* fun =
|
||||
JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id,
|
||||
methodSpec.nargs);
|
||||
if (!fun) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(!methodSpec.call.op, "Bad FunctionSpec declaration: non-null native");
|
||||
MOZ_ASSERT(!methodSpec.call.info, "Bad FunctionSpec declaration: non-null jitinfo");
|
||||
funobj = JS_GetFunctionObject(fun);
|
||||
} else {
|
||||
fun = JS_NewFunctionById(cx, methodSpec.call.op, methodSpec.nargs, 0, wrapper, id);
|
||||
if (!fun) {
|
||||
funobj = XrayCreateFunction(cx, wrapper, methodSpec.call,
|
||||
methodSpec.nargs, id);
|
||||
if (!funobj) {
|
||||
return false;
|
||||
}
|
||||
SET_JITINFO(fun, methodSpec.call.info);
|
||||
}
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
desc.value().setObject(*funobj);
|
||||
desc.setAttributes(methodSpec.flags);
|
||||
desc.object().set(wrapper);
|
||||
|
@ -119,10 +119,25 @@ JSObject *
|
||||
XrayAwareCalleeGlobal(JSObject *fun)
|
||||
{
|
||||
MOZ_ASSERT(js::IsFunctionObject(fun));
|
||||
JSObject *scope = js::GetObjectParent(fun);
|
||||
if (IsXrayWrapper(scope))
|
||||
scope = js::UncheckedUnwrap(scope);
|
||||
return js::GetGlobalForObjectCrossCompartment(scope);
|
||||
|
||||
if (!js::FunctionHasNativeReserved(fun)) {
|
||||
// Just a normal function, no Xrays involved.
|
||||
return js::GetGlobalForObjectCrossCompartment(fun);
|
||||
}
|
||||
|
||||
// The functions we expect here have the Xray wrapper they're associated with
|
||||
// in their XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT and, in a debug build,
|
||||
// themselves in their XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF. Assert that
|
||||
// last bit.
|
||||
MOZ_ASSERT(&js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF).toObject() ==
|
||||
fun);
|
||||
|
||||
Value v =
|
||||
js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT);
|
||||
MOZ_ASSERT(IsXrayWrapper(&v.toObject()));
|
||||
|
||||
JSObject *xrayTarget = js::UncheckedUnwrap(&v.toObject());
|
||||
return js::GetGlobalForObjectCrossCompartment(xrayTarget);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
@ -14,6 +14,14 @@
|
||||
#include "jswrapper.h"
|
||||
#include "js/Proxy.h"
|
||||
|
||||
// Slot where Xray functions for Web IDL methods store a pointer to
|
||||
// the Xray wrapper they're associated with.
|
||||
#define XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT 0
|
||||
// Slot where in debug builds Xray functions for Web IDL methods store
|
||||
// a pointer to their themselves, just so we can assert that they're the
|
||||
// sort of functions we expect.
|
||||
#define XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF 1
|
||||
|
||||
// Xray wrappers re-resolve the original native properties on the native
|
||||
// object and always directly access to those properties.
|
||||
// Because they work so differently from the rest of the wrapper hierarchy,
|
||||
|
Loading…
Reference in New Issue
Block a user