Remove support for workers-specific codegen.

This commit is contained in:
Ms2ger 2014-02-25 14:28:27 +01:00
parent c96c7bab12
commit 3c7f9832f0
2 changed files with 96 additions and 196 deletions

View file

@ -132,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():
@ -366,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")))
@ -393,7 +391,6 @@ 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
class FakeInterface: class FakeInterface:
@ -645,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
@ -654,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(
@ -918,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,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, "
@ -1195,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}"
@ -1773,11 +1764,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
@ -1921,7 +1911,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,
@ -2053,13 +2043,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"
@ -2201,11 +2187,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", nativeHooks) native_hooks: &NativeHooks as *NativePropertyHooks
}""" % prototypeChainString
class CGDOMJSClass(CGThing): class CGDOMJSClass(CGThing):
""" """
@ -2627,9 +2613,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());
@ -2736,9 +2719,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.
@ -2826,10 +2807,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
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 = "xpc::AccessCheck::isChrome(js::GetObjectCompartment(aGlobal))"
accessCheck = "mozilla::dom::workers::GetWorkerPrivateFromContext(aCx)->IsChromeWorker()"
else:
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)
chrome = CGWrapper(chrome, pre="\n\n") chrome = CGWrapper(chrome, pre="\n\n")
@ -2913,14 +2891,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):
@ -3156,10 +3130,7 @@ class CGPerSignatureCall(CGThing):
if isCreator: if isCreator:
# We better be returning addrefed things! # We better be returning addrefed things!
#assert(isResultAlreadyAddRefed(self.descriptor, #assert(isResultAlreadyAddRefed(self.descriptor,
# self.extendedAttributes) or # self.extendedAttributes))
# Workers use raw pointers for new-object return
# values or something
# self.descriptor.workers)
pass pass
resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp', resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp',
@ -3283,8 +3254,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
@ -4822,15 +4792,10 @@ class CGAbstractClassHook(CGAbstractExternMethod):
assert(False) assert(False)
def finalizeHook(descriptor, hookName, context): def finalizeHook(descriptor, hookName, context):
if descriptor.workers: release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj));
#release = "self->Release();"
pass
else:
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):
@ -4866,11 +4831,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.
@ -4878,11 +4838,9 @@ 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"]
name = self._ctor.identifier.name name = self._ctor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name)) nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
callGenerator = CGMethodCall(preArgs, nativeName, True, callGenerator = CGMethodCall(["&global"], nativeName, True,
self.descriptor, self._ctor) self.descriptor, self._ctor)
return preamble + callGenerator.define(); return preamble + callGenerator.define();
@ -4966,10 +4924,8 @@ class CGDescriptor(CGThing):
else: else:
cgThings.append(CGGetConstructorObjectMethod(descriptor)) cgThings.append(CGGetConstructorObjectMethod(descriptor))
# 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))
@ -4980,8 +4936,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
@ -5072,7 +5026,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
@ -5080,23 +5033,14 @@ 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 self.memberInfo = [
# if we don't have a relevant descriptor when self.workers is True. (member,
# If that happens, just mark ourselves as not being getJSToNativeConversionTemplate(member.type,
# generatable and move on. descriptorProvider,
try: isMember=True,
self.memberInfo = [ isOptional=(not member.defaultValue),
(member, defaultValue=member.defaultValue))
getJSToNativeConversionTemplate(member.type, for member in dictionary.members ]
descriptorProvider,
isMember=True,
isOptional=(not member.defaultValue),
defaultValue=member.defaultValue))
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:
@ -5115,7 +5059,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"
@ -5159,41 +5102,39 @@ 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" "\n"
"\n" "impl ${selfName} {\n"
"impl ${selfName} {\n" " pub fn new() -> ${selfName} {\n"
" pub fn new() -> ${selfName} {\n" " ${selfName} {\n" +
" ${selfName} {\n" + ((" parent: %s::%s::new(),\n" % (self.makeModuleName(d.parent),
((" parent: %s::%s::new(),\n" % (self.makeModuleName(d.parent), self.makeClassName(d.parent))) if d.parent else "") +
self.makeClassName(d.parent))) if d.parent else "") + "\n".join(" %s: %s," % (self.makeMemberName(m[0].identifier.name), defaultValue(self.getMemberType(m))) for m in self.memberInfo) + "\n"
"\n".join(" %s: %s," % (self.makeMemberName(m[0].identifier.name), defaultValue(self.getMemberType(m))) for m in self.memberInfo) + "\n" " }\n"
" }\n" " }\n"
" }\n" "\n"
"\n" " pub fn InitIds(&mut self, cx: *JSContext) -> bool {\n"
" pub fn InitIds(&mut self, cx: *JSContext) -> bool {\n" " //MOZ_ASSERT(!initedIds);\n"
" //MOZ_ASSERT(!initedIds);\n" " /*${idInit}\n"
" /*${idInit}\n" " initedIds = true;*/ //XXXjdm\n"
" initedIds = true;*/ //XXXjdm\n" " return true;\n"
" return true;\n" " }\n"
" }\n" "\n"
"\n" if not self.workers else "") +
" 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"
" }\n" if not self.workers else "") +
"${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"
@ -5205,16 +5146,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):
@ -5251,8 +5190,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)
@ -5335,7 +5273,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):
@ -5353,8 +5290,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)
@ -5392,22 +5328,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")
@ -6428,7 +6360,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)
@ -6476,7 +6407,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,38 +112,30 @@ 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 = "nsIDOM" + ifaceName
nativeTypeDefault = "JSObject"
else:
nativeTypeDefault = "nsIDOM" + ifaceName
else: else:
if self.workers: nativeTypeDefault = 'JS<%s>' % ifaceName
nativeTypeDefault = "workers::" + ifaceName
else:
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)
@ -234,9 +211,7 @@ class Descriptor(DescriptorProvider):
iface.setUserData('hasProxyDescendant', True) iface.setUserData('hasProxyDescendant', True)
iface = iface.parent iface = iface.parent
def make_name(name): self.name = interface.identifier.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
@ -272,7 +247,7 @@ class Descriptor(DescriptorProvider):
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))
@ -288,19 +263,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():