auto merge of #1750 : Ms2ger/servo/cleanup-Bindings.conf, r=jdm

This commit is contained in:
bors-servo 2014-02-25 09:52:33 -05:00
commit 3b9ff728fe
3 changed files with 166 additions and 979 deletions

View file

@ -4,554 +4,99 @@
# DOM Bindings Configuration. # DOM Bindings Configuration.
# #
# The WebIDL interfaces are defined in dom/webidl. For each such interface, there # The WebIDL interfaces are defined in dom/webidls. For each such interface,
# is a corresponding entry in the configuration table below. The configuration # there is a corresponding entry in the configuration table below.
# table maps each interface name to a |descriptor| or list of |descriptor|s. # The configuration table maps each interface name to a |descriptor|.
# #
# Valid fields for all descriptors: # Valid fields for all descriptors:
# * nativeType - The native type (concrete class or XPCOM interface) that # * needsAbstract: a list of members that require a JS<>-wrapped version of
# instances of this interface will unwrap to. If not # self to be passed to the native code.
# specified, defaults to "mozilla::dom::InterfaceName" for # * createGlobal: True for global objects.
# non-worker non-external-or-callback interfaces, to
# "mozilla::dom::workers::InterfaceName" for worker
# non-external interfaces, to 'nsIDOM' followed by the
# interface name for non-worker external-or-callback
# interfaces, and to "JSObject" for worker external-or-callback
# interfaces.
# * headerFile - The file in which the nativeType is declared (defaults
# to an educated guess).
# * castable - Indicates whether the value in the wrapper can be cast to
# nativeType, or whether it needs to be QI-ed (defaults to True
# for everything but callback interfaces and external interfaces,
# for which it defaults to false and is not allowed to be set
# at all).
# * concrete - Indicates whether there exist objects with this interface as
# their primary interface (defaults to True).
# * prefable - Indicates whether this bindings should be disabled if the
# global pref for Web IDL bindings is set to false. This is a
# risk mitigation strategy and it will cause all of the Web IDL
# bindings marked as prefable to fall back to the xpconnect
# bindings in case something goes wrong. This defaults to False.
# Setting this on objects which only have Web IDL bindings does
# not make any sense.
# Cannot be set on external interfaces.
# * workers - Indicates whether the descriptor is intended to be used for
# worker threads (defaults to false).
# * customTrace - The native class will use a custom trace hook (defaults to
# true for workers, false otherwise).
# * customFinalize - The native class will use a custom finalize hook
# (defaults to true for workers, false otherwise).
# * 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.
# * binaryNames - Dict for mapping method and attribute names to different
# names when calling the native methods (defaults to an empty
# dict). The keys are the property names as they appear in the
# .webidl file and the values are the names as they should be
# in the WebIDL.
# * wrapperCache: True if this object is a wrapper cache. Objects that are
# not can only be returned from a limited set of methods,
# cannot be prefable, and must ensure that they disallow
# XPConnect wrapping. Always true for worker descriptors.
# Defaults to true.
#
# The following fields are either a string, an array (defaults to an empty
# array) or a dictionary with three possible keys (all, getterOnly and
# setterOnly) each having such an array as the value
#
# * implicitJSContext - attributes and methods specified in the .webidl file
# that require a JSContext as the first argument
# * resultNotAddRefed - attributes and methods specified in the .webidl file
# that do not AddRef the return value
DOMInterfaces = { DOMInterfaces = {
'Attr' : { 'Attr': {},
}, 'AudioBuffer': {},
'AttrList': {},
'AudioBuffer' : { 'Blob': {},
}, 'CanvasRenderingContext2D': {},
'CharacterData': {},
'AttrList': { 'ClientRect': {},
}, 'ClientRectList': {},
'Console': {},
'mozAudioContext': {
'nativeType': 'AudioContext',
'implicitJSContext': [ 'createBuffer' ],
},
'AudioNode' : {
'concrete': False,
},
'AudioSourceNode': {
'concrete': False,
},
'AudioBufferSourceNode': {
},
'AudioDestinationNode': {
},
'Blob': [
{
},
#{
# 'workers': True,
#}
],
'CanvasRenderingContext2D': [
{
'nativeType': 'nsCanvasRenderingContext2DAzure',
# Making this non-prefable requires that we ensure that nothing takes this
# type as an argument or that the non-Azure variant is removed.
'prefable': True,
'implicitJSContext': [
'createImageData', 'getImageData', 'putImageData', 'strokeStyle',
'fillStyle', 'mozDash'
],
'resultNotAddRefed': [ 'canvas' ],
'binaryNames': {
'mozImageSmoothingEnabled': 'imageSmoothingEnabled',
'mozFillRule': 'fillRule'
}
}],
'CharacterData': {
},
'ClientRect': [
{
}],
'ClientRectList': [
{
}],
'Console': {
},
'CSS2Properties': {
'nativeType': 'nsDOMCSSDeclaration',
'prefable': True,
},
'CSSStyleDeclaration': {
'nativeType': 'nsICSSDeclaration',
'prefable': True
},
'Document': { 'Document': {
'customTrace': 'trace',
'needsAbstract': [ 'needsAbstract': [
'body',
'createComment', 'createComment',
'createDocumentFragment', 'createDocumentFragment',
'createElement', 'createElement',
'createProcessingInstruction', 'createProcessingInstruction',
'createTextNode', 'createTextNode',
'title', 'title',
'body',
], ],
}, },
'DOMException': {},
'DOMException': { 'DOMImplementation': {},
}, 'DOMParser': {},
'DOMImplementation': {
},
'DOMParser': {
},
'DOMSettableTokenList': [
{
'nativeType': 'nsDOMSettableTokenList',
'prefable': True,
'binaryNames': {
'__stringifier': 'Stringify'
}
}],
'DOMTokenList': [
{
'nativeType': 'nsDOMTokenList',
'prefable': True,
'binaryNames': {
'__stringifier': 'Stringify'
}
}],
'Element': { 'Element': {
'needsAbstract': ['getClientRects', 'getBoundingClientRect', 'setAttribute', 'setAttributeNS', 'removeAttribute', 'removeAttributeNS', 'id', 'attributes', 'innerHTML', 'outerHTML'] 'needsAbstract': [
'attributes',
'getBoundingClientRect',
'getClientRects',
'id',
'innerHTML',
'outerHTML',
'removeAttribute',
'removeAttributeNS',
'setAttribute',
'setAttributeNS',
]
}, },
'Event': {},
'Event': {
},
'EventListener': { 'EventListener': {
'nativeType': 'EventListenerBinding::EventListener', 'nativeType': 'EventListenerBinding::EventListener',
}, },
'EventTarget': { 'EventTarget': {
'needsAbstract': ['dispatchEvent'] 'needsAbstract': ['dispatchEvent']
}, },
'FormData': {},
'FileList': [ 'HTMLCollection': {},
{ 'Location': {},
'nativeType': 'nsDOMFileList', 'MouseEvent': {},
'headerFile': 'nsDOMFile.h', 'Navigator': {},
'prefable': True,
'resultNotAddRefed': [ 'item' ]
}],
'FileReaderSync': [
{
'workers': True,
'headerFile': 'mozilla/dom/workers/bindings/FileReaderSync.h'
}],
'FormData': [
{
},
#{
# 'workers': True,
#}
],
'HTMLCollection': [
{
}],
'HTMLOptionsCollection': [
{
'nativeType': 'nsHTMLOptionCollection',
'headerFile': 'nsHTMLSelectElement.h',
'prefable': True,
'resultNotAddRefed': [ 'item' ],
'binaryNames': {
'__indexedsettercreator': 'SetOption'
}
}],
'HTMLPropertiesCollection': [
{
'headerFile': 'HTMLPropertiesCollection.h',
'prefable': True,
'resultNotAddRefed': [ 'item', 'namedItem', 'names' ]
}],
'IID': [
{
'nativeType': 'nsIJSIID',
'headerFile': 'xpcjsid.h',
},
{
'workers': True,
}],
'InputStream': [
{
'nativeType': 'nsIInputStream',
'notflattened': True
},
{
'workers': True,
}],
'Location': {
},
'MozChannel': [
{
'nativeType': 'nsIChannel',
'notflattened': True
},
{
'workers': True,
}],
'MouseEvent': {
},
'Navigator': {
},
'Node': { 'Node': {
'needsAbstract': [ 'needsAbstract': [
'appendChild', 'appendChild',
'childNodes', 'childNodes',
'contains',
'insertBefore', 'insertBefore',
'isEqualNode',
'nodeName', 'nodeName',
'nodeValue', 'nodeValue',
'removeChild', 'removeChild',
'replaceChild', 'replaceChild',
'textContent', 'textContent',
'contains',
'isEqualNode',
] ]
}, },
'NodeList': [ 'NodeList': {},
{
'resultNotAddRefed': ['item']
}],
'PaintRequestList': [
{
'nativeType': 'nsPaintRequestList',
'headerFile': 'nsPaintRequest.h',
'prefable': True,
'resultNotAddRefed': [ 'item' ]
}],
'Performance': {
'nativeType': 'nsPerformance',
'resultNotAddRefed': [ 'timing', 'navigation' ]
},
'PerformanceTiming': {
'nativeType': 'nsPerformanceTiming',
'headerFile': 'nsPerformance.h'
},
'PerformanceNavigation': {
'nativeType': 'nsPerformanceNavigation',
'headerFile': 'nsPerformance.h'
},
'PropertyNodeList': [
{
'headerFile': 'HTMLPropertiesCollection.h',
'prefable': True,
'resultNotAddRefed': [ 'item' ]
}],
'SVGLengthList': [
{
'nativeType': 'mozilla::DOMSVGLengthList',
'headerFile': 'DOMSVGLengthList.h',
'prefable': True,
'resultNotAddRefed': [ 'getItem' ]
}],
'SVGNumberList': [
{
'nativeType': 'mozilla::DOMSVGNumberList',
'headerFile': 'DOMSVGNumberList.h',
'prefable': True,
'resultNotAddRefed': [ 'getItem' ]
}],
'SVGPathSegList': [
{
'nativeType': 'mozilla::DOMSVGPathSegList',
'headerFile': 'DOMSVGPathSegList.h',
'prefable': True,
'resultNotAddRefed': [ 'getItem' ]
}],
'SVGPointList': [
{
'nativeType': 'mozilla::DOMSVGPointList',
'headerFile': 'DOMSVGPointList.h',
'prefable': True,
'resultNotAddRefed': [ 'getItem' ]
}],
'SVGTransformList': [
{
'nativeType': 'mozilla::DOMSVGTransformList',
'headerFile': 'DOMSVGTransformList.h',
'prefable': True,
'resultNotAddRefed': [ 'getItem' ]
}],
'UIEvent': {
},
'ValidityState': {
},
'WebGLRenderingContext': {
'nativeType': 'mozilla::WebGLContext',
'headerFile': 'WebGLContext.h',
'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
'getAttachedShaders' ],
'implicitJSContext': [ 'texImage2D', 'texSubImage2D' ],
},
'WebGLUniformLocation': {
'nativeType': 'mozilla::WebGLUniformLocation',
'headerFile': 'WebGLContext.h',
'wrapperCache': False
},
'XMLHttpRequest': [
{
'nativeType': 'nsXMLHttpRequest',
'implicitJSContext': [ 'constructor', ],
'resultNotAddRefed': [ 'upload', 'responseXML' ]
},
{
'workers': True,
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequest.h',
}],
'XMLHttpRequestEventTarget': [
{
'nativeType': 'nsXHREventTarget',
'headerFile': 'nsXMLHttpRequest.h',
'concrete': False,
'prefable': True,
},
{
'workers': True,
'concrete': False,
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestEventTarget.h'
}],
'XMLHttpRequestUpload': [
{
'nativeType': 'nsXMLHttpRequestUpload',
'headerFile': 'nsXMLHttpRequest.h',
'prefable': True
},
{
'workers': True,
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestUpload.h'
}],
'WebSocket': [
{
'headerFile': 'WebSocket.h',
'implicitJSContext': [ 'constructor' ]
}],
'UIEvent': {},
'ValidityState': {},
'Window': { 'Window': {
'createGlobal': True, 'createGlobal': True,
'customTrace': 'trace'
}, },
'WindowProxy': { 'WindowProxy': {},
},
####################################
# Test Interfaces of various sorts #
####################################
'TestInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False,
'resultNotAddRefed': [ 'receiveWeakSelf', 'receiveWeakNullableSelf',
'receiveWeakOther', 'receiveWeakNullableOther',
'receiveWeakExternal', 'receiveWeakNullableExternal',
'ReceiveWeakCallbackInterface',
'ReceiveWeakNullableCallbackInterface',
'receiveWeakCastableObjectSequence',
'receiveWeakNullableCastableObjectSequence',
'receiveWeakCastableObjectNullableSequence',
'receiveWeakNullableCastableObjectNullableSequence' ],
'binaryNames': { 'methodRenamedFrom': 'methodRenamedTo',
'attributeGetterRenamedFrom': 'attributeGetterRenamedTo',
'attributeRenamedFrom': 'attributeRenamedTo' }
},
'TestNonCastableInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False,
'castable': False
},
'TestExternalInterface' : {
'nativeType': 'mozilla::dom::TestExternalInterface',
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestNonWrapperCacheInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False,
'wrapperCache': False
},
'TestCallbackInterface': {
'nativeType': 'mozilla::dom::TestCallbackInterface',
'headerFile': 'TestBindingHeader.h',
'register': False
},
'IndirectlyImplementedInterface': {
'headerFile': 'TestBindingHeader.h',
'register': False,
'castable': False,
'concrete': False
},
'OnlyForUseInConstructor' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedGetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestNamedGetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedAndNamedGetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedSetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestNamedSetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedAndNamedSetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedAndNamedGetterAndSetterInterface' : {
'headerFile': 'TestBindingHeader.h',
'register': False,
'binaryNames': { '__stringifier': 'Stringify' }
},
} }
# These are temporary, until they've been converted to use new DOM bindings
def addExternalIface(iface, nativeType=None, headerFile=None, pointerType=None):
domInterface = {
'concrete': False
}
if not nativeType is None:
domInterface['nativeType'] = nativeType
if not headerFile is None:
domInterface['headerFile'] = headerFile
if not pointerType is None:
domInterface['pointerType'] = pointerType
DOMInterfaces[iface] = domInterface
# FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625 # FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625
def addHTMLElement(element, concrete=None, needsAbstract=[]): def addHTMLElement(element, concrete=None, needsAbstract=[]):
DOMInterfaces[element] = { DOMInterfaces[element] = {
'nativeType': 'JS<%s>' % element, 'nativeType': 'JS<%s>' % element,
'pointerType': '', 'pointerType': '',
'concreteType': concrete if concrete else element, 'concreteType': concrete if concrete else element,
'customTrace': 'trace',
'needsAbstract': needsAbstract 'needsAbstract': needsAbstract
} }
@ -630,51 +175,3 @@ addHTMLElement('HTMLTrackElement')
addHTMLElement('HTMLUListElement') addHTMLElement('HTMLUListElement')
addHTMLElement('HTMLVideoElement') addHTMLElement('HTMLVideoElement')
addHTMLElement('HTMLUnknownElement') addHTMLElement('HTMLUnknownElement')
# If you add one of these, you need to make sure nsDOMQS.h has the relevant
# macros added for it
def addExternalHTMLElement(element):
nativeElement = element
addExternalIface(element, nativeType=nativeElement,
headerFile=nativeElement + '.h')
addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
addExternalIface('CSSRule')
addExternalIface('CSSValue')
addExternalIface('DOMStringList', nativeType='nsDOMStringList',
headerFile='nsDOMLists.h')
addExternalIface('File')
addExternalIface('HitRegionOptions', nativeType='nsISupports')
addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
addExternalIface('PaintRequest')
addExternalIface('SVGLength')
addExternalIface('SVGMatrix')
addExternalIface('SVGNumber')
addExternalIface('SVGPathSeg')
addExternalIface('SVGPoint')
addExternalIface('SVGTransform')
addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
headerFile='WebGLContext.h')
addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
headerFile='WebGLContext.h')
addExternalIface('WebGLContextAttributes', nativeType='JSObject',
headerFile='jsapi.h')
addExternalIface('WebGLExtension', nativeType='nsIWebGLExtension',
headerFile='WebGLContext.h')
addExternalIface('WebGLFramebuffer', nativeType='mozilla::WebGLFramebuffer',
headerFile='WebGLContext.h')
addExternalIface('WebGLProgram', nativeType='mozilla::WebGLProgram',
headerFile='WebGLContext.h')
addExternalIface('WebGLRenderbuffer', nativeType='mozilla::WebGLRenderbuffer',
headerFile='WebGLContext.h')
addExternalIface('WebGLShader', nativeType='mozilla::WebGLShader',
headerFile='WebGLContext.h')
addExternalIface('WebGLShaderPrecisionFormat',
nativeType='mozilla::WebGLShaderPrecisionFormat',
headerFile='WebGLContext.h')
addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
headerFile='WebGLContext.h')
addExternalIface('XULElement')

View file

@ -108,23 +108,6 @@ class CastableObjectUnwrapper():
"codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define(), "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define(),
"unwrapped_val" : ("Some(%s)" % unwrappedVal) if isOptional else unwrappedVal, "unwrapped_val" : ("Some(%s)" % unwrappedVal) if isOptional else unwrappedVal,
"unwrapFn": "unwrap_jsmanaged" if 'JS' in descriptor.nativeType else "unwrap_object"} "unwrapFn": "unwrap_jsmanaged" if 'JS' in descriptor.nativeType else "unwrap_object"}
if descriptor.hasXPConnectImpls:
# We don't use xpc_qsUnwrapThis because it will always throw on
# unwrap failure, whereas we want to control whether we throw or
# not.
self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
"${type} *objPtr;\n"
"xpc_qsSelfRef objRef;\n"
"JS::Value val = JS::ObjectValue(*${source});\n"
"nsresult rv = xpc_qsUnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
"if (NS_FAILED(rv)) {\n"
"${codeOnFailure}\n"
"}\n"
"// We should be castable!\n"
"MOZ_ASSERT(!objRef.ptr);\n"
"// We should have an object, too!\n"
"MOZ_ASSERT(objPtr);\n"
"${target} = objPtr;").substitute(self.substitution)), 4).define()
def __str__(self): def __str__(self):
return string.Template( return string.Template(
@ -149,8 +132,7 @@ class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
""" """
def __init__(self, descriptor, source, target, isOptional): def __init__(self, descriptor, source, target, isOptional):
CastableObjectUnwrapper.__init__(self, descriptor, source, target, CastableObjectUnwrapper.__init__(self, descriptor, source, target,
"return 0; //XXXjdm return Throw<%s>(cx, rv);" % "return 0; //XXXjdm return Throw(cx, rv);",
toStringBool(not descriptor.workers),
isOptional) isOptional)
class CGThing(): class CGThing():
@ -383,8 +365,7 @@ class CGMethodCall(CGThing):
else: else:
# Just throw; we have no idea what we're supposed to # Just throw; we have no idea what we're supposed to
# do with this. # do with this.
caseBody.append(CGGeneric("return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);" % caseBody.append(CGGeneric("return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);"))
toStringBool(not descriptor.workers)))
argCountCases.append(CGCase(str(argCount), argCountCases.append(CGCase(str(argCount),
CGList(caseBody, "\n"))) CGList(caseBody, "\n")))
@ -410,10 +391,8 @@ class CGMethodCall(CGThing):
class FakeCastableDescriptor(): class FakeCastableDescriptor():
def __init__(self, descriptor): def __init__(self, descriptor):
self.castable = True self.castable = True
self.workers = descriptor.workers
self.nativeType = "*Box<%s>" % descriptor.concreteType self.nativeType = "*Box<%s>" % descriptor.concreteType
self.name = descriptor.name self.name = descriptor.name
self.hasXPConnectImpls = descriptor.hasXPConnectImpls
class FakeInterface: class FakeInterface:
def inheritanceDepth(self): def inheritanceDepth(self):
return descriptor.interface.inheritanceDepth() return descriptor.interface.inheritanceDepth()
@ -663,7 +642,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
templateBody = ("""JSObject* seq = &${val}.toObject();\n templateBody = ("""JSObject* seq = &${val}.toObject();\n
if (!IsArrayLike(cx, seq)) { if (!IsArrayLike(cx, seq)) {
return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS); return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
} }
uint32_t length; uint32_t length;
// JS_GetArrayLength actually works on all objects // JS_GetArrayLength actually works on all objects
@ -672,18 +651,16 @@ if (!JS_GetArrayLength(cx, seq, &length)) {
} }
Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s); Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s);
if (!arr.SetCapacity(length)) { if (!arr.SetCapacity(length)) {
return Throw<%s>(cx, NS_ERROR_OUT_OF_MEMORY); return Throw(cx, NS_ERROR_OUT_OF_MEMORY);
} }
for (uint32_t i = 0; i < length; ++i) { for (uint32_t i = 0; i < length; ++i) {
jsval temp; jsval temp;
if (!JS_GetElement(cx, seq, i, &temp)) { if (!JS_GetElement(cx, seq, i, &temp)) {
return false; return false;
} }
""" % (toStringBool(descriptorProvider.workers), """ % (elementDeclType.define(),
elementDeclType.define(), elementDeclType.define(),
elementDeclType.define(), arrayRef))
arrayRef,
toStringBool(descriptorProvider.workers)))
templateBody += CGIndenter(CGGeneric( templateBody += CGIndenter(CGGeneric(
string.Template(elementTemplate).substitute( string.Template(elementTemplate).substitute(
@ -936,10 +913,9 @@ for (uint32_t i = 0; i < length; ++i) {
# Allow null pointers for nullable types and old-binding classes # Allow null pointers for nullable types and old-binding classes
argIsPointer = type.nullable() or type.unroll().inner.isExternal() argIsPointer = type.nullable() or type.unroll().inner.isExternal()
# Sequences and non-worker callbacks have to hold a strong ref to the # Sequences and callbacks have to hold a strong ref to the thing being
# thing being passed down. # passed down.
forceOwningType = (descriptor.interface.isCallback() and forceOwningType = descriptor.interface.isCallback() or isMember
not descriptor.workers) or isMember
typePtr = descriptor.nativeType typePtr = descriptor.nativeType
@ -960,11 +936,6 @@ for (uint32_t i = 0; i < length; ++i) {
templateBody = "" templateBody = ""
if descriptor.castable: if descriptor.castable:
if descriptor.prefable:
raise TypeError("We don't support prefable castable object "
"arguments (like %s), because we don't know "
"how to handle them being preffed off" %
descriptor.interface.identifier.name)
if descriptor.interface.isConsequential(): if descriptor.interface.isConsequential():
raise TypeError("Consequential interface %s being used as an " raise TypeError("Consequential interface %s being used as an "
"argument but flagged as castable" % "argument but flagged as castable" %
@ -983,8 +954,6 @@ for (uint32_t i = 0; i < length; ++i) {
"JSVAL_TO_OBJECT(${val})", "JSVAL_TO_OBJECT(${val})",
"${declName}", "${declName}",
isOptional or argIsPointer or type.nullable())) isOptional or argIsPointer or type.nullable()))
elif descriptor.workers:
templateBody += "${declName} = &${val}.toObject();"
else: else:
templateBody += ( templateBody += (
"match unwrap_value::<" + typePtr + ">(&${val} as *JSVal, " "match unwrap_value::<" + typePtr + ">(&${val} as *JSVal, "
@ -1218,8 +1187,7 @@ for (uint32_t i = 0; i < length; ++i) {
# should be able to assume not isOptional here. # should be able to assume not isOptional here.
assert not isOptional assert not isOptional
typeName = CGDictionary.makeDictionaryName(type.inner, typeName = CGDictionary.makeDictionaryName(type.inner)
descriptorProvider.workers)
actualTypeName = typeName actualTypeName = typeName
selfRef = "${declName}" selfRef = "${declName}"
@ -1574,21 +1542,11 @@ for (uint32_t i = 0; i < length; ++i) {
if (not descriptor.interface.isExternal() and if (not descriptor.interface.isExternal() and
not descriptor.interface.isCallback()): not descriptor.interface.isCallback()):
wrap = "GetReflector(cx, (%s).reflector(), ${jsvalPtr} as *mut JSVal)" % result wrap = "GetReflector(cx, (%s).reflector(), ${jsvalPtr} as *mut JSVal)" % result
# We don't support prefable stuff in workers.
assert(not descriptor.prefable or not descriptor.workers)
if not descriptor.prefable:
# Non-prefable bindings can only fail to wrap as a new-binding object # Non-prefable bindings can only fail to wrap as a new-binding object
# if they already threw an exception. Same thing for # if they already threw an exception. Same thing for
# non-prefable bindings. # non-prefable bindings.
failed = ("assert!(unsafe { JS_IsExceptionPending(cx) != 0 });\n" + failed = ("assert!(unsafe { JS_IsExceptionPending(cx) != 0 });\n" +
"%s" % exceptionCode) "%s" % exceptionCode)
else:
if descriptor.notflattened:
raise TypeError("%s is prefable but not flattened; "
"fallback won't work correctly" %
descriptor.interface.identifier.name)
# Try old-style wrapping for bindings which might be preffed off.
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
wrappingCode += wrapAndSetPtr(wrap, failed) wrappingCode += wrapAndSetPtr(wrap, failed)
else: else:
wrap = "GetReflector(cx, (%s).reflector(), ${jsvalPtr} as *mut JSVal)" % result wrap = "GetReflector(cx, (%s).reflector(), ${jsvalPtr} as *mut JSVal)" % result
@ -1722,8 +1680,7 @@ def memberIsCreator(member):
# Returns a tuple consisting of a CGThing containing the type of the return # Returns a tuple consisting of a CGThing containing the type of the return
# value, or None if there is no need for a return value, and a boolean signaling # value, or None if there is no need for a return value, and a boolean signaling
# whether the return value is passed in an out parameter. # whether the return value is passed in an out parameter.
def getRetvalDeclarationForType(returnType, descriptorProvider, def getRetvalDeclarationForType(returnType, descriptorProvider):
resultAlreadyAddRefed):
if returnType is None or returnType.isVoid(): if returnType is None or returnType.isVoid():
# Nothing to declare # Nothing to declare
return None, False return None, False
@ -1763,8 +1720,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
# If our result is already addrefed, use the right type in the # If our result is already addrefed, use the right type in the
# sequence argument here. # sequence argument here.
(result, _) = getRetvalDeclarationForType(returnType.inner, (result, _) = getRetvalDeclarationForType(returnType.inner,
descriptorProvider, descriptorProvider)
resultAlreadyAddRefed)
result = CGWrapper(result, pre="nsTArray< ", post=" >") result = CGWrapper(result, pre="nsTArray< ", post=" >")
if nullable: if nullable:
result = CGWrapper(result, pre="Nullable< ", post=" >") result = CGWrapper(result, pre="Nullable< ", post=" >")
@ -1806,11 +1762,10 @@ class PropertyDefiner:
# We only need Xrays for methods, attributes and constants. And we only # We only need Xrays for methods, attributes and constants. And we only
# need them for the non-chrome ones if we have no chromeonly things. # need them for the non-chrome ones if we have no chromeonly things.
# Otherwise (we have chromeonly attributes) we need Xrays for the chrome # Otherwise (we have chromeonly attributes) we need Xrays for the chrome
# methods/attributes/constants. Finally, in workers there are no Xrays. # methods/attributes/constants.
return ((self.name is "Methods" or self.name is "Attributes" or return ((self.name is "Methods" or self.name is "Attributes" or
self.name is "Constants") and self.name is "Constants") and
chrome == self.hasChromeOnly() and chrome == self.hasChromeOnly())
not self.descriptor.workers)
def __str__(self): def __str__(self):
# We only need to generate id arrays for things that will end # We only need to generate id arrays for things that will end
@ -1954,7 +1909,7 @@ class MethodDefiner(PropertyDefiner):
"flags": "JSPROP_ENUMERATE", "flags": "JSPROP_ENUMERATE",
"pref": None }) "pref": None })
#if not descriptor.interface.parent and not static and not descriptor.workers: #if not descriptor.interface.parent and not static:
# self.chrome.append({"name": 'QueryInterface', # self.chrome.append({"name": 'QueryInterface',
# "methodInfo": False, # "methodInfo": False,
# "length": 1, # "length": 1,
@ -2086,13 +2041,9 @@ class CGNativePropertyHooks(CGThing):
CGThing.__init__(self) CGThing.__init__(self)
self.descriptor = descriptor self.descriptor = descriptor
def declare(self): def declare(self):
if self.descriptor.workers:
return ""
#return "extern const NativePropertyHooks NativeHooks;\n" #return "extern const NativePropertyHooks NativeHooks;\n"
return "" return ""
def define(self): def define(self):
if self.descriptor.workers:
return ""
if self.descriptor.concrete and self.descriptor.proxy: if self.descriptor.concrete and self.descriptor.proxy:
resolveOwnProperty = "ResolveOwnProperty" resolveOwnProperty = "ResolveOwnProperty"
enumerateOwnProperties = "EnumerateOwnProperties" enumerateOwnProperties = "EnumerateOwnProperties"
@ -2234,12 +2185,11 @@ def DOMClass(descriptor):
# padding. # padding.
protoList.extend(['PrototypeList::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList))) protoList.extend(['PrototypeList::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
prototypeChainString = ', '.join(protoList) prototypeChainString = ', '.join(protoList)
nativeHooks = "0 as *NativePropertyHooks" if descriptor.workers else "&NativeHooks as *NativePropertyHooks"
return """DOMClass { return """DOMClass {
interface_chain: [ %s ], interface_chain: [ %s ],
unused: %s, native_hooks: %s unused: false,
}""" % (prototypeChainString, "false", #toStringBool(descriptor.nativeIsISupports), native_hooks: &NativeHooks as *NativePropertyHooks
nativeHooks) }""" % prototypeChainString
class CGDOMJSClass(CGThing): class CGDOMJSClass(CGThing):
""" """
@ -2252,7 +2202,7 @@ class CGDOMJSClass(CGThing):
#return "extern DOMJSClass Class;\n" #return "extern DOMJSClass Class;\n"
return "" return ""
def define(self): def define(self):
traceHook = "Some(%s)" % TRACE_HOOK_NAME if self.descriptor.customTrace else 'None' traceHook = "Some(%s)" % TRACE_HOOK_NAME
if self.descriptor.createGlobal: if self.descriptor.createGlobal:
flags = "JSCLASS_IS_GLOBAL" flags = "JSCLASS_IS_GLOBAL"
slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1" slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1"
@ -2291,7 +2241,6 @@ static Class: DOMJSClass = DOMJSClass {
""" % (len(self.descriptor.interface.identifier.name) + 1, """ % (len(self.descriptor.interface.identifier.name) + 1,
str_to_const_array(self.descriptor.interface.identifier.name), str_to_const_array(self.descriptor.interface.identifier.name),
flags, slots, slots, flags, slots, slots,
#ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers and self.descriptor.wrapperCache else 'crust::JS_PropertyStub',
'crust::JS_PropertyStub', 'crust::JS_PropertyStub',
FINALIZE_HOOK_NAME, traceHook, FINALIZE_HOOK_NAME, traceHook,
CGIndenter(CGGeneric(DOMClass(self.descriptor))).define()) CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
@ -2345,7 +2294,7 @@ class CGInterfaceObjectJSClass(CGThing):
# We're purely for internal consumption # We're purely for internal consumption
return "" return ""
def define(self): def define(self):
if not self.descriptor.hasInstanceInterface: if True:
return "" return ""
ctorname = "0 as *u8" if not self.descriptor.interface.ctor() else CONSTRUCT_HOOK_NAME ctorname = "0 as *u8" if not self.descriptor.interface.ctor() else CONSTRUCT_HOOK_NAME
hasinstance = HASINSTANCE_HOOK_NAME hasinstance = HASINSTANCE_HOOK_NAME
@ -2662,9 +2611,6 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
CGAbstractMethod.__init__(self, descriptor, 'Wrap_', '*JSObject', args) CGAbstractMethod.__init__(self, descriptor, 'Wrap_', '*JSObject', args)
def definition_body(self): def definition_body(self):
if self.descriptor.workers:
return """return aObject->GetJSObject();"""
if not self.descriptor.createGlobal: if not self.descriptor.createGlobal:
return """ return """
assert!(aScope.is_not_null()); assert!(aScope.is_not_null());
@ -2702,27 +2648,6 @@ class CGWrapMethod(CGAbstractMethod):
def definition_body(self): def definition_body(self):
return "return Wrap_(aCx, aScope, aObject);" return "return Wrap_(aCx, aScope, aObject);"
class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
def __init__(self, descriptor):
# XXX can we wrap if we don't have an interface prototype object?
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
Argument('@' + descriptor.nativeType, 'aObject')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
def definition_body(self):
return """
JSObject* global = JS_GetGlobalForObject(aCx, aScope);
JSObject* proto = GetProtoObject(aCx, global, global);
if (!proto) {
return NULL;
}
%s
NS_ADDREF(aObject);
return obj;""" % CreateBindingJSObject(self.descriptor, "global")
class CGAbstractExternMethod(CGAbstractMethod): class CGAbstractExternMethod(CGAbstractMethod):
""" """
Abstract base class for codegen of implementation-only (no Abstract base class for codegen of implementation-only (no
@ -2792,9 +2717,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
assert needInterfaceObject or needInterfacePrototypeObject assert needInterfaceObject or needInterfacePrototypeObject
idsToInit = [] idsToInit = []
# There is no need to init any IDs in workers, because worker bindings if False: #XXXjdm don't need xray stuff yet
# don't have Xrays.
if False and not self.descriptor.workers: #XXXjdm don't need xray stuff yet
for var in self.properties.xrayRelevantArrayNames(): for var in self.properties.xrayRelevantArrayNames():
props = getattr(self.properties, var) props = getattr(self.properties, var)
# We only have non-chrome ids to init if we have no chrome ids. # We only have non-chrome ids to init if we have no chrome ids.
@ -2845,10 +2768,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
" return ptr::null();\n" + " return ptr::null();\n" +
"}\n") % getParentProto "}\n") % getParentProto
needInterfaceObjectClass = (needInterfaceObject and
self.descriptor.hasInstanceInterface)
needConstructor = (needInterfaceObject and
not self.descriptor.hasInstanceInterface)
if self.descriptor.interface.ctor(): if self.descriptor.interface.ctor():
constructHook = CONSTRUCT_HOOK_NAME constructHook = CONSTRUCT_HOOK_NAME
constructArgs = methodLength(self.descriptor.interface.ctor()) constructArgs = methodLength(self.descriptor.interface.ctor())
@ -2871,7 +2790,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
return "ptr::to_unsafe_ptr(&%s[0])" % val return "ptr::to_unsafe_ptr(&%s[0])" % val
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
%s, %s, %s, %d, %s, ptr::null(), %s, %d,
%s, %s,
%s, %s,
%s, %s,
@ -2879,17 +2798,13 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
%s, %s,
%s);""" % ( %s);""" % (
"&PrototypeClass" if needInterfacePrototypeObject else "ptr::null()", "&PrototypeClass" if needInterfacePrototypeObject else "ptr::null()",
"&InterfaceObjectClass" if needInterfaceObjectClass else "ptr::null()", "Some(%s)" % constructHook if needInterfaceObject else "None",
"Some(%s)" % constructHook if needConstructor else "None",
constructArgs, constructArgs,
domClass, domClass,
arrayPtr("methods"), arrayPtr("attrs"), arrayPtr("methods"), arrayPtr("attrs"),
arrayPtr("consts"), arrayPtr("staticMethods"), arrayPtr("consts"), arrayPtr("staticMethods"),
'"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "ptr::null()") '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "ptr::null()")
if self.properties.hasChromeOnly(): if self.properties.hasChromeOnly():
if self.descriptor.workers:
accessCheck = "mozilla::dom::workers::GetWorkerPrivateFromContext(aCx)->IsChromeWorker()"
else:
accessCheck = "xpc::AccessCheck::isChrome(js::GetObjectCompartment(aGlobal))" accessCheck = "xpc::AccessCheck::isChrome(js::GetObjectCompartment(aGlobal))"
chrome = CGIfWrapper(CGGeneric(call % self.properties.variableNames(True)), chrome = CGIfWrapper(CGGeneric(call % self.properties.variableNames(True)),
accessCheck) accessCheck)
@ -2974,14 +2889,10 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'bool', args, pub=True) CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'bool', args, pub=True)
def declare(self): def declare(self):
if self.descriptor.workers:
return ''
#return CGAbstractMethod.declare(self) #return CGAbstractMethod.declare(self)
return "" return ""
def define(self): def define(self):
if self.descriptor.workers:
return ''
return CGAbstractMethod.define(self) return CGAbstractMethod.define(self)
def definition_body(self): def definition_body(self):
@ -3030,7 +2941,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
CreateProxyHandler(ptr::to_unsafe_ptr(&traps), ptr::to_unsafe_ptr(&Class) as *libc::c_void)); CreateProxyHandler(ptr::to_unsafe_ptr(&traps), ptr::to_unsafe_ptr(&Class) as *libc::c_void));
""" % (FINALIZE_HOOK_NAME, """ % (FINALIZE_HOOK_NAME,
('Some(%s)' % TRACE_HOOK_NAME) if self.descriptor.customTrace else 'None', ('Some(%s)' % TRACE_HOOK_NAME),
self.descriptor.name) self.descriptor.name)
else: else:
body += """ (*page).js_info.get_ref().dom_static.attribute_ids.insert(PrototypeList::id::%s as uint, body += """ (*page).js_info.get_ref().dom_static.attribute_ids.insert(PrototypeList::id::%s as uint,
@ -3043,14 +2954,10 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
*aEnabled = true; *aEnabled = true;
return %s(aCx, global, aReceiver).is_not_null();""" % (getter)) return %s(aCx, global, aReceiver).is_not_null();""" % (getter))
def isResultAlreadyAddRefed(extendedAttributes):
return not 'resultNotAddRefed' in extendedAttributes
def needCx(returnType, arguments, extendedAttributes, considerTypes): def needCx(returnType, arguments, extendedAttributes, considerTypes):
return (considerTypes and return (considerTypes and
(typeNeedsCx(returnType, True) or (typeNeedsCx(returnType, True) or
any(typeNeedsCx(a.type) for a in arguments)) or any(typeNeedsCx(a.type) for a in arguments)))
'implicitJSContext' in extendedAttributes)
def needScopeObject(returnType, arguments, extendedAttributes, def needScopeObject(returnType, arguments, extendedAttributes,
isWrapperCached, considerTypes): isWrapperCached, considerTypes):
@ -3075,12 +2982,8 @@ class CGCallGenerator(CGThing):
isFallible = errorReport is not None isFallible = errorReport is not None
#resultAlreadyAddRefed = isResultAlreadyAddRefed(descriptorProvider,
# extendedAttributes)
resultAlreadyAddRefed = True
(result, resultOutParam) = getRetvalDeclarationForType(returnType, (result, resultOutParam) = getRetvalDeclarationForType(returnType,
descriptorProvider, descriptorProvider)
resultAlreadyAddRefed)
args = CGList([CGGeneric(arg) for arg in argsPre], ", ") args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
for (a, name) in arguments: for (a, name) in arguments:
@ -3101,8 +3004,7 @@ class CGCallGenerator(CGThing):
args.append(CGGeneric("result")) args.append(CGGeneric("result"))
needsCx = (typeNeedsCx(returnType, True) or needsCx = (typeNeedsCx(returnType, True) or
any(typeNeedsCx(a.type) for (a, _) in arguments) or any(typeNeedsCx(a.type) for (a, _) in arguments))
'implicitJSContext' in extendedAttributes)
if not "cx" in argsPre and needsCx: if not "cx" in argsPre and needsCx:
args.prepend(CGGeneric("cx")) args.prepend(CGGeneric("cx"))
@ -3214,15 +3116,6 @@ class CGPerSignatureCall(CGThing):
def wrap_return_value(self): def wrap_return_value(self):
isCreator = memberIsCreator(self.idlNode) isCreator = memberIsCreator(self.idlNode)
if isCreator:
# We better be returning addrefed things!
#assert(isResultAlreadyAddRefed(self.descriptor,
# self.extendedAttributes) or
# Workers use raw pointers for new-object return
# values or something
# self.descriptor.workers)
pass
resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp', resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp',
'isCreator': isCreator} 'isCreator': isCreator}
try: try:
@ -3344,8 +3237,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
if unwrapFailureCode is None: if unwrapFailureCode is None:
self.unwrapFailureCode = ("return 0; //XXXjdm return Throw<%s>(cx, rv);" % self.unwrapFailureCode = "return 0; //XXXjdm return Throw(cx, rv);"
toStringBool(not descriptor.workers))
else: else:
self.unwrapFailureCode = unwrapFailureCode self.unwrapFailureCode = unwrapFailureCode
@ -3414,7 +3306,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
def definition_body(self): def definition_body(self):
name = self.method.identifier.name name = self.method.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name)) nativeName = MakeNativeName(name)
extraPre = '' extraPre = ''
argsPre = [] argsPre = []
if name in self.descriptor.needsAbstract: if name in self.descriptor.needsAbstract:
@ -3469,13 +3361,11 @@ class CGSpecializedGetter(CGAbstractExternMethod):
def definition_body(self): def definition_body(self):
name = self.attr.identifier.name name = self.attr.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name)) nativeName = MakeNativeName(name)
extraPre = '' extraPre = ''
argsPre = [] argsPre = []
# resultOutParam does not depend on whether resultAlreadyAddRefed is set
(_, resultOutParam) = getRetvalDeclarationForType(self.attr.type, (_, resultOutParam) = getRetvalDeclarationForType(self.attr.type,
self.descriptor, self.descriptor)
False)
infallible = ('infallible' in infallible = ('infallible' in
self.descriptor.getExtendedAttributes(self.attr, self.descriptor.getExtendedAttributes(self.attr,
getter=True)) getter=True))
@ -3539,7 +3429,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
def definition_body(self): def definition_body(self):
name = self.attr.identifier.name name = self.attr.identifier.name
nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name)) nativeName = "Set" + MakeNativeName(name)
argsPre = [] argsPre = []
extraPre = '' extraPre = ''
if name in self.descriptor.needsAbstract: if name in self.descriptor.needsAbstract:
@ -4473,7 +4363,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
(don't use this directly, use the derived classes below). (don't use this directly, use the derived classes below).
""" """
def __init__(self, descriptor, operation): def __init__(self, descriptor, operation):
nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation)) nativeName = MakeNativeName(operation)
operation = descriptor.operations[operation] operation = descriptor.operations[operation]
assert len(operation.signatures()) == 1 assert len(operation.signatures()) == 1
signature = operation.signatures()[0] signature = operation.signatures()[0]
@ -4836,8 +4726,7 @@ class CGDOMJSProxyHandler_obj_toString(CGAbstractExternMethod):
def getBody(self): def getBody(self):
stringifier = self.descriptor.operations['Stringifier'] stringifier = self.descriptor.operations['Stringifier']
if stringifier: if stringifier:
name = stringifier.identifier.name nativeName = MakeNativeName(stringifier.identifier.name)
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
signature = stringifier.signatures()[0] signature = stringifier.signatures()[0]
returnType = signature[0] returnType = signature[0]
extendedAttributes = self.descriptor.getExtendedAttributes(stringifier) extendedAttributes = self.descriptor.getExtendedAttributes(stringifier)
@ -4883,21 +4772,10 @@ class CGAbstractClassHook(CGAbstractExternMethod):
assert(False) assert(False)
def finalizeHook(descriptor, hookName, context): def finalizeHook(descriptor, hookName, context):
if descriptor.customFinalize:
return """if (this) {
this->%s(%s);
}""" % (hookName, context)
#clearWrapper = "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
if descriptor.workers:
#release = "self->Release();"
pass
else:
assert descriptor.nativeIsISupports
release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj)); release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj));
let _: %s %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val)); let _: %s %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val));
debug!("%s finalize: {:p}", this); debug!("%s finalize: {:p}", this);
""" % (DOMObjectPointerType(descriptor), descriptor.concreteType, descriptor.concreteType) """ % (DOMObjectPointerType(descriptor), descriptor.concreteType, descriptor.concreteType)
#return clearWrapper + release
return release return release
class CGClassTraceHook(CGAbstractClassHook): class CGClassTraceHook(CGAbstractClassHook):
@ -4933,11 +4811,6 @@ class CGClassConstructHook(CGAbstractExternMethod):
def generate_code(self): def generate_code(self):
preamble = """ preamble = """
//JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp))); //JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
"""
if self.descriptor.workers:
preArgs = ["cx", "obj"]
else:
preamble += """
//XXXjdm Gecko obtains a GlobalObject from the global (maybe from the private value, //XXXjdm Gecko obtains a GlobalObject from the global (maybe from the private value,
// or through unwrapping a slot or something). We'll punt and get the Window // or through unwrapping a slot or something). We'll punt and get the Window
// from the context for now. // from the context for now.
@ -4945,65 +4818,11 @@ class CGClassConstructHook(CGAbstractExternMethod):
let global = (*page).frame.get_ref().window.clone(); let global = (*page).frame.get_ref().window.clone();
let obj = global.reflector().get_jsobject(); let obj = global.reflector().get_jsobject();
""" """
preArgs = ["&global"] nativeName = MakeNativeName(self._ctor.identifier.name)
callGenerator = CGMethodCall(["&global"], nativeName, True,
name = self._ctor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
callGenerator = CGMethodCall(preArgs, nativeName, True,
self.descriptor, self._ctor) self.descriptor, self._ctor)
return preamble + callGenerator.define(); return preamble + callGenerator.define();
class CGClassHasInstanceHook(CGAbstractStaticMethod):
def __init__(self, descriptor):
args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'),
Argument('JSMutableHandleValue', 'vp'), Argument('*JSBool', 'bp')]
CGAbstractStaticMethod.__init__(self, descriptor, HASINSTANCE_HOOK_NAME,
'JSBool', args)
def define(self):
if not self.descriptor.hasInstanceInterface:
return ""
return CGAbstractStaticMethod.define(self)
def definition_body(self):
return self.generate_code()
def generate_code(self):
return """ if (!vp.isObject()) {
*bp = 0;
return 1;
}
jsval protov;
if (!JS_GetProperty(cx, obj, "prototype", &protov))
return false;
if (!protov.isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE,
"%s");
return false;
}
JSObject *objProto = &protov.toObject();
JSObject* instance = &vp.toObject();
JSObject* proto;
if (!JS_GetPrototype(cx, instance, &proto))
return false;
while (proto) {
if (proto == objProto) {
*bp = true;
return true;
}
if (!JS_GetPrototype(cx, proto, &proto))
return false;
}
nsISupports* native =
nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, instance);
nsCOMPtr<%s> qiResult = do_QueryInterface(native);
*bp = !!qiResult;
return true;
""" % (self.descriptor.name, self.descriptor.hasInstanceInterface)
class CGClassFinalizeHook(CGAbstractClassHook): class CGClassFinalizeHook(CGAbstractClassHook):
""" """
A hook for finalize, used to release our native object. A hook for finalize, used to release our native object.
@ -5066,42 +4885,26 @@ class CGDescriptor(CGThing):
# lenientThis=True)) # lenientThis=True))
if descriptor.concrete: if descriptor.concrete:
if not descriptor.workers and descriptor.wrapperCache:
#cgThings.append(CGAddPropertyHook(descriptor))
pass
# Always have a finalize hook, regardless of whether the class wants a
# custom hook.
cgThings.append(CGClassFinalizeHook(descriptor)) cgThings.append(CGClassFinalizeHook(descriptor))
# Only generate a trace hook if the class wants a custom hook.
if (descriptor.customTrace):
cgThings.append(CGClassTraceHook(descriptor)) cgThings.append(CGClassTraceHook(descriptor))
if descriptor.interface.hasInterfaceObject(): if descriptor.interface.hasInterfaceObject():
cgThings.append(CGClassConstructHook(descriptor)) cgThings.append(CGClassConstructHook(descriptor))
cgThings.append(CGClassHasInstanceHook(descriptor))
cgThings.append(CGInterfaceObjectJSClass(descriptor)) cgThings.append(CGInterfaceObjectJSClass(descriptor))
pass
if descriptor.interface.hasInterfacePrototypeObject(): if descriptor.interface.hasInterfacePrototypeObject():
cgThings.append(CGPrototypeJSClass(descriptor)) cgThings.append(CGPrototypeJSClass(descriptor))
pass
properties = PropertyArrays(descriptor) properties = PropertyArrays(descriptor)
cgThings.append(CGGeneric(define=str(properties))) cgThings.append(CGGeneric(define=str(properties)))
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties)) cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
if descriptor.interface.hasInterfacePrototypeObject(): if descriptor.interface.hasInterfacePrototypeObject():
cgThings.append(CGGetProtoObjectMethod(descriptor)) cgThings.append(CGGetProtoObjectMethod(descriptor))
pass
else: else:
cgThings.append(CGGetConstructorObjectMethod(descriptor)) cgThings.append(CGGetConstructorObjectMethod(descriptor))
pass
# Set up our Xray callbacks as needed. Note that we don't need to do # Set up our Xray callbacks as needed.
# it in workers. if descriptor.interface.hasInterfacePrototypeObject():
if (descriptor.interface.hasInterfacePrototypeObject() and
not descriptor.workers):
if descriptor.concrete and descriptor.proxy: if descriptor.concrete and descriptor.proxy:
#cgThings.append(CGResolveOwnProperty(descriptor)) #cgThings.append(CGResolveOwnProperty(descriptor))
#cgThings.append(CGEnumerateOwnProperties(descriptor)) #cgThings.append(CGEnumerateOwnProperties(descriptor))
@ -5112,8 +4915,6 @@ class CGDescriptor(CGThing):
if descriptor.interface.hasInterfaceObject(): if descriptor.interface.hasInterfaceObject():
cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
if (not descriptor.interface.isExternal() and if (not descriptor.interface.isExternal() and
# Workers stuff is never pref-controlled
not descriptor.workers and
descriptor.interface.getExtendedAttribute("PrefControlled") is not None): descriptor.interface.getExtendedAttribute("PrefControlled") is not None):
#cgThings.append(CGPrefEnabled(descriptor)) #cgThings.append(CGPrefEnabled(descriptor))
pass pass
@ -5141,13 +4942,8 @@ class CGDescriptor(CGThing):
cgThings.append(CGDOMJSClass(descriptor)) cgThings.append(CGDOMJSClass(descriptor))
pass pass
if descriptor.wrapperCache:
cgThings.append(CGWrapWithCacheMethod(descriptor)) cgThings.append(CGWrapWithCacheMethod(descriptor))
cgThings.append(CGWrapMethod(descriptor)) cgThings.append(CGWrapMethod(descriptor))
pass
else:
cgThings.append(CGWrapNonWrapperCacheMethod(descriptor))
pass
cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n") cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n")
cgThings = CGWrapper(cgThings, pre='\n', post='\n') cgThings = CGWrapper(cgThings, pre='\n', post='\n')
@ -5209,7 +5005,6 @@ class CGNamespacedEnum(CGThing):
class CGDictionary(CGThing): class CGDictionary(CGThing):
def __init__(self, dictionary, descriptorProvider): def __init__(self, dictionary, descriptorProvider):
self.dictionary = dictionary; self.dictionary = dictionary;
self.workers = descriptorProvider.workers
if all(CGDictionary(d, descriptorProvider).generatable for if all(CGDictionary(d, descriptorProvider).generatable for
d in CGDictionary.getDictionaryDependencies(dictionary)): d in CGDictionary.getDictionaryDependencies(dictionary)):
self.generatable = True self.generatable = True
@ -5217,11 +5012,6 @@ class CGDictionary(CGThing):
self.generatable = False self.generatable = False
# Nothing else to do here # Nothing else to do here
return return
# Getting a conversion template for interface types can fail
# if we don't have a relevant descriptor when self.workers is True.
# If that happens, just mark ourselves as not being
# generatable and move on.
try:
self.memberInfo = [ self.memberInfo = [
(member, (member,
getJSToNativeConversionTemplate(member.type, getJSToNativeConversionTemplate(member.type,
@ -5230,10 +5020,6 @@ class CGDictionary(CGThing):
isOptional=(not member.defaultValue), isOptional=(not member.defaultValue),
defaultValue=member.defaultValue)) defaultValue=member.defaultValue))
for member in dictionary.members ] for member in dictionary.members ]
except NoSuchDescriptorError, err:
if not self.workers:
raise err
self.generatable = False
def declare(self): def declare(self):
if not self.generatable: if not self.generatable:
@ -5252,7 +5038,6 @@ class CGDictionary(CGThing):
"pub struct ${selfName} {\n" + "pub struct ${selfName} {\n" +
"${inheritance}" + "${inheritance}" +
"\n".join(memberDecls) + "\n" + "\n".join(memberDecls) + "\n" +
# NOTE: jsids are per-runtime, so don't use them in workers
"\n".join(" //static jsid " + "\n".join(" //static jsid " +
self.makeIdName(m.identifier.name) + ";" for self.makeIdName(m.identifier.name) + ";" for
m in d.members) + "\n" m in d.members) + "\n"
@ -5296,8 +5081,7 @@ class CGDictionary(CGThing):
return "/* uh oh: %s */" % ty return "/* uh oh: %s */" % ty
return string.Template( return string.Template(
# NOTE: jsids are per-runtime, so don't use them in workers "static initedIds: bool = false;\n" +
("static initedIds: bool = false;\n" +
"\n".join("static %s: jsid = JSID_VOID;" % "\n".join("static %s: jsid = JSID_VOID;" %
self.makeIdName(m.identifier.name) self.makeIdName(m.identifier.name)
for m in d.members) + "\n" for m in d.members) + "\n"
@ -5317,20 +5101,19 @@ class CGDictionary(CGThing):
" initedIds = true;*/ //XXXjdm\n" " initedIds = true;*/ //XXXjdm\n"
" return true;\n" " return true;\n"
" }\n" " }\n"
"\n" if not self.workers else "") + "\n"
" pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n" " pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n"
" unsafe {\n" + " unsafe {\n"
# NOTE: jsids are per-runtime, so don't use them in workers " if (!initedIds && !self.InitIds(cx)) {\n"
(" if (!initedIds && !self.InitIds(cx)) {\n"
" return 0;\n" " return 0;\n"
" }\n" if not self.workers else "") + " }\n"
"${initParent}" "${initParent}"
" let mut found: JSBool = 0;\n" " let mut found: JSBool = 0;\n"
" let temp: JSVal = JSVAL_NULL;\n" " let temp: JSVal = JSVAL_NULL;\n"
" let isNull = RUST_JSVAL_IS_NULL(val) != 0 || RUST_JSVAL_IS_VOID(val) != 0;\n" " let isNull = RUST_JSVAL_IS_NULL(val) != 0 || RUST_JSVAL_IS_VOID(val) != 0;\n"
" if !isNull && RUST_JSVAL_IS_PRIMITIVE(val) != 0 {\n" " if !isNull && RUST_JSVAL_IS_PRIMITIVE(val) != 0 {\n"
" return 0; //XXXjdm throw properly here\n" " return 0; //XXXjdm throw properly here\n"
" //return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n" " //return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
" }\n" " }\n"
"\n" "\n"
"${initMembers}\n" "${initMembers}\n"
@ -5342,16 +5125,14 @@ class CGDictionary(CGThing):
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=6).define(), "initParent": CGIndenter(CGGeneric(initParent), indentLevel=6).define(),
"initMembers": "\n\n".join(memberInits), "initMembers": "\n\n".join(memberInits),
"idInit": CGIndenter(idinit).define(), "idInit": CGIndenter(idinit).define(),
"isMainThread": toStringBool(not self.workers)
}) })
@staticmethod @staticmethod
def makeDictionaryName(dictionary, workers): def makeDictionaryName(dictionary):
suffix = "Workers" if workers else "" return dictionary.identifier.name
return dictionary.identifier.name + suffix
def makeClassName(self, dictionary): def makeClassName(self, dictionary):
return self.makeDictionaryName(dictionary, self.workers) return self.makeDictionaryName(dictionary)
@staticmethod @staticmethod
def makeModuleName(dictionary): def makeModuleName(dictionary):
@ -5388,8 +5169,7 @@ class CGDictionary(CGThing):
if member.defaultValue: if member.defaultValue:
replacements["haveValue"] = "found != 0" replacements["haveValue"] = "found != 0"
# NOTE: jsids are per-runtime, so don't use them in workers if True: #XXXjdm hack until 'static mut' exists for global jsids
if True or self.workers: #XXXjdm hack until 'static mut' exists for global jsids
propName = member.identifier.name propName = member.identifier.name
propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, RUST_JSVAL_TO_OBJECT(val), s, ptr::to_unsafe_ptr(&found)) })' % propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, RUST_JSVAL_TO_OBJECT(val), s, ptr::to_unsafe_ptr(&found)) })' %
propName) propName)
@ -5472,7 +5252,6 @@ class CGRegisterProtos(CGAbstractMethod):
" &mut unused));" % (desc.name) " &mut unused));" % (desc.name)
for desc in self.config.getDescriptors(hasInterfaceObject=True, for desc in self.config.getDescriptors(hasInterfaceObject=True,
isExternal=False, isExternal=False,
workers=False,
register=True)] register=True)]
return '\n'.join(lines) + '\n' return '\n'.join(lines) + '\n'
def definition_body(self): def definition_body(self):
@ -5490,8 +5269,7 @@ class CGBindingRoot(CGThing):
cgthings = [] cgthings = []
mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile, mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile)
workers=False)
callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile, callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
isCallback=True) isCallback=True)
@ -5529,22 +5307,18 @@ class CGBindingRoot(CGThing):
reSortedDictionaries.extend(toMove) reSortedDictionaries.extend(toMove)
dictionaries = reSortedDictionaries dictionaries = reSortedDictionaries
#XXXjdm No codegen for workers right now. cgthings.extend([CGDictionary(d, config.getDescriptorProvider())
#cgthings.extend([CGDictionary(d, config.getDescriptorProvider(True))
# for d in dictionaries])
cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False))
for d in dictionaries]) for d in dictionaries])
# Do codegen for all the callbacks. # Do codegen for all the callbacks.
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False)) cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider())
for c in mainCallbacks) for c in mainCallbacks)
# Do codegen for all the descriptors # Do codegen for all the descriptors
cgthings.extend([CGDescriptor(x) for x in descriptors]) cgthings.extend([CGDescriptor(x) for x in descriptors])
# Do codegen for all the callback interfaces. Skip worker callbacks. # Do codegen for all the callback interfaces.
cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors])
not x.workers])
# And make sure we have the right number of newlines at the end # And make sure we have the right number of newlines at the end
curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n") curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
@ -5606,13 +5380,11 @@ class CGNativeMember(ClassMethod):
passed as JSObject*. passed as JSObject*.
If passJSBitsAsNeeded is false, we don't automatically pass in a If passJSBitsAsNeeded is false, we don't automatically pass in a
JSContext* or a JSObject* based on the return and argument types. We JSContext* or a JSObject* based on the return and argument types.
can still pass it based on 'implicitJSContext' annotations.
""" """
self.descriptorProvider = descriptorProvider self.descriptorProvider = descriptorProvider
self.member = member self.member = member
self.extendedAttrs = extendedAttrs self.extendedAttrs = extendedAttrs
self.resultAlreadyAddRefed = isResultAlreadyAddRefed(self.extendedAttrs)
self.passJSBitsAsNeeded = passJSBitsAsNeeded self.passJSBitsAsNeeded = passJSBitsAsNeeded
self.jsObjectsArePtr = jsObjectsArePtr self.jsObjectsArePtr = jsObjectsArePtr
self.variadicIsSequence = variadicIsSequence self.variadicIsSequence = variadicIsSequence
@ -5692,21 +5464,7 @@ class CGNativeMember(ClassMethod):
nativeType.pop(0) nativeType.pop(0)
if nativeType[0] == "dom": if nativeType[0] == "dom":
nativeType.pop(0) nativeType.pop(0)
result = CGGeneric("::".join(nativeType)) result = CGWrapper(CGGeneric("::".join(nativeType)), post="*")
if self.resultAlreadyAddRefed:
if isMember:
holder = "nsRefPtr"
else:
holder = "already_AddRefed"
if memberReturnsNewObject(self.member):
warning = ""
else:
warning = "// Mark this as resultNotAddRefed to return raw pointers\n"
result = CGWrapper(result,
pre=("%s%s<" % (warning, holder)),
post=">")
else:
result = CGWrapper(result, post="*")
# Since we always force an owning type for callback return values, # Since we always force an owning type for callback return values,
# our ${declName} is an OwningNonNull or nsRefPtr. So we can just # our ${declName} is an OwningNonNull or nsRefPtr. So we can just
# .forget() to get our already_AddRefed. # .forget() to get our already_AddRefed.
@ -6107,11 +5865,6 @@ class FakeMember():
def isMethod(self): def isMethod(self):
return False return False
def getExtendedAttribute(self, name): def getExtendedAttribute(self, name):
# Claim to be a [NewObject] so we can avoid the "mark this
# resultNotAddRefed" comments CGNativeMember codegen would
# otherwise stick in.
if name == "NewObject":
return True
return None return None
class CallbackMember(CGNativeMember): class CallbackMember(CGNativeMember):
@ -6565,7 +6318,6 @@ class GlobalGenRoots():
# Add the includes # Add the includes
defineIncludes = [CGImports.getDeclarationFilename(desc.interface) defineIncludes = [CGImports.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True, for desc in config.getDescriptors(hasInterfaceObject=True,
workers=False,
register=True)] register=True)]
curr = CGImports([], [], ['dom::bindings::codegen', curr = CGImports([], [], ['dom::bindings::codegen',
'js::rust::Compartment'], defineIncludes, curr) 'js::rust::Compartment'], defineIncludes, curr)
@ -6613,7 +6365,7 @@ class GlobalGenRoots():
derived = [CGGeneric(declare='pub trait %s { fn %s(&self) -> bool; }\n' % derived = [CGGeneric(declare='pub trait %s { fn %s(&self) -> bool; }\n' %
(name + 'Derived', 'is_' + name.lower()))] (name + 'Derived', 'is_' + name.lower()))]
for protoName in descriptor.prototypeChain[1:-1]: for protoName in descriptor.prototypeChain[1:-1]:
protoDescriptor = config.getDescriptor(protoName, False) protoDescriptor = config.getDescriptor(protoName)
delegate = string.Template('''impl ${selfName} for ${baseName} { delegate = string.Template('''impl ${selfName} for ${baseName} {
fn ${fname}(&self) -> bool { fn ${fname}(&self) -> bool {
self.${parentName}.${fname}() self.${parentName}.${fname}()

View file

@ -78,46 +78,31 @@ class Configuration:
return filter(lambda e: e.filename() == webIDLFile, self.enums) return filter(lambda e: e.filename() == webIDLFile, self.enums)
@staticmethod @staticmethod
def _filterForFileAndWorkers(items, filters): def _filterForFile(items, webIDLFile=""):
"""Gets the items that match the given filters.""" """Gets the items that match the given filters."""
for key, val in filters.iteritems(): return filter(lambda x: x.filename() == webIDLFile, items)
if key == 'webIDLFile': def getDictionaries(self, webIDLFile=""):
items = filter(lambda x: x.filename() == val, items) return self._filterForFile(self.dictionaries, webIDLFile=webIDLFile)
elif key == 'workers': def getCallbacks(self, webIDLFile=""):
if val: return self._filterForFile(self.callbacks, webIDLFile=webIDLFile)
items = filter(lambda x: x.getUserData("workers", False), items)
else:
items = filter(lambda x: x.getUserData("mainThread", False), items)
else:
assert(0) # Unknown key
return items
def getDictionaries(self, **filters):
return self._filterForFileAndWorkers(self.dictionaries, filters)
def getCallbacks(self, **filters):
return self._filterForFileAndWorkers(self.callbacks, filters)
def getDescriptor(self, interfaceName, workers): def getDescriptor(self, interfaceName):
""" """
Gets the appropriate descriptor for the given interface name Gets the appropriate descriptor for the given interface name.
and the given workers boolean.
""" """
iface = self.getInterface(interfaceName) iface = self.getInterface(interfaceName)
descriptors = self.getDescriptors(interface=iface) descriptors = self.getDescriptors(interface=iface)
# The only filter we currently have is workers vs non-workers. # We should have exactly one result.
matches = filter(lambda x: x.workers is workers, descriptors) if len(descriptors) is not 1:
# After filtering, we should have exactly one result.
if len(matches) is not 1:
raise NoSuchDescriptorError("For " + interfaceName + " found " + raise NoSuchDescriptorError("For " + interfaceName + " found " +
str(len(matches)) + " matches"); str(len(matches)) + " matches");
return matches[0] return descriptors[0]
def getDescriptorProvider(self, workers): def getDescriptorProvider(self):
""" """
Gets a descriptor provider that can provide descriptors as needed, Gets a descriptor provider that can provide descriptors as needed.
for the given workers boolean
""" """
return DescriptorProvider(self, workers) return DescriptorProvider(self)
class NoSuchDescriptorError(TypeError): class NoSuchDescriptorError(TypeError):
def __init__(self, str): def __init__(self, str):
@ -127,53 +112,36 @@ class DescriptorProvider:
""" """
A way of getting descriptors for interface names A way of getting descriptors for interface names
""" """
def __init__(self, config, workers): def __init__(self, config):
self.config = config self.config = config
self.workers = workers
def getDescriptor(self, interfaceName): def getDescriptor(self, interfaceName):
""" """
Gets the appropriate descriptor for the given interface name given the Gets the appropriate descriptor for the given interface name given the
context of the current descriptor. This selects the appropriate context of the current descriptor.
implementation for cases like workers.
""" """
return self.config.getDescriptor(interfaceName, self.workers) return self.config.getDescriptor(interfaceName)
class Descriptor(DescriptorProvider): class Descriptor(DescriptorProvider):
""" """
Represents a single descriptor for an interface. See Bindings.conf. Represents a single descriptor for an interface. See Bindings.conf.
""" """
def __init__(self, config, interface, desc): def __init__(self, config, interface, desc):
DescriptorProvider.__init__(self, config, desc.get('workers', False)) DescriptorProvider.__init__(self, config)
self.interface = interface self.interface = interface
# Read the desc, and fill in the relevant defaults. # Read the desc, and fill in the relevant defaults.
ifaceName = self.interface.identifier.name ifaceName = self.interface.identifier.name
if self.interface.isExternal() or self.interface.isCallback(): if self.interface.isExternal() or self.interface.isCallback():
if self.workers:
nativeTypeDefault = "JSObject"
else:
nativeTypeDefault = "nsIDOM" + ifaceName nativeTypeDefault = "nsIDOM" + ifaceName
else:
if self.workers:
nativeTypeDefault = "workers::" + ifaceName
else: else:
nativeTypeDefault = 'JS<%s>' % ifaceName nativeTypeDefault = 'JS<%s>' % ifaceName
self.nativeType = desc.get('nativeType', nativeTypeDefault) self.nativeType = desc.get('nativeType', nativeTypeDefault)
self.concreteType = desc.get('concreteType', ifaceName) self.concreteType = desc.get('concreteType', ifaceName)
self.needsAbstract = desc.get('needsAbstract', []) self.needsAbstract = desc.get('needsAbstract', [])
self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
self.createGlobal = desc.get('createGlobal', False) self.createGlobal = desc.get('createGlobal', False)
# Do something sane for JSObject
if self.nativeType == "JSObject":
headerDefault = "jsapi.h"
else:
headerDefault = self.nativeType
headerDefault = headerDefault.replace("::", "/") + ".h"
self.headerFile = desc.get('headerFile', headerDefault)
if self.interface.isCallback() or self.interface.isExternal(): if self.interface.isCallback() or self.interface.isExternal():
if 'castable' in desc: if 'castable' in desc:
raise TypeError("%s is external or callback but has a castable " raise TypeError("%s is external or callback but has a castable "
@ -182,11 +150,8 @@ class Descriptor(DescriptorProvider):
else: else:
self.castable = desc.get('castable', True) self.castable = desc.get('castable', True)
self.notflattened = desc.get('notflattened', False)
self.register = desc.get('register', True) 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 # If we're concrete, we need to crawl our ancestor interfaces and mark
# them as having a concrete descendant. # them as having a concrete descendant.
self.concrete = desc.get('concrete', not self.interface.isExternal()) self.concrete = desc.get('concrete', not self.interface.isExternal())
@ -246,23 +211,7 @@ class Descriptor(DescriptorProvider):
iface.setUserData('hasProxyDescendant', True) iface.setUserData('hasProxyDescendant', True)
iface = iface.parent iface = iface.parent
if self.interface.isExternal() and 'prefable' in desc: self.name = interface.identifier.name
raise TypeError("%s is external but has a prefable setting" %
self.interface.identifier.name)
self.prefable = desc.get('prefable', False)
self.nativeIsISupports = not self.workers
self.customTrace = desc.get('customTrace', self.workers) or 'trace'
self.customFinalize = desc.get('customFinalize', self.workers)
self.wrapperCache = self.workers or desc.get('wrapperCache', True)
if not self.wrapperCache and self.prefable:
raise TypeError("Descriptor for %s is prefable but not wrappercached" %
self.interface.identifier.name)
def make_name(name):
return name + "_workers" if self.workers else name
self.name = make_name(interface.identifier.name)
# self.extendedAttributes is a dict of dicts, keyed on # self.extendedAttributes is a dict of dicts, keyed on
# all/getterOnly/setterOnly and then on member name. Values are an # all/getterOnly/setterOnly and then on member name. Values are an
@ -289,16 +238,11 @@ class Descriptor(DescriptorProvider):
else: else:
add('all', [config], attribute) add('all', [config], attribute)
for attribute in ['implicitJSContext', 'resultNotAddRefed']:
addExtendedAttribute(attribute, desc.get(attribute, {}))
self.binaryNames = desc.get('binaryNames', {})
# Build the prototype chain. # Build the prototype chain.
self.prototypeChain = [] self.prototypeChain = []
parent = interface parent = interface
while parent: while parent:
self.prototypeChain.insert(0, make_name(parent.identifier.name)) self.prototypeChain.insert(0, parent.identifier.name)
parent = parent.parent parent = parent.parent
config.maxProtoChainLength = max(config.maxProtoChainLength, config.maxProtoChainLength = max(config.maxProtoChainLength,
len(self.prototypeChain)) len(self.prototypeChain))
@ -314,19 +258,13 @@ class Descriptor(DescriptorProvider):
return self.interface.hasInterfaceObject() or self.interface.hasInterfacePrototypeObject() return self.interface.hasInterfaceObject() or self.interface.hasInterfacePrototypeObject()
def getExtendedAttributes(self, member, getter=False, setter=False): def getExtendedAttributes(self, member, getter=False, setter=False):
def ensureValidThrowsExtendedAttribute(attr):
assert(attr is None or attr is True or len(attr) == 1)
if (attr is not None and attr is not True and
'Workers' not in attr and 'MainThread' not in attr):
raise TypeError("Unknown value for 'Throws': " + attr[0])
def maybeAppendInfallibleToAttrs(attrs, throws): def maybeAppendInfallibleToAttrs(attrs, throws):
ensureValidThrowsExtendedAttribute(throws) if throws is None:
if (throws is None or
(throws is not True and
('Workers' not in throws or not self.workers) and
('MainThread' not in throws or self.workers))):
attrs.append("infallible") attrs.append("infallible")
elif throws is True:
pass
else:
raise TypeError("Unknown value for 'Throws'")
name = member.identifier.name name = member.identifier.name
if member.isMethod(): if member.isMethod():