diff options
Diffstat (limited to 'src/components/script/dom/bindings/codegen')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 3 | ||||
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 233 |
2 files changed, 56 insertions, 180 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index 3e6d8dbe88f..a40dfdf1fe6 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -33,6 +33,7 @@ DOMInterfaces = { 'createComment', 'createDocumentFragment', 'createElement', + 'createElementNS', 'createProcessingInstruction', 'createTextNode', 'embeds', @@ -43,6 +44,7 @@ DOMInterfaces = { 'images', 'importNode', 'links', + 'location', 'plugins', 'scripts', 'title', @@ -94,6 +96,7 @@ DOMInterfaces = { 'contains', 'insertBefore', 'isEqualNode', + 'namespaceURI', 'nodeName', 'nodeValue', 'normalize', diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index ded87534683..d319ebe909e 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1089,18 +1089,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode, return (setValue("(%s).to_jsval(cx)" % result), True) if type.isEnum(): - if type.nullable(): - raise TypeError("We don't support nullable enumerated return types " - "yet") - return ("""assert!((%(result)s as uint) < %(strings)s.len()); -let %(resultStr)s: *JSString = JS_NewStringCopyN(cx, &%(strings)s[%(result)s as u32].value[0] as *i8, %(strings)s[%(result)s as u32].length as libc::size_t); -if %(resultStr)s.is_null() { - return 0; -} -""" % { "result" : result, - "resultStr" : result + "_str", - "strings" : type.inner.identifier.name + "Values::strings" } + - setValue("StringValue(&*(%s_str))" % result), False) + return (setValue("(%s).to_jsval(cx)" % result), True) if type.isCallback(): assert not type.isInterface() @@ -1196,9 +1185,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): result = CGWrapper(result, pre="Option<", post=">") return result if returnType.isEnum(): + result = CGGeneric(returnType.unroll().inner.identifier.name) if returnType.nullable(): - raise TypeError("We don't support nullable enum return values") - return CGGeneric(returnType.inner.identifier.name) + result = CGWrapper(result, pre="Option<", post=">") + return result if returnType.isGeckoInterface(): descriptor = descriptorProvider.getDescriptor( returnType.unroll().inner.identifier.name) @@ -1250,23 +1240,13 @@ class PropertyDefiner: if self.hasNonChromeOnly(): return "s" + self.name return "ptr::null()" - def usedForXrays(self, chrome): - # 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. - # Otherwise (we have chromeonly attributes) we need Xrays for the chrome - # methods/attributes/constants. - return ((self.name is "Methods" or self.name is "Attributes" or - self.name is "Constants") and - chrome == self.hasChromeOnly()) def __str__(self): # We only need to generate id arrays for things that will end # up used via ResolveProperty or EnumerateProperties. - str = self.generateArray(self.regular, self.variableName(False), - self.usedForXrays(False)) + str = self.generateArray(self.regular, self.variableName(False)) if self.hasChromeOnly(): - str += self.generateArray(self.chrome, self.variableName(True), - self.usedForXrays(True)) + str += self.generateArray(self.chrome, self.variableName(True)) return str @staticmethod @@ -1280,7 +1260,7 @@ class PropertyDefiner: return prefName[0] def generatePrefableArray(self, array, name, specTemplate, specTerminator, - specType, getPref, getDataTuple, doIdArrays): + specType, getPref, getDataTuple): """ This method generates our various arrays. @@ -1313,8 +1293,6 @@ class PropertyDefiner: # at the very front of the list. specs = [] prefableSpecs = [] - if doIdArrays: - prefableIds = [] prefableTemplate = ' { true, &%s[%d] }' prefCacheTemplate = '&%s[%d].enabled' @@ -1345,16 +1323,9 @@ class PropertyDefiner: specs.append(specTerminator) prefableSpecs.append(" { false, NULL }"); - arrays = (("static %s: [%s, ..%i] = [\n" + - ',\n'.join(specs) + "\n" + - "];\n\n") % (name, specType, len(specs))) - #+ - #"static Prefable<%s> %s[] = [\n" + - #',\n'.join(prefableSpecs) + "\n" + - #"];\n\n") - if doIdArrays: - arrays += ("static %s_ids: [jsid, ..%i] = [" % (name, len(specs))) + ", ".join(["JSID_VOID"] * len(specs)) + "];\n\n" - return arrays + return (("static %s: [%s, ..%i] = [\n" + + ",\n".join(specs) + "\n" + + "];\n\n") % (name, specType, len(specs))) # The length of a method is the maximum of the lengths of the # argument lists of all its overloads. @@ -1417,7 +1388,7 @@ class MethodDefiner(PropertyDefiner): # non-static methods go on the interface prototype object assert not self.hasChromeOnly() and not self.hasNonChromeOnly() - def generateArray(self, array, name, doIdArrays): + def generateArray(self, array, name): if len(array) == 0: return "" @@ -1443,7 +1414,7 @@ class MethodDefiner(PropertyDefiner): ' JSFunctionSpec {name: &%s_name as *u8 as *libc::c_char, call: JSNativeWrapper {op: Some(%s), info: %s}, nargs: %s, flags: %s as u16, selfHostedName: 0 as *libc::c_char }', ' JSFunctionSpec {name: 0 as *libc::c_char, call: JSNativeWrapper {op: None, info: 0 as *JSJitInfo}, nargs: 0, flags: 0, selfHostedName: 0 as *libc::c_char }', 'JSFunctionSpec', - pref, specData, doIdArrays) + pref, specData) class AttrDefiner(PropertyDefiner): def __init__(self, descriptor, name): @@ -1452,7 +1423,7 @@ class AttrDefiner(PropertyDefiner): self.chrome = [m for m in descriptor.interface.members if m.isAttr()] self.regular = [m for m in self.chrome if not isChromeOnly(m)] - def generateArray(self, array, name, doIdArrays): + def generateArray(self, array, name): if len(array) == 0: return "" @@ -1491,7 +1462,7 @@ class AttrDefiner(PropertyDefiner): ' JSPropertySpec { name: &%s_name as *u8 as *libc::c_char, tinyid: 0, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }', ' JSPropertySpec { name: 0 as *libc::c_char, tinyid: 0, flags: 0, getter: JSPropertyOpWrapper {op: None, info: 0 as *JSJitInfo}, setter: JSStrictPropertyOpWrapper {op: None, info: 0 as *JSJitInfo} }', 'JSPropertySpec', - PropertyDefiner.getControllingPref, specData, doIdArrays) + PropertyDefiner.getControllingPref, specData) class ConstDefiner(PropertyDefiner): """ @@ -1503,7 +1474,7 @@ class ConstDefiner(PropertyDefiner): self.chrome = [m for m in descriptor.interface.members if m.isConst()] self.regular = [m for m in self.chrome if not isChromeOnly(m)] - def generateArray(self, array, name, doIdArrays): + def generateArray(self, array, name): if len(array) == 0: return "" @@ -1523,33 +1494,12 @@ class ConstDefiner(PropertyDefiner): ' ConstantSpec { name: &%s_name as *u8 as *libc::c_char, value: %s }', ' ConstantSpec { name: 0 as *libc::c_char, value: VoidVal }', 'ConstantSpec', - PropertyDefiner.getControllingPref, specData, doIdArrays) - -class CGNativePropertyHooks(CGThing): - """ - Generate a NativePropertyHooks for a given descriptor - """ - def __init__(self, descriptor): - CGThing.__init__(self) - self.descriptor = descriptor - - def define(self): - if self.descriptor.concrete and self.descriptor.proxy: - resolveOwnProperty = "ResolveOwnProperty" - enumerateOwnProperties = "EnumerateOwnProperties" - else: - enumerateOwnProperties = resolveOwnProperty = "0 as *u8" - parent = self.descriptor.interface.parent - parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::NativeHooks" - if parent else '0 as *NativePropertyHooks') - return """ -static NativeHooks: NativePropertyHooks = NativePropertyHooks { resolve_own_property: /*%s*/ 0 as *u8, resolve_property: ResolveProperty, enumerate_own_properties: /*%s*/ 0 as *u8, enumerate_properties: /*EnumerateProperties*/ 0 as *u8, proto_hooks: /*%s*/ 0 as *NativePropertyHooks }; -""" % (resolveOwnProperty, enumerateOwnProperties, parentHooks) + PropertyDefiner.getControllingPref, specData) # We'll want to insert the indent at the beginnings of lines, but we # don't want to indent empty lines. So only indent lines that have a # non-newline character on them. -lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE) +lineStartDetector = re.compile("^(?=[^\n])", re.MULTILINE) class CGIndenter(CGThing): """ A class that takes another CGThing and generates code that indents that @@ -1656,8 +1606,7 @@ def DOMClass(descriptor): protoList.extend(['PrototypeList::id::IDCount'] * (descriptor.config.maxProtoChainLength - len(protoList))) prototypeChainString = ', '.join(protoList) return """DOMClass { - interface_chain: [ %s ], - native_hooks: &NativeHooks as *NativePropertyHooks + interface_chain: [ %s ] }""" % prototypeChainString class CGDOMJSClass(CGThing): @@ -2023,7 +1972,7 @@ def CreateBindingJSObject(descriptor, parent=None): assert not descriptor.createGlobal handler = """ let js_info = aScope.get().page().js_info(); - let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); + let handler = js_info.get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); """ % descriptor.name create += handler + """ let obj = NewProxyObject(aCx, *handler, &PrivateValue(squirrel_away_unique(aObject) as *libc::c_void), @@ -2336,14 +2285,9 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): """ % (FINALIZE_HOOK_NAME, ('Some(%s)' % TRACE_HOOK_NAME), self.descriptor.name) - else: - body += """ js_info.dom_static.attribute_ids.insert(PrototypeList::id::%s as uint, - vec::cast_to_mut(vec::from_slice(sAttributes_ids))); -""" % self.descriptor.name - body = "" #XXXjdm xray stuff isn't necessary yet - return (body + """ let cx = js_info.js_context.borrow().ptr; - let receiver = js_info.js_compartment.borrow().global_obj; + return (body + """ let cx = js_info.js_context.deref().ptr; + let receiver = js_info.js_compartment.global_obj; let global: *JSObject = JS_GetGlobalForObject(cx, receiver); return %s(cx, global, receiver).is_not_null();""" % (getter)) @@ -2908,20 +2852,37 @@ def getEnumValueName(value): class CGEnum(CGThing): def __init__(self, enum): CGThing.__init__(self) - self.enum = enum + inner = """ +use dom::bindings::conversions::ToJSValConvertible; +use js::jsapi::JSContext; +use js::jsval::JSVal; - def define(self): - return """ - #[repr(uint)] - pub enum valuelist { - %s +#[repr(uint)] +pub enum valuelist { + %s +} + +pub static strings: &'static [&'static str] = &[ + %s, +]; + +impl ToJSValConvertible for valuelist { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + strings[*self as uint].to_owned().to_jsval(cx) } +} +""" % (",\n ".join(map(getEnumValueName, enum.values())), + ",\n ".join(['&"%s"' % val for val in enum.values()])) + + self.cgRoot = CGList([ + CGNamespace.build([enum.identifier.name + "Values"], + CGIndenter(CGGeneric(inner)), public=True), + CGGeneric("pub type %s = self::%sValues::valuelist;\n" % + (enum.identifier.name, enum.identifier.name)), + ]) - pub static strings: &'static [EnumEntry] = &[ - %s, - ]; -""" % (",\n ".join(map(getEnumValueName, self.enum.values())), - ",\n ".join(['EnumEntry {value: &"' + val + '", length: ' + str(len(val)) + '}' for val in self.enum.values()])) + def define(self): + return self.cgRoot.define() def convertConstIDLValueToRust(value): @@ -3685,72 +3646,6 @@ class CGClass(CGThing): result += "}" return result - -class CGXrayHelper(CGAbstractExternMethod): - def __init__(self, descriptor, name, args, properties): - CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args) - self.properties = properties - - def definition_body(self): - varNames = self.properties.variableNames(True) - - setup = ("let window = global_object_for_js_object(wrapper);\n" - "let js_info = window.get().page().js_info();\n") - - methods = self.properties.methods - if methods.hasNonChromeOnly() or methods.hasChromeOnly(): - methodArgs = "Some(zip_copies(%(methods)s, *method_ids))" % varNames - setup += "let method_ids = js_info.get().get_ref().dom_static.method_ids.get(&(PrototypeList::id::ClientRect as uint));\n" - else: - methodArgs = "None" - methodArgs = CGGeneric(methodArgs) - - attrs = self.properties.attrs - if attrs.hasNonChromeOnly() or attrs.hasChromeOnly(): - attrArgs = "Some(zip_copies(%(attrs)s, *attr_ids))" % varNames - setup += "let attr_ids = js_info.get().get_ref().dom_static.attribute_ids.get(&(PrototypeList::id::ClientRect as uint));\n" - else: - attrArgs = "None" - attrArgs = CGGeneric(attrArgs) - - consts = self.properties.consts - if consts.hasNonChromeOnly() or consts.hasChromeOnly(): - constArgs = "Some(zip_copies(%(consts)s, *const_ids))" % varNames - setup += "let const_ids = js_info.get().get_ref().dom_static.constant_ids.get(&(PrototypeList::id::ClientRect as uint));\n" - else: - constArgs = "None" - constArgs = CGGeneric(constArgs) - - prefixArgs = CGGeneric(self.getPrefixArgs()) - - return CGIndenter( - CGWrapper(CGList([prefixArgs, methodArgs, attrArgs, constArgs], ", "), - pre=(setup + "return Xray%s(" % self.name), - post=");", - reindent=True)).define() - -class CGResolveProperty(CGXrayHelper): - def __init__(self, descriptor, properties): - args = [Argument('*JSContext', 'cx'), Argument('*JSObject', 'wrapper'), - Argument('jsid', 'id'), Argument('bool', 'set'), - Argument('*mut JSPropertyDescriptor', 'desc')] - CGXrayHelper.__init__(self, descriptor, "ResolveProperty", args, - properties) - - def getPrefixArgs(self): - return "cx, wrapper, id, desc" - - -class CGEnumerateProperties(CGXrayHelper): - def __init__(self, descriptor, properties): - args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'), - Argument('JS::AutoIdVector&', 'props')] - CGXrayHelper.__init__(self, descriptor, "EnumerateProperties", args, - properties) - - def getPrefixArgs(self): - return "props" - class CGProxySpecialOperation(CGPerSignatureCall): """ Base class for classes for calling an indexed or named special operation @@ -4294,25 +4189,12 @@ class CGDescriptor(CGThing): CGConstant(m for m in descriptor.interface.members if m.isConst()), public=True)) - # Set up our Xray callbacks as needed. - if descriptor.interface.hasInterfacePrototypeObject(): - if descriptor.concrete and descriptor.proxy: - #cgThings.append(CGResolveOwnProperty(descriptor)) - #cgThings.append(CGEnumerateOwnProperties(descriptor)) - pass - cgThings.append(CGResolveProperty(descriptor, properties)) - #cgThings.append(CGEnumerateProperties(descriptor, properties)) - if descriptor.interface.hasInterfaceObject(): cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) if (descriptor.interface.getExtendedAttribute("PrefControlled") is not None): #cgThings.append(CGPrefEnabled(descriptor)) pass - if descriptor.interface.hasInterfacePrototypeObject(): - cgThings.append(CGNativePropertyHooks(descriptor)) - pass - if descriptor.concrete: if descriptor.proxy: #cgThings.append(CGProxyIsProxy(descriptor)) @@ -4656,15 +4538,7 @@ class CGBindingRoot(CGThing): isCallback=True) # Do codegen for all the enums - def makeEnum(e): - return CGNamespace.build([e.identifier.name + "Values"], - CGList([CGGeneric(" use dom::bindings::utils::EnumEntry;"), - CGEnum(e)]), public=True) - def makeEnumTypedef(e): - return CGGeneric("pub type %s = self::%sValues::valuelist;\n" % - (e.identifier.name, e.identifier.name)) - cgthings = [ fun(e) for e in config.getEnums(webIDLFile) - for fun in [makeEnum, makeEnumTypedef] ] + cgthings = [CGEnum(e) for e in config.getEnums(webIDLFile)] # Do codegen for all the dictionaries. We have to be a bit careful # here, because we have to generate these in order from least derived @@ -4746,13 +4620,12 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{GetPropertyOnPrototype, GetProtoOrIfaceArray}', 'dom::bindings::utils::{HasPropertyOnPrototype, IntVal}', 'dom::bindings::utils::{jsid_to_str}', - 'dom::bindings::utils::{NativePropertyHooks}', 'dom::bindings::utils::global_object_for_js_object', 'dom::bindings::utils::{Reflectable}', 'dom::bindings::utils::{squirrel_away_unique}', 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', 'dom::bindings::utils::{unwrap_object, VoidVal, with_gc_disabled}', - 'dom::bindings::utils::{with_gc_enabled, XrayResolveProperty}', + 'dom::bindings::utils::{with_gc_enabled}', 'dom::bindings::trace::Traceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}', @@ -4774,7 +4647,7 @@ class CGBindingRoot(CGThing): 'std::cmp', 'std::libc', 'std::ptr', - 'std::vec', + 'std::slice', 'std::str', 'std::num', ]) @@ -5336,7 +5209,7 @@ class CallbackMember(CGNativeMember): if self.argCount > 0: replacements["argCount"] = self.argCountStr replacements["argvDecl"] = string.Template( - "let mut argv = vec::from_elem(${argCount}, UndefinedValue());\n" + "let mut argv = slice::from_elem(${argCount}, UndefinedValue());\n" ).substitute(replacements) else: # Avoid weird 0-sized arrays |