mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 10:08:41 +00:00
Bug 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, move some code around. r=bholley.
--HG-- extra : rebase_source : 713a35d4bc7ffa4a25561823dbb0301a22565cb5
This commit is contained in:
parent
cbd064cb38
commit
307531531b
@ -941,16 +941,6 @@ GetNativePropertyHooks(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
return ifaceAndProtoJSClass->mNativeHooks;
|
||||
}
|
||||
|
||||
// Try to resolve a property as an unforgeable property from the given
|
||||
// NativeProperties, if it's there. nativeProperties is allowed to be null (in
|
||||
// which case we of course won't resolve anything).
|
||||
static bool
|
||||
XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder,
|
||||
const NativeProperties* nativeProperties);
|
||||
|
||||
static bool
|
||||
XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
const NativePropertyHooks* nativePropertyHooks,
|
||||
@ -959,58 +949,6 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder);
|
||||
|
||||
bool
|
||||
XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
cacheOnHolder = false;
|
||||
|
||||
DOMObjectType type;
|
||||
bool isGlobal;
|
||||
const NativePropertyHooks *nativePropertyHooks =
|
||||
GetNativePropertyHooks(cx, obj, type, isGlobal);
|
||||
|
||||
if (type != eInstance || (isGlobal && GlobalPropertiesAreOwn())) {
|
||||
// For prototype objects and interface objects, just return their
|
||||
// normal set of properties. For global objects the WebIDL properties live
|
||||
// on the instance objects, so resolve those here too.
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
|
||||
obj, id, desc, cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For non-global non-instance Xrays there are no other properties, so
|
||||
// return here for them whether we resolved the property or not.
|
||||
if (!isGlobal || desc.object()) {
|
||||
cacheOnHolder = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for unforgeable properties before doing mResolveOwnProperty weirdness
|
||||
const NativePropertiesHolder& nativeProperties =
|
||||
nativePropertyHooks->mNativeProperties;
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
|
||||
nativeProperties.regular)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
return true;
|
||||
}
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
|
||||
nativeProperties.chromeOnly)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !nativePropertyHooks->mResolveOwnProperty ||
|
||||
nativePropertyHooks->mResolveOwnProperty(cx, wrapper, obj, id, desc);
|
||||
}
|
||||
|
||||
static bool
|
||||
XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
@ -1113,6 +1051,9 @@ XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to resolve a property as an unforgeable property from the given
|
||||
// NativeProperties, if it's there. nativeProperties is allowed to be null (in
|
||||
// which case we of course won't resolve anything).
|
||||
/* static */ bool
|
||||
XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
@ -1264,6 +1205,97 @@ ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
return JS_WrapPropertyDescriptor(cx, desc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static void
|
||||
DEBUG_CheckXBLCallable(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
// In general, we shouldn't have cross-compartment wrappers here, because
|
||||
// we should be running in an XBL scope, and the content prototype should
|
||||
// contain wrappers to functions defined in the XBL scope. But if the node
|
||||
// has been adopted into another compartment, those prototypes will now point
|
||||
// to a different XBL scope (which is ok).
|
||||
MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(obj),
|
||||
xpc::IsContentXBLScope(js::GetObjectCompartment(js::UncheckedUnwrap(obj))));
|
||||
MOZ_ASSERT(JS::IsCallable(obj));
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_CheckXBLLookup(JSContext *cx, JSPropertyDescriptor *desc)
|
||||
{
|
||||
if (!desc->obj)
|
||||
return;
|
||||
if (!desc->value.isUndefined()) {
|
||||
MOZ_ASSERT(desc->value.isObject());
|
||||
DEBUG_CheckXBLCallable(cx, &desc->value.toObject());
|
||||
}
|
||||
if (desc->getter) {
|
||||
MOZ_ASSERT(desc->attrs & JSPROP_GETTER);
|
||||
DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->getter));
|
||||
}
|
||||
if (desc->setter) {
|
||||
MOZ_ASSERT(desc->attrs & JSPROP_SETTER);
|
||||
DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->setter));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define DEBUG_CheckXBLLookup(a, b) {}
|
||||
#endif
|
||||
|
||||
bool
|
||||
XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
cacheOnHolder = false;
|
||||
|
||||
DOMObjectType type;
|
||||
bool isGlobal;
|
||||
const NativePropertyHooks *nativePropertyHooks =
|
||||
GetNativePropertyHooks(cx, obj, type, isGlobal);
|
||||
|
||||
if (type != eInstance || (isGlobal && GlobalPropertiesAreOwn())) {
|
||||
// For prototype objects and interface objects, just return their
|
||||
// normal set of properties. For global objects the WebIDL properties live
|
||||
// on the instance objects, so resolve those here too.
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
|
||||
obj, id, desc, cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For non-global non-instance Xrays there are no other properties, so
|
||||
// return here for them whether we resolved the property or not.
|
||||
if (!isGlobal || desc.object()) {
|
||||
cacheOnHolder = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Check for unforgeable properties before doing mResolveOwnProperty weirdness
|
||||
const NativePropertiesHolder& nativeProperties =
|
||||
nativePropertyHooks->mNativeProperties;
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
|
||||
nativeProperties.regular)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
return true;
|
||||
}
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
|
||||
nativeProperties.chromeOnly)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return !nativePropertyHooks->mResolveOwnProperty ||
|
||||
nativePropertyHooks->mResolveOwnProperty(cx, wrapper, obj, id, desc);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
const NativePropertyHooks* nativePropertyHooks,
|
||||
|
@ -2954,6 +2954,12 @@ GlobalPropertiesAreOwn()
|
||||
void
|
||||
AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo,
|
||||
JS::Handle<JS::Value> aValue);
|
||||
|
||||
extern void
|
||||
DEBUG_CheckXBLLookup(JSContext *cx, JSPropertyDescriptor *desc);
|
||||
#else
|
||||
#define DEBUG_CheckXBLLookup(a, b) {}
|
||||
|
||||
#endif
|
||||
|
||||
// Returns true if aObj's global has any of the permissions named in aPermissions
|
||||
|
@ -1454,33 +1454,6 @@ XPCWrappedNativeXrayTraits::construct(JSContext *cx, HandleObject wrapper,
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject holder, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
bool unused;
|
||||
RootedObject obj(cx, getTargetObject(wrapper));
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, obj, id, desc, unused))
|
||||
return false;
|
||||
|
||||
if (!desc.object() &&
|
||||
id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING))
|
||||
{
|
||||
|
||||
JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, wrapper, "toString");
|
||||
if (!toString)
|
||||
return false;
|
||||
|
||||
FillPropertyDescriptor(desc, wrapper, 0,
|
||||
ObjectValue(*JS_GetFunctionObject(toString)));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, HandleObject wrapper,
|
||||
HandleObject holder, HandleId id,
|
||||
@ -1536,6 +1509,33 @@ DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, Handl
|
||||
JS_GetPropertyDescriptorById(cx, holder, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject holder, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
bool unused;
|
||||
RootedObject obj(cx, getTargetObject(wrapper));
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, obj, id, desc, unused))
|
||||
return false;
|
||||
|
||||
if (!desc.object() &&
|
||||
id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING))
|
||||
{
|
||||
|
||||
JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, wrapper, "toString");
|
||||
if (!toString)
|
||||
return false;
|
||||
|
||||
FillPropertyDescriptor(desc, wrapper, 0,
|
||||
ObjectValue(*JS_GetFunctionObject(toString)));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
@ -1771,43 +1771,6 @@ XrayToString(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static void
|
||||
DEBUG_CheckXBLCallable(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
// In general, we shouldn't have cross-compartment wrappers here, because
|
||||
// we should be running in an XBL scope, and the content prototype should
|
||||
// contain wrappers to functions defined in the XBL scope. But if the node
|
||||
// has been adopted into another compartment, those prototypes will now point
|
||||
// to a different XBL scope (which is ok).
|
||||
MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(obj),
|
||||
xpc::IsContentXBLScope(js::GetObjectCompartment(js::UncheckedUnwrap(obj))));
|
||||
MOZ_ASSERT(JS::IsCallable(obj));
|
||||
}
|
||||
|
||||
static void
|
||||
DEBUG_CheckXBLLookup(JSContext *cx, JSPropertyDescriptor *desc)
|
||||
{
|
||||
if (!desc->obj)
|
||||
return;
|
||||
if (!desc->value.isUndefined()) {
|
||||
MOZ_ASSERT(desc->value.isObject());
|
||||
DEBUG_CheckXBLCallable(cx, &desc->value.toObject());
|
||||
}
|
||||
if (desc->getter) {
|
||||
MOZ_ASSERT(desc->attrs & JSPROP_GETTER);
|
||||
DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->getter));
|
||||
}
|
||||
if (desc->setter) {
|
||||
MOZ_ASSERT(desc->attrs & JSPROP_SETTER);
|
||||
DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->setter));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define DEBUG_CheckXBLLookup(a, b) {}
|
||||
#endif
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
|
Loading…
x
Reference in New Issue
Block a user