Bug 1085062. Remove hasXPConnectImpls support from bindings codegen. r=peterv

This commit is contained in:
Boris Zbarsky 2018-04-04 14:39:52 -04:00
parent 419465b581
commit fe15e92e6b
5 changed files with 16 additions and 194 deletions

View File

@ -343,7 +343,9 @@ protected:
private:
// Friend declarations for things that need to be able to call
// SetIsNotDOMBinding(). The goal is to get rid of all of these, and
// SetIsNotDOMBinding() too.
// SetIsNotDOMBinding() too. Once that's done, we can remove the
// couldBeDOMBinding bits in DoGetOrCreateDOMReflector, as well as any ither
// consumers of IsDOMBinding().
friend class SandboxPrivate;
void SetIsNotDOMBinding()
{

View File

@ -1233,8 +1233,7 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
// Switch this to UnwrapDOMObjectToISupports once our global objects are
// using new bindings.
nsCOMPtr<nsISupports> native;
UnwrapArg<nsISupports>(cx, obj, getter_AddRefs(native));
nsCOMPtr<nsISupports> native = UnwrapDOMObjectToISupports(obj);
if (!native) {
return Throw(cx, NS_ERROR_FAILURE);
}
@ -3265,40 +3264,6 @@ UnwrapArgImpl(JSContext* cx,
return wrappedJS->QueryInterface(iid, ppArg);
}
nsresult
UnwrapXPConnectImpl(JSContext* cx,
JS::MutableHandle<JS::Value> src,
const nsIID &iid,
void **ppArg)
{
if (!NS_IsMainThread()) {
return NS_ERROR_NOT_AVAILABLE;
}
MOZ_ASSERT(src.isObject());
// Unwrap ourselves, because we're going to want access to the unwrapped
// object.
JS::Rooted<JSObject*> obj(cx,
js::CheckedUnwrap(&src.toObject(),
/* stopAtWindowProxy = */ false));
if (!obj) {
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsISupports> iface = xpc::UnwrapReflectorToISupports(obj);
if (!iface) {
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
if (NS_FAILED(iface->QueryInterface(iid, ppArg))) {
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
// Now update our source to keep rooting our object.
src.setObject(*obj);
return NS_OK;
}
nsresult
UnwrapWindowProxyImpl(JSContext* cx,
JS::Handle<JSObject*> src,

View File

@ -80,29 +80,6 @@ UnwrapArg<nsPIDOMWindowOuter>(JSContext* cx, JS::Handle<JSObject*> src,
return UnwrapWindowProxyImpl(cx, src, ppArg);
}
nsresult
UnwrapXPConnectImpl(JSContext* cx, JS::MutableHandle<JS::Value> src,
const nsIID& iid, void** ppArg);
/*
* Convert a jsval being used as a Web IDL interface implementation to an XPCOM
* pointer; this is only used for Web IDL interfaces that specify
* hasXPConnectImpls. This is not the same as UnwrapArg because caller _can_
* assume that if unwrapping succeeds "val" will be updated so it's rooting the
* XPCOM pointer. Also, UnwrapXPConnect doesn't need to worry about doing
* XPCWrappedJS things.
*
* val must be an ObjectValue.
*/
template<class Interface>
inline nsresult
UnwrapXPConnect(JSContext* cx, JS::MutableHandle<JS::Value> val,
Interface** ppThis)
{
return UnwrapXPConnectImpl(cx, val, NS_GET_TEMPLATE_IID(Interface),
reinterpret_cast<void**>(ppThis));
}
bool
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
bool aSecurityError, const char* aInterfaceName);
@ -1093,7 +1070,8 @@ DoGetOrCreateDOMReflector(JSContext* cx, T* value,
{
MOZ_ASSERT(value);
MOZ_ASSERT_IF(givenProto, js::IsObjectInContextCompartment(givenProto, cx));
// We can get rid of this when we remove support for hasXPConnectImpls.
// We can get rid of this when we remove support for
// nsWrapperCache::SetIsNotDOMBinding.
bool couldBeDOMBinding = CouldBeDOMBinding(value);
JSObject* obj = value->GetWrapper();
if (obj) {

View File

@ -686,11 +686,6 @@ class CGPrototypeJSClass(CGThing):
protoGetter=protoGetter)
def NeedsGeneratedHasInstance(descriptor):
assert descriptor.interface.hasInterfaceObject()
return descriptor.hasXPConnectImpls
def InterfaceObjectProtoGetter(descriptor, forXrays=False):
"""
Returns a tuple with two elements:
@ -741,9 +736,7 @@ class CGInterfaceObjectJSClass(CGThing):
ctorname = "nullptr"
else:
ctorname = "ThrowingConstructor"
needsHasInstance = (
not NeedsGeneratedHasInstance(self.descriptor) and
self.descriptor.interface.hasInterfacePrototypeObject())
needsHasInstance = self.descriptor.interface.hasInterfacePrototypeObject()
prototypeID, depth = PrototypeIDAndDepth(self.descriptor)
slotCount = "DOM_INTERFACE_SLOTS_BASE"
@ -1106,15 +1099,6 @@ class CGHeaders(CGWrapper):
implementationIncludes |= set(self.getDeclarationFilename(i) for i in
interfacesImplementingSelf)
# Grab the includes for the things that involve XPCOM interfaces
hasInstanceIncludes = set(self.getDeclarationFilename(d.interface) for d
in descriptors if
d.interface.hasInterfaceObject() and
NeedsGeneratedHasInstance(d) and
d.interface.hasInterfacePrototypeObject())
if len(hasInstanceIncludes) > 0:
hasInstanceIncludes.add("nsContentUtils.h")
# Now find all the things we'll need as arguments because we
# need to wrap or unwrap them.
bindingHeaders = set()
@ -1298,7 +1282,6 @@ class CGHeaders(CGWrapper):
definePre=_includeString(sorted(set(defineIncludes) |
bindingIncludes |
bindingHeaders |
hasInstanceIncludes |
implementationIncludes)))
@staticmethod
@ -1980,52 +1963,6 @@ class CGNamedConstructors(CGThing):
namedConstructors=namedConstructors)
class CGHasInstanceHook(CGAbstractStaticMethod):
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('unsigned', 'argc'),
Argument('JS::Value*', 'vp')]
assert descriptor.interface.hasInterfaceObject()
assert NeedsGeneratedHasInstance(descriptor)
CGAbstractStaticMethod.__init__(self, descriptor, HASINSTANCE_HOOK_NAME,
'bool', args)
def define(self):
return CGAbstractStaticMethod.define(self)
def definition_body(self):
return self.generate_code()
def generate_code(self):
return fill(
"""
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (!args.get(0).isObject()) {
args.rval().setBoolean(false);
return true;
}
JS::Rooted<JSObject*> instance(cx, &args[0].toObject());
static_assert(IsBaseOf<nsISupports, ${nativeType}>::value,
"HasInstance only works for nsISupports-based classes.");
bool ok = InterfaceHasInstance(cx, argc, vp);
if (!ok || args.rval().toBoolean()) {
return ok;
}
// FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
nsCOMPtr<nsISupports> native =
xpc::UnwrapReflectorToISupports(js::UncheckedUnwrap(instance, /* stopAtWindowProxy = */ false));
nsCOMPtr<nsIDOM${name}> qiResult = do_QueryInterface(native);
args.rval().setBoolean(!!qiResult);
return true;
""",
nativeType=self.descriptor.nativeType,
name=self.descriptor.interface.identifier.name)
def isChromeOnly(m):
return m.getExtendedAttribute("ChromeOnly")
@ -2442,20 +2379,6 @@ class MethodDefiner(PropertyDefiner):
"condition": MemberCondition()
})
if (static and
not unforgeable and
descriptor.interface.hasInterfaceObject() and
NeedsGeneratedHasInstance(descriptor)):
self.regular.append({
"name": "@@hasInstance",
"methodInfo": False,
"nativeName": HASINSTANCE_HOOK_NAME,
"length": 1,
# Flags match those of Function[Symbol.hasInstance]
"flags": "JSPROP_READONLY | JSPROP_PERMANENT",
"condition": MemberCondition()
})
# Generate the keys/values/entries aliases for value iterables.
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
if (not static and
@ -4340,14 +4263,6 @@ class CastableObjectUnwrapper():
"target": target,
"codeOnFailure": codeOnFailure,
}
# Supporting both the "cross origin object" case and the "has
# XPConnect impls" case at the same time is a pain, so let's
# not do that. That allows us to assume that our source is
# always a Handle or MutableHandle.
if allowCrossOriginObj and descriptor.hasXPConnectImpls:
raise TypeError("Interface %s both allows a cross-origin 'this' "
"and has XPConnect impls. We don't support that" %
descriptor.name)
if allowCrossOriginObj:
self.substitution["uncheckedObjDecl"] = fill(
"""
@ -4368,30 +4283,14 @@ class CastableObjectUnwrapper():
codeOnFailure=(codeOnFailure % { 'securityError': 'true'}))
self.substitution["source"] = "maybeUncheckedObj"
self.substitution["mutableSource"] = "&maybeUncheckedObj"
# No need to set up xpconnectUnwrap, since it won't be
# used in the allowCrossOriginObj case.
else:
self.substitution["uncheckedObjDecl"] = ""
self.substitution["uncheckedObjGet"] = ""
self.substitution["source"] = source
self.substitution["mutableSource"] = mutableSource
xpconnectUnwrap = (
"nsresult rv = UnwrapXPConnect<${type}>(cx, ${mutableSource}, getter_AddRefs(objPtr));\n")
if descriptor.hasXPConnectImpls:
self.substitution["codeOnFailure"] = string.Template(
"RefPtr<${type}> objPtr;\n" +
xpconnectUnwrap +
"if (NS_FAILED(rv)) {\n"
"${indentedCodeOnFailure}"
"}\n"
"// We should have an object\n"
"MOZ_ASSERT(objPtr);\n"
"${target} = objPtr;\n"
).substitute(self.substitution,
indentedCodeOnFailure=indent(codeOnFailure))
elif (isCallbackReturnValue == "JSImpl" and
descriptor.interface.isJSImplemented()):
if (isCallbackReturnValue == "JSImpl" and
descriptor.interface.isJSImplemented()):
exceptionCode = exceptionCode or codeOnFailure
self.substitution["codeOnFailure"] = fill(
"""
@ -6835,18 +6734,10 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
if isConstructorRetval:
wrapArgs += ", desiredProto"
wrap = "%s(%s)" % (wrapMethod, wrapArgs)
if not descriptor.hasXPConnectImpls:
# Can only fail to wrap as a new-binding object
# if they already threw an exception.
failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
exceptionCode)
else:
if descriptor.notflattened:
raise TypeError("%s has XPConnect impls but not flattened; "
"fallback won't work correctly" %
descriptor.interface.identifier.name)
# Try old-style wrapping for bindings which might be XPConnect impls.
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalHandle})" % result)
# Can only fail to wrap as a new-binding object
# if they already threw an exception.
failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
exceptionCode)
else:
if descriptor.notflattened:
getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
@ -9226,12 +9117,6 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
self.attr)
if self.attr.slotIndices is not None:
if self.descriptor.hasXPConnectImpls:
raise TypeError("Interface '%s' has XPConnect impls, so we "
"can't use our slot for property '%s'!" %
(self.descriptor.interface.identifier.name,
self.attr.identifier.name))
# We're going to store this return value in a slot on some object,
# to cache it. The question is, which object? For dictionary and
# sequence return values, we want to use a slot on the Xray expando
@ -12863,12 +12748,6 @@ class CGDescriptor(CGThing):
for m in clearableCachedAttrs(descriptor):
cgThings.append(CGJSImplClearCachedValueMethod(descriptor, m))
# Need to output our generated hasinstance bits before
# PropertyArrays tries to use them.
if (descriptor.interface.hasInterfaceObject() and
NeedsGeneratedHasInstance(descriptor)):
cgThings.append(CGHasInstanceHook(descriptor))
properties = PropertyArrays(descriptor)
cgThings.append(CGGeneric(define=str(properties)))
cgThings.append(CGNativeProperties(descriptor, properties))

View File

@ -399,8 +399,6 @@ class Descriptor(DescriptorProvider):
self.notflattened = desc.get('notflattened', False)
self.register = desc.get('register', True)
self.hasXPConnectImpls = desc.get('hasXPConnectImpls', False)
# If we're concrete, we need to crawl our ancestor interfaces and mark
# them as having a concrete descendant.
self.concrete = (not self.interface.isExternal() and
@ -762,10 +760,10 @@ class Descriptor(DescriptorProvider):
Returns true if this descriptor requires generic ops other than
GenericBindingMethod/GenericBindingGetter/GenericBindingSetter.
In practice we need to do this if our this value might be an XPConnect
object or if we need to coerce null/undefined to the global.
In practice we need to do this if we need to coerce null/undefined
to the global.
"""
return self.hasXPConnectImpls or self.interface.isOnGlobalProtoChain()
return self.interface.isOnGlobalProtoChain()
def isGlobal(self):
"""