Fix for bug 785188 (Make Xrays work with newest DOM list bindings). r=mrbkap.

This commit is contained in:
Peter Van der Beken 2012-06-06 21:52:26 +02:00
parent 59f47be2a6
commit cb66e04e69
5 changed files with 86 additions and 22 deletions

View File

@ -72,12 +72,17 @@ class CGNativePropertyHooks(CGThing):
def define(self):
if self.descriptor.workers:
return ""
if self.descriptor.concrete and self.descriptor.proxy:
resolveOwnProperty = "ResolveOwnProperty"
enumerateOwnProperties = "EnumerateOwnProperties"
else:
enumerateOwnProperties = resolveOwnProperty = "NULL"
parent = self.descriptor.interface.parent
parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::NativeHooks"
if parent else 'NULL')
return """
const NativePropertyHooks NativeHooks = { ResolveProperty, EnumerateProperties, %s };
""" % parentHooks
const NativePropertyHooks NativeHooks = { %s, ResolveProperty, %s, EnumerateProperties, %s };
""" % (resolveOwnProperty, enumerateOwnProperties, parentHooks)
def DOMClass(descriptor):
protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain]
@ -4202,6 +4207,37 @@ class CGClass(CGThing):
result = result + memberString
return result
class CGResolveOwnProperty(CGAbstractMethod):
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
Argument('jsid', 'id'), Argument('bool', 'set'),
Argument('JSPropertyDescriptor*', 'desc')]
CGAbstractMethod.__init__(self, descriptor, "ResolveOwnProperty", "bool", args)
def definition_body(self):
return """ JSObject* obj = wrapper;
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
obj = js::UnwrapObject(obj);
}
// We rely on getOwnPropertyDescriptor not shadowing prototype properties by named
// properties. If that changes we'll need to filter here.
return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, set, desc);
"""
class CGEnumerateOwnProperties(CGAbstractMethod):
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
Argument('JS::AutoIdVector&', 'props')]
CGAbstractMethod.__init__(self, descriptor, "EnumerateOwnProperties", "bool", args)
def definition_body(self):
return """ JSObject* obj = wrapper;
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
obj = js::UnwrapObject(obj);
}
// We rely on getOwnPropertyNames not shadowing prototype properties by named
// properties. If that changes we'll need to filter here.
return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
"""
class CGXrayHelper(CGAbstractMethod):
def __init__(self, descriptor, name, args, properties):
CGAbstractMethod.__init__(self, descriptor, name, "bool", args)
@ -4256,7 +4292,8 @@ class CGResolveProperty(CGXrayHelper):
class CGEnumerateProperties(CGXrayHelper):
def __init__(self, descriptor, properties):
args = [Argument('JS::AutoIdVector&', 'props')]
args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
Argument('JS::AutoIdVector&', 'props')]
CGXrayHelper.__init__(self, descriptor, "EnumerateProperties", args,
properties)
@ -4478,6 +4515,9 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
'obj': 'proxy', 'successCode': fillDescriptor}
# Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named
# properties that shadow prototype properties.
namedGet = ("\n" +
"if (!set && JSID_IS_STRING(id) && !HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
" JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
@ -4887,6 +4927,9 @@ class CGDescriptor(CGThing):
# it in workers.
if (descriptor.interface.hasInterfacePrototypeObject() and
not descriptor.workers):
if descriptor.concrete and descriptor.proxy:
cgThings.append(CGResolveOwnProperty(descriptor))
cgThings.append(CGEnumerateOwnProperties(descriptor))
cgThings.append(CGResolveProperty(descriptor, properties))
cgThings.append(CGEnumerateProperties(descriptor, properties))

View File

@ -35,11 +35,14 @@ typedef bool
(* ResolveProperty)(JSContext* cx, JSObject* wrapper, jsid id, bool set,
JSPropertyDescriptor* desc);
typedef bool
(* EnumerateProperties)(JS::AutoIdVector& props);
(* EnumerateProperties)(JSContext* cx, JSObject* wrapper,
JS::AutoIdVector& props);
struct NativePropertyHooks
{
ResolveProperty mResolveOwnProperty;
ResolveProperty mResolveProperty;
EnumerateProperties mEnumerateOwnProperties;
EnumerateProperties mEnumerateProperties;
const NativePropertyHooks *mProtoHooks;

View File

@ -33,12 +33,15 @@ WorkerResolveProperty(JSContext* cx, JSObject* wrapper, jsid id, bool set,
return true;
}
bool
WorkerEnumerateProperties(JS::AutoIdVector& props)
WorkerEnumerateProperties(JSContext* cx, JSObject* wrapper,
JS::AutoIdVector& props)
{
return true;
}
NativePropertyHooks mozilla::dom::workers::sNativePropertyHooks =
{ WorkerResolveProperty, WorkerEnumerateProperties, NULL };
{ WorkerResolveProperty, WorkerResolveProperty,
WorkerEnumerateProperties, WorkerEnumerateProperties,
NULL };
namespace {

View File

@ -290,13 +290,13 @@ enum XrayType {
static XrayType
GetXrayType(JSObject *obj)
{
js::Class* clasp = js::GetObjectClass(obj);
if (mozilla::dom::IsDOMClass(Jsvalify(clasp))) {
if (mozilla::dom::IsDOMObject(obj))
return XrayForDOMObject;
}
if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
if (mozilla::dom::oldproxybindings::instanceIsProxy(obj))
return XrayForDOMProxyObject;
}
js::Class* clasp = js::GetObjectClass(obj);
if (IS_WRAPPER_CLASS(clasp) || clasp->ext.innerObject) {
NS_ASSERTION(clasp->ext.innerObject || IS_WN_WRAPPER_OBJECT(obj),
"We forgot to Morph a slim wrapper!");
@ -368,10 +368,10 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
else
wrapper = &FilteringWrapper<Xray, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::IsDOMObject(obj)) {
wrapper = &FilteringWrapper<XrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
wrapper = &FilteringWrapper<XrayProxy, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::IsDOMClass(JS_GetClass(obj))) {
wrapper = &FilteringWrapper<XrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (IsComponentsObject(obj)) {
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
ComponentsObjectPolicy>::singleton;

View File

@ -1036,12 +1036,13 @@ DOMXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject
bool set, JSPropertyDescriptor *desc)
{
JSObject *obj = getInnerObject(wrapper);
const NativePropertyHooks *nativeHooks =
DOMJSClass::FromJSClass(JS_GetClass(obj))->mClass.mNativeHooks;
const NativePropertyHooks *nativeHooks = GetDOMClass(obj)->mNativeHooks;
do {
if (nativeHooks->mResolveProperty(cx, wrapper, id, set, desc) &&
desc->obj) {
if (!nativeHooks->mResolveProperty(cx, wrapper, id, set, desc))
return false;
if (desc->obj) {
NS_ASSERTION(desc->obj == wrapper, "What did we resolve this on?");
return true;
}
@ -1054,6 +1055,17 @@ bool
DOMXrayTraits::resolveOwnProperty(JSContext *cx, js::Wrapper &jsWrapper, JSObject *wrapper,
JSObject *holder, jsid id, bool set, JSPropertyDescriptor *desc)
{
JSObject *obj = getInnerObject(wrapper);
const NativePropertyHooks *nativeHooks = GetDOMClass(obj)->mNativeHooks;
if (nativeHooks->mResolveOwnProperty) {
if (!nativeHooks->mResolveOwnProperty(cx, wrapper, id, set, desc))
return false;
NS_ASSERTION(!desc->obj || desc->obj == wrapper,
"What did we resolve this on?");
}
return true;
}
@ -1082,16 +1094,19 @@ bool
DOMXrayTraits::enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
JS::AutoIdVector &props)
{
JSObject *obj = getInnerObject(wrapper);
const NativePropertyHooks *nativeHooks = GetDOMClass(obj)->mNativeHooks;
if (nativeHooks->mEnumerateOwnProperties &&
!nativeHooks->mEnumerateOwnProperties(cx, wrapper, props))
return false;
if (flags & (JSITER_OWNONLY | JSITER_HIDDEN))
// Probably need to return expandos on the Xray here!
return true;
JSObject *obj = getInnerObject(wrapper);
const NativePropertyHooks *nativeHooks =
DOMJSClass::FromJSClass(JS_GetClass(obj))->mClass.mNativeHooks;
do {
if (!nativeHooks->mEnumerateProperties(props)) {
if (!nativeHooks->mEnumerateProperties(cx, wrapper, props)) {
return false;
}
} while ((nativeHooks = nativeHooks->mProtoHooks));