Bug 1005898 - Make WebIDL properties on all globals own properties. r=bz.

--HG--
extra : rebase_source : 3eb201d073b090b2627814264a126a1a4281207f
This commit is contained in:
Peter Van der Beken 2014-02-15 22:12:34 +01:00
parent 309febb8bc
commit 05e48c378e
5 changed files with 106 additions and 31 deletions

View File

@ -1813,8 +1813,17 @@ nsWindowSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
const NativeProperties* eventTargetProperties =
EventTargetBinding::sNativePropertyHooks->mNativeProperties.regular;
return DefineWebIDLBindingPropertiesOnXPCObject(cx, window, windowProperties, true) &&
DefineWebIDLBindingPropertiesOnXPCObject(cx, window, eventTargetProperties, true) ?
if (!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, windowProperties) ||
!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, eventTargetProperties)) {
return NS_ERROR_FAILURE;
}
if (!GlobalPropertiesAreOwn()) {
return NS_OK;
}
return DefineWebIDLBindingPropertiesOnXPCObject(cx, window, windowProperties) &&
DefineWebIDLBindingPropertiesOnXPCObject(cx, window, eventTargetProperties) ?
NS_OK : NS_ERROR_FAILURE;
}

View File

@ -543,11 +543,23 @@ CreateInterfaceObject(JSContext* cx, JS::Handle<JSObject*> global,
return constructor;
}
bool
DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties)
{
if (properties->unforgeableAttributes &&
!DefinePrefable(cx, obj, properties->unforgeableAttributes)) {
return false;
}
return true;
}
bool
DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties,
bool defineUnforgeableAttributes)
const NativeProperties* properties)
{
if (properties->methods &&
!DefinePrefable(cx, obj, properties->methods)) {
@ -559,11 +571,6 @@ DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
return false;
}
if (defineUnforgeableAttributes && properties->unforgeableAttributes &&
!DefinePrefable(cx, obj, properties->unforgeableAttributes)) {
return false;
}
return true;
}
@ -576,45 +583,54 @@ CreateInterfacePrototypeObject(JSContext* cx, JS::Handle<JSObject*> global,
{
JS::Rooted<JSObject*> ourProto(cx,
JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global));
if (!ourProto) {
if (!ourProto ||
!DefineProperties(cx, ourProto, properties, chromeOnlyProperties)) {
return nullptr;
}
return ourProto;
}
bool
DefineProperties(JSContext* cx, JS::Handle<JSObject*> obj,
const NativeProperties* properties,
const NativeProperties* chromeOnlyProperties)
{
if (properties) {
if (properties->methods &&
!DefinePrefable(cx, ourProto, properties->methods)) {
return nullptr;
!DefinePrefable(cx, obj, properties->methods)) {
return false;
}
if (properties->attributes &&
!DefinePrefable(cx, ourProto, properties->attributes)) {
return nullptr;
!DefinePrefable(cx, obj, properties->attributes)) {
return false;
}
if (properties->constants &&
!DefinePrefable(cx, ourProto, properties->constants)) {
return nullptr;
!DefinePrefable(cx, obj, properties->constants)) {
return false;
}
}
if (chromeOnlyProperties) {
if (chromeOnlyProperties->methods &&
!DefinePrefable(cx, ourProto, chromeOnlyProperties->methods)) {
return nullptr;
!DefinePrefable(cx, obj, chromeOnlyProperties->methods)) {
return false;
}
if (chromeOnlyProperties->attributes &&
!DefinePrefable(cx, ourProto, chromeOnlyProperties->attributes)) {
return nullptr;
!DefinePrefable(cx, obj, chromeOnlyProperties->attributes)) {
return false;
}
if (chromeOnlyProperties->constants &&
!DefinePrefable(cx, ourProto, chromeOnlyProperties->constants)) {
return nullptr;
!DefinePrefable(cx, obj, chromeOnlyProperties->constants)) {
return false;
}
}
return ourProto;
return true;
}
void

View File

@ -581,6 +581,24 @@ CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
const NativeProperties* chromeOnlyProperties,
const char* name, bool defineOnGlobal);
/**
* Define the properties (regular and chrome-only) on obj.
*
* obj the object to instal the properties on. This should be the interface
* prototype object for regular interfaces and the instance object for
* interfaces marked with Global.
* properties contains the methods, attributes and constants to be defined on
* objects in any compartment.
* chromeProperties contains the methods, attributes and constants to be defined
* on objects in chrome compartments. This must be null if the
* interface doesn't have any ChromeOnly properties or if the
* object is being created in non-chrome compartment.
*/
bool
DefineProperties(JSContext* cx, JS::Handle<JSObject*> obj,
const NativeProperties* properties,
const NativeProperties* chromeOnlyProperties);
/*
* Define the unforgeable attributes on an object.
*/
@ -588,11 +606,15 @@ bool
DefineUnforgeableAttributes(JSContext* cx, JS::Handle<JSObject*> obj,
const Prefable<const JSPropertySpec>* props);
bool
DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties);
bool
DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties,
bool defineUnforgeableAttributes);
const NativeProperties* properties);
#ifdef _MSC_VER
#define HAS_MEMBER_CHECK(_name) \
@ -2661,6 +2683,15 @@ ConvertExceptionToPromise(JSContext* cx,
JSObject* promiseScope,
JS::MutableHandle<JS::Value> rval);
// While we wait for the outcome of spec discussions on whether properties for
// DOM global objects live on the object or the prototype, we supply this one
// place to switch the behaviour, so we can easily turn this off on branches.
inline bool
GlobalPropertiesAreOwn()
{
return true;
}
} // namespace dom
} // namespace mozilla

View File

@ -2482,13 +2482,17 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
else:
domClass = "nullptr"
if self.properties.hasNonChromeOnly():
isGlobal = self.descriptor.interface.getExtendedAttribute("Global") is not None
if not isGlobal and self.properties.hasNonChromeOnly():
properties = "&sNativeProperties"
elif self.properties.hasNonChromeOnly():
properties = "!GlobalPropertiesAreOwn() ? &sNativeProperties : nullptr"
else:
properties = "nullptr"
if self.properties.hasChromeOnly():
accessCheck = "nsContentUtils::ThreadsafeIsCallerChrome()"
chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
if not isGlobal and self.properties.hasChromeOnly():
chromeProperties = "nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
elif self.properties.hasChromeOnly():
chromeProperties = "!GlobalPropertiesAreOwn() && nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
else:
chromeProperties = "nullptr"
@ -2963,6 +2967,15 @@ class CGWrapGlobalMethod(CGAbstractMethod):
self.properties = properties
def definition_body(self):
if self.properties.hasNonChromeOnly():
properties = "GlobalPropertiesAreOwn() ? &sNativeProperties : nullptr"
else:
properties = "nullptr"
if self.properties.hasChromeOnly():
chromeProperties = "GlobalPropertiesAreOwn() && nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
else:
chromeProperties = "nullptr"
return fill(
"""
${assertions}
@ -2980,6 +2993,10 @@ class CGWrapGlobalMethod(CGAbstractMethod):
// obj is a new global, so has a new compartment. Enter it
// before doing anything with it.
JSAutoCompartment ac(aCx, obj);
if (!DefineProperties(aCx, obj, ${properties}, ${chromeProperties})) {
return nullptr;
}
$*{unforgeable}
$*{slots}
@ -2991,6 +3008,8 @@ class CGWrapGlobalMethod(CGAbstractMethod):
""",
assertions=AssertInheritanceChain(self.descriptor),
nativeType=self.descriptor.nativeType,
properties=properties,
chromeProperties=chromeProperties,
unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
slots=InitMemberSlots(self.descriptor, True))

View File

@ -143,11 +143,11 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *protoArg, unsigned flags,
if (entry->newBindingProperties) {
if (entry->newBindingProperties->regular) {
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->regular, false);
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->regular);
}
if (entry->newBindingProperties->chromeOnly &&
xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->chromeOnly, false);
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->chromeOnly);
}
}
// Next.