Bug 920196 - Make QueryInterface opt-in for WebIDL interfaces. r=bz.

--HG--
extra : rebase_source : 4cf7f9dc90f234dd663da05f27c0dc9484c7c0e1
This commit is contained in:
Peter Van der Beken 2013-09-24 21:37:53 +02:00
parent ffdecec1a8
commit d0b24c7ccf
6 changed files with 134 additions and 45 deletions

View File

@ -1378,19 +1378,12 @@ InitIds(JSContext* cx, const Prefable<Spec>* prefableSpecs, jsid* ids)
bool
QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
template <class T>
struct
WantsQueryInterface
{
static bool Enabled(JSContext* aCx, JSObject* aGlobal)
{
return false;
}
};
template <class T>
struct
WantsQueryInterface<T, true>
{
static_assert(IsBaseOf<nsISupports, T>::value,
"QueryInterface can't work without an nsISupports.");
static bool Enabled(JSContext* aCx, JSObject* aGlobal)
{
return NS_IsMainThread() && IsChromeOrXBL(aCx, aGlobal);

View File

@ -30,8 +30,6 @@
# true for workers, false otherwise).
# * customFinalize - The native class will use a custom finalize hook
# (defaults to true for workers, false otherwise).
# * wantsQI - Indicates whether the interface should have a QueryInterface
# method available to chrome.
# * notflattened - The native type does not have nsIClassInfo, so when
# wrapping it the right IID needs to be passed in.
# * register - True if this binding should be registered. Defaults to true.
@ -318,7 +316,6 @@ DOMInterfaces = {
},
'DOMException': {
'wantsQI': False,
'binaryNames': {
'message': 'messageMoz',
},
@ -395,7 +392,6 @@ DOMInterfaces = {
'Exception': {
'headerFile': 'mozilla/dom/DOMException.h',
'wantsQI': False,
'binaryNames': {
'message': 'messageMoz',
},
@ -660,7 +656,6 @@ DOMInterfaces = {
'ImageData': [
{
'wrapperCache': False,
'wantsQI': False,
}],
'InputStream': [

View File

@ -1462,6 +1462,41 @@ class MethodDefiner(PropertyDefiner):
self.chrome = []
self.regular = []
for m in methods:
if m.identifier.name == 'queryInterface':
if self.descriptor.workers:
continue
if m.isStatic():
raise TypeError("Legacy queryInterface member shouldn't be static")
signatures = m.signatures()
def argTypeIsIID(arg):
return arg.type.inner.isExternal() and arg.type.inner.identifier.name == 'IID'
if len(signatures) > 1 or len(signatures[0][1]) > 1 or not argTypeIsIID(signatures[0][1][0]):
raise TypeError("There should be only one queryInterface method with 1 argument of type IID")
# Make sure to not stick QueryInterface on abstract interfaces that
# have hasXPConnectImpls (like EventTarget). So only put it on
# interfaces that are concrete and all of whose ancestors are abstract.
def allAncestorsAbstract(iface):
if not iface.parent:
return True
desc = self.descriptor.getDescriptor(iface.parent.identifier.name)
if desc.concrete:
return False
return allAncestorsAbstract(iface.parent)
if (not self.descriptor.interface.hasInterfacePrototypeObject() or
not self.descriptor.concrete or
not allAncestorsAbstract(self.descriptor.interface)):
raise TypeError("QueryInterface is only supported on "
"interfaces that are concrete and all "
"of whose ancestors are abstract: " +
self.descriptor.name)
condition = "WantsQueryInterface<%s>::Enabled" % descriptor.nativeType
self.regular.append({"name": 'QueryInterface',
"methodInfo": False,
"length": 1,
"flags": "0",
"condition": MemberCondition(None, condition) })
continue
method = { "name": m.identifier.name,
"methodInfo": not m.isStatic(),
"length": methodLength(m),
@ -1481,14 +1516,6 @@ class MethodDefiner(PropertyDefiner):
"flags": "JSPROP_ENUMERATE",
"condition": MemberCondition(None, None) })
if not static and descriptor.wantsQI():
condition = "WantsQueryInterface<%s>::Enabled" % descriptor.nativeType
self.regular.append({"name": 'QueryInterface',
"methodInfo": False,
"length": 1,
"flags": "0",
"condition": MemberCondition(None, condition) })
if not static:
stringifier = descriptor.operations['Stringifier']
if stringifier:
@ -7860,6 +7887,8 @@ class CGDescriptor(CGThing):
cgThings.append(CGClassConstructor(descriptor, n,
NamedConstructorName(n)))
for m in descriptor.interface.members:
if m.isMethod() and m.identifier.name == 'queryInterface':
continue
if (m.isMethod() and m == descriptor.operations['Jsonifier']):
hasJsonifier = True
hasMethod = True

View File

@ -356,8 +356,6 @@ class Descriptor(DescriptorProvider):
(self.interface.identifier.name, self.nativeOwnership))
self.customTrace = desc.get('customTrace', self.workers)
self.customFinalize = desc.get('customFinalize', self.workers)
if desc.get('wantsQI', None) != None:
self._wantsQI = desc.get('wantsQI', None)
self.wrapperCache = (not self.interface.isCallback() and
(self.nativeOwnership == 'worker' or
(self.nativeOwnership != 'owned' and
@ -477,26 +475,6 @@ class Descriptor(DescriptorProvider):
any((m.isAttr() or m.isMethod()) and m.isStatic() for m
in self.interface.members))
def wantsQI(self):
# If it was specified explicitly use that.
if hasattr(self, '_wantsQI'):
return self._wantsQI
# Make sure to not stick QueryInterface on abstract interfaces that
# have hasXPConnectImpls (like EventTarget). So only put it on
# interfaces that are concrete and all of whose ancestors are abstract.
def allAncestorsAbstract(iface):
if not iface.parent:
return True
desc = self.getDescriptor(iface.parent.identifier.name)
if desc.concrete:
return False
return allAncestorsAbstract(iface.parent)
return (not self.workers and
self.interface.hasInterfacePrototypeObject() and
self.concrete and
allAncestorsAbstract(self.interface))
# Some utility methods
def getTypesFromDescriptor(descriptor):
"""

View File

@ -0,0 +1,93 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
interface nsISupports;
interface IID;
[NoInterfaceObject]
interface LegacyQueryInterface {
// Legacy QueryInterface, only exposed to chrome or XBL code on the
// main thread.
nsISupports queryInterface(IID iid);
};
Attr implements LegacyQueryInterface;
BarProp implements LegacyQueryInterface;
CaretPosition implements LegacyQueryInterface;
ClientRect implements LegacyQueryInterface;
ClientRectList implements LegacyQueryInterface;
Comment implements LegacyQueryInterface;
Crypto implements LegacyQueryInterface;
CSSPrimitiveValue implements LegacyQueryInterface;
CSSStyleDeclaration implements LegacyQueryInterface;
CSSValueList implements LegacyQueryInterface;
DOMImplementation implements LegacyQueryInterface;
DOMParser implements LegacyQueryInterface;
DOMStringMap implements LegacyQueryInterface;
DOMTokenList implements LegacyQueryInterface;
Document implements LegacyQueryInterface;
DocumentFragment implements LegacyQueryInterface;
DocumentType implements LegacyQueryInterface;
Element implements LegacyQueryInterface;
Event implements LegacyQueryInterface;
EventSource implements LegacyQueryInterface;
FileList implements LegacyQueryInterface;
FormData implements LegacyQueryInterface;
HTMLCollection implements LegacyQueryInterface;
History implements LegacyQueryInterface;
IDBCursor implements LegacyQueryInterface;
IDBDatabase implements LegacyQueryInterface;
IDBFactory implements LegacyQueryInterface;
IDBIndex implements LegacyQueryInterface;
IDBObjectStore implements LegacyQueryInterface;
IDBRequest implements LegacyQueryInterface;
IDBTransaction implements LegacyQueryInterface;
MimeTypeArray implements LegacyQueryInterface;
MozNamedAttrMap implements LegacyQueryInterface;
MutationObserver implements LegacyQueryInterface;
MutationRecord implements LegacyQueryInterface;
Navigator implements LegacyQueryInterface;
NodeIterator implements LegacyQueryInterface;
NodeList implements LegacyQueryInterface;
Notification implements LegacyQueryInterface;
OfflineResourceList implements LegacyQueryInterface;
PaintRequest implements LegacyQueryInterface;
PaintRequestList implements LegacyQueryInterface;
Performance implements LegacyQueryInterface;
Plugin implements LegacyQueryInterface;
PluginArray implements LegacyQueryInterface;
ProcessingInstruction implements LegacyQueryInterface;
Range implements LegacyQueryInterface;
Rect implements LegacyQueryInterface;
SVGAnimatedEnumeration implements LegacyQueryInterface;
SVGAnimatedInteger implements LegacyQueryInterface;
SVGAnimatedNumber implements LegacyQueryInterface;
SVGAnimatedNumberList implements LegacyQueryInterface;
SVGAnimatedPreserveAspectRatio implements LegacyQueryInterface;
SVGAnimatedString implements LegacyQueryInterface;
SVGLengthList implements LegacyQueryInterface;
SVGNumberList implements LegacyQueryInterface;
SVGPathSegList implements LegacyQueryInterface;
SVGPoint implements LegacyQueryInterface;
SVGPointList implements LegacyQueryInterface;
SVGPreserveAspectRatio implements LegacyQueryInterface;
SVGRect implements LegacyQueryInterface;
SVGStringList implements LegacyQueryInterface;
SVGTransformList implements LegacyQueryInterface;
Screen implements LegacyQueryInterface;
StyleSheet implements LegacyQueryInterface;
Text implements LegacyQueryInterface;
Touch implements LegacyQueryInterface;
TouchList implements LegacyQueryInterface;
TreeColumns implements LegacyQueryInterface;
TreeWalker implements LegacyQueryInterface;
UndoManager implements LegacyQueryInterface;
ValidityState implements LegacyQueryInterface;
WebSocket implements LegacyQueryInterface;
XMLHttpRequest implements LegacyQueryInterface;
XMLHttpRequestUpload implements LegacyQueryInterface;
XMLSerializer implements LegacyQueryInterface;
XPathEvaluator implements LegacyQueryInterface;

View File

@ -193,6 +193,7 @@ WEBIDL_FILES = [
'InterAppMessagePort.webidl',
'KeyboardEvent.webidl',
'KeyEvent.webidl',
'LegacyQueryInterface.webidl',
'LinkStyle.webidl',
'LocalMediaStream.webidl',
'Location.webidl',