From a9ffff92159645dc3e85f7c1d5bed9e3ae20eaa7 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 16 Apr 2014 21:37:58 +0200 Subject: [PATCH 1/9] Rewrite the interface unwrapping to return an expression. --- .../script/dom/bindings/codegen/CodegenRust.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index e8b723d4d98..0a77645874f 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -553,13 +553,13 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, if type.nullable(): templateBody += ( "} else if (${val}).is_null_or_undefined() {\n" - " ${declName} = None;\n") + " None\n") templateBody += ( "} else {\n" + CGIndenter(onFailureNotAnObject(failureCode)).define() + "}") if type.nullable(): - templateBody = handleDefaultNull(templateBody, "${declName} = None;") + templateBody = handleDefaultNull(templateBody, "None") else: assert(defaultValue is None) @@ -609,11 +609,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, if descriptor.interface.isCallback(): name = descriptor.nativeType declType = CGGeneric("Option<%s>" % name); - conversion = ("${declName} = Some(%s::new((${val}).to_object()));" % name) + conversion = ("Some(%s::new((${val}).to_object()))" % name) template = wrapObjectTemplate(conversion, isDefinitelyObject, type, failureCode) - return (template, declType, None, isOptional, None) + return ("${declName} = " + template + ";", declType, None, isOptional, None) templateBody = "" if descriptor.interface.isConsequential(): @@ -621,19 +621,17 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, "argument" % descriptor.interface.identifier.name) - templateBody = "${declName} = " if failureCode is not None: - templateBody += str(CastableObjectUnwrapper( + templateBody = str(CastableObjectUnwrapper( descriptor, "(${val}).to_object()", failureCode, isOptional or type.nullable())) else: - templateBody += str(FailureFatalCastableObjectUnwrapper( + templateBody = str(FailureFatalCastableObjectUnwrapper( descriptor, "(${val}).to_object()", isOptional or type.nullable())) - templateBody += ";\n" templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject, type, failureCode) @@ -642,7 +640,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, if type.nullable() or isOptional: declType = CGWrapper(declType, pre="Option<", post=">") - return (templateBody, declType, None, isOptional, "None" if isOptional else None) + return ("${declName} = " + templateBody + ";", declType, None, isOptional, "None" if isOptional else None) if type.isSpiderMonkeyInterface(): raise TypeError("Can't handle SpiderMonkey interface arguments yet") From 4905b226737062356bac280563b0760114fef721 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 17 Apr 2014 12:06:23 +0200 Subject: [PATCH 2/9] Rewrite the union unwrapping to return an expression. --- .../script/dom/bindings/codegen/CodegenRust.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 0a77645874f..9b45d130055 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -584,21 +584,21 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, declType = CGWrapper(declType, pre="Option<", post=" >") value = CGWrapper(value, pre="Some(", post=")") - templateBody = CGGeneric("${declName} = match %s::from_value(cx, ${val}) {\n" + templateBody = CGGeneric("match %s::from_value(cx, ${val}) {\n" " Err(()) => { %s },\n" " Ok(value) => %s,\n" - "};" % (type.name, exceptionCode, value.define())) + "}" % (type.name, exceptionCode, value.define())) if type.nullable(): templateBody = CGIfElseWrapper( "(${val}).is_null_or_undefined()", - CGGeneric("${declName} = None;"), + CGGeneric("None"), templateBody) templateBody = handleDefaultNull(templateBody.define(), - "${declName} = None;") + "None") - return (templateBody, declType, None, isOptional, "None" if isOptional else None) + return ("${declName} = " + templateBody + ";", declType, None, isOptional, "None" if isOptional else None) if type.isGeckoInterface(): assert not isEnforceRange and not isClamp From 1027801b04b8fa2670642021aa0a2632b8d6c15b Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 17 Apr 2014 12:15:28 +0200 Subject: [PATCH 3/9] Rewrite the DOMString unwrapping to return an expression. --- .../script/dom/bindings/codegen/CodegenRust.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 9b45d130055..7262c6d7a77 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -665,17 +665,17 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, strval = "Some(%s)" % strval conversionCode = ( - "${declName} = match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" + "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" " Ok(strval) => %s,\n" " Err(_) => { %s },\n" - "};" % (nullBehavior, strval, exceptionCode)) + "}" % (nullBehavior, strval, exceptionCode)) if defaultValue is None: return conversionCode if isinstance(defaultValue, IDLNullValue): assert(type.nullable()) - return handleDefault(conversionCode, "${declName} = None;") + return handleDefault(conversionCode, "None") value = "str::from_utf8(data).unwrap().to_owned()" if type.nullable(): @@ -683,7 +683,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, default = ( "static data: [u8, ..%s] = [ %s ];\n" - "${declName} = %s;" % + "%s" % (len(defaultValue.value) + 1, ", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]), value)) @@ -700,8 +700,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, initialValue = "None" return ( - "%s\n" % - (getConversionCode(isOptional)), + "${declName} = %s;" % getConversionCode(isOptional), CGGeneric(declType), None, #CGGeneric("FakeDependentString"), False, initialValue) From 643ea874d101700d59153d9bd3f2033135754d08 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 17 Apr 2014 12:19:47 +0200 Subject: [PATCH 4/9] Rewrite the any unwrapping to return an expression. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 7262c6d7a77..62f2138147c 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -767,11 +767,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, declType = CGWrapper(declType, pre="Option<", post=">") value = CGWrapper(value, pre="Some(", post=")") - templateBody = "${declName} = %s;" % value.define() - templateBody = handleDefaultNull(templateBody, - "${declName} = NullValue();") - - return (templateBody, declType, None, isOptional, "None" if isOptional else None) + templateBody = handleDefaultNull(value.define(), "NullValue()") + return ("${declName} = " + templateBody + ";", declType, None, isOptional, "None" if isOptional else None) if type.isObject(): raise TypeError("Can't handle object arguments yet") From 2b9d1d6bc150c1c085298fc4df5c558325c3e1c5 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 17 Apr 2014 15:41:38 +0200 Subject: [PATCH 5/9] Rewrite the primitive unwrapping to return an expression. --- .../script/dom/bindings/codegen/CodegenRust.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 62f2138147c..e1beebc3f8a 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -826,10 +826,10 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, #XXXjdm support conversionBehavior here template = ( - "${declName} = match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" + "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" " Ok(v) => %s,\n" " Err(_) => { %s }\n" - "};" % (value, exceptionCode)) + "}" % (value, exceptionCode)) if defaultValue is not None: if isinstance(defaultValue, IDLNullValue): @@ -838,7 +838,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, else: tag = defaultValue.type.tag() if tag in numericTags: - defaultStr = defaultValue.value + defaultStr = str(defaultValue.value) else: assert(tag == IDLType.Tags.bool) defaultStr = toStringBool(defaultValue.value) @@ -848,9 +848,9 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, template = CGIfElseWrapper("${haveValue}", CGGeneric(template), - CGGeneric("${declName} = %s;" % defaultStr)).define() + CGGeneric(defaultStr)).define() - return (template, declType, None, isOptional, "None" if isOptional else None) + return ("${declName} = " + template + ";", declType, None, isOptional, "None" if isOptional else None) def instantiateJSToNativeConversionTemplate(templateTuple, replacements, argcAndIndex=None): From c5bf011d1eed6de6237c83955b92ccc5ffb92434 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 25 Apr 2014 10:55:16 +0200 Subject: [PATCH 6/9] Rewrite the enumeration unwrapping to return an expression. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index e1beebc3f8a..594ddde9e65 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -723,7 +723,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, " Ok(None) => { %(handleInvalidEnumValueCode)s },\n" " Ok(Some(index)) => {\n" " //XXXjdm need some range checks up in here.\n" - " ${declName} = cast::transmute(index);\n" + " cast::transmute(index)\n" " },\n" "}" % { "values" : enum + "Values::strings", "exceptionCode" : exceptionCode, @@ -732,11 +732,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, if defaultValue is not None: assert(defaultValue.type.tag() == IDLType.Tags.domstring) template = handleDefault(template, - ("${declName} = %sValues::%s;" % + ("%sValues::%s" % (enum, getEnumValueName(defaultValue.value)))) - return (template, CGGeneric(enum), None, isOptional, None) + return ("${declName} = " + template + ";", CGGeneric(enum), None, isOptional, None) if type.isCallback(): assert not isEnforceRange and not isClamp From 05d0ba783f45fb3530a6a299d9802dacedee69a0 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 25 Apr 2014 11:30:04 +0200 Subject: [PATCH 7/9] Move responsibility for assigning to ${declName} out of getJSToNativeConversionTemplate. This commit does not make any change to the generated code. --- .../dom/bindings/codegen/CodegenRust.py | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 594ddde9e65..78971532b3a 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -598,7 +598,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, templateBody = handleDefaultNull(templateBody.define(), "None") - return ("${declName} = " + templateBody + ";", declType, None, isOptional, "None" if isOptional else None) + return (templateBody, declType, None, isOptional, "None" if isOptional else None) if type.isGeckoInterface(): assert not isEnforceRange and not isClamp @@ -613,7 +613,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, template = wrapObjectTemplate(conversion, isDefinitelyObject, type, failureCode) - return ("${declName} = " + template + ";", declType, None, isOptional, None) + return (template, declType, None, isOptional, None) templateBody = "" if descriptor.interface.isConsequential(): @@ -640,7 +640,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, if type.nullable() or isOptional: declType = CGWrapper(declType, pre="Option<", post=">") - return ("${declName} = " + templateBody + ";", declType, None, isOptional, "None" if isOptional else None) + return (templateBody, declType, None, isOptional, "None" if isOptional else None) if type.isSpiderMonkeyInterface(): raise TypeError("Can't handle SpiderMonkey interface arguments yet") @@ -700,7 +700,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, initialValue = "None" return ( - "${declName} = %s;" % getConversionCode(isOptional), + getConversionCode(isOptional), CGGeneric(declType), None, #CGGeneric("FakeDependentString"), False, initialValue) @@ -736,7 +736,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, (enum, getEnumValueName(defaultValue.value)))) - return ("${declName} = " + template + ";", CGGeneric(enum), None, isOptional, None) + return (template, CGGeneric(enum), None, isOptional, None) if type.isCallback(): assert not isEnforceRange and not isClamp @@ -768,7 +768,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, value = CGWrapper(value, pre="Some(", post=")") templateBody = handleDefaultNull(value.define(), "NullValue()") - return ("${declName} = " + templateBody + ";", declType, None, isOptional, "None" if isOptional else None) + return (templateBody, declType, None, isOptional, "None" if isOptional else None) if type.isObject(): raise TypeError("Can't handle object arguments yet") @@ -794,10 +794,10 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, else: val = "${val}" - template = ("${declName} = match %s::new(cx, %s) {\n" + template = ("match %s::new(cx, %s) {\n" " Ok(dictionary) => dictionary,\n" " Err(_) => return 0,\n" - "};" % (typeName, val)) + "}" % (typeName, val)) return (template, declType, None, False, None) @@ -850,7 +850,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, CGGeneric(template), CGGeneric(defaultStr)).define() - return ("${declName} = " + template + ";", declType, None, isOptional, "None" if isOptional else None) + return (template, declType, None, isOptional, "None" if isOptional else None) def instantiateJSToNativeConversionTemplate(templateTuple, replacements, argcAndIndex=None): @@ -892,20 +892,22 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements, tmpresult += [CGGeneric(";")] result.append(CGList(tmpresult)) - originalDeclName = replacements["declName"] + conversion = CGGeneric( + string.Template(templateBody).substitute(replacements) + ) + if declType is not None: newDecl = [CGGeneric("let mut "), - CGGeneric(originalDeclName), + CGGeneric(replacements["declName"]), CGGeneric(": "), declType] if initialValue: newDecl.append(CGGeneric(" = " + initialValue)) newDecl.append(CGGeneric(";")) result.append(CGList(newDecl)) - - conversion = CGGeneric( - string.Template(templateBody).substitute(replacements) - ) + conversion = CGWrapper(conversion, + pre="%s = " % replacements["declName"], + post=";") if argcAndIndex is not None: declConstruct = None @@ -2916,8 +2918,8 @@ def getUnionTypeTemplateVars(type, descriptorProvider): "holderName": None, }) jsConversion = CGWrapper(CGGeneric(jsConversion), - pre="let retval;\n", - post="\nOk(Some(retval))") + pre="let retval;\nretval = ", + post=";\nOk(Some(retval))") return { "name": name, @@ -4296,7 +4298,7 @@ class CGDictionary(CGThing): propName = member.identifier.name conversion = CGIndenter( - CGGeneric(string.Template(templateBody).substitute(replacements)), + CGGeneric(string.Template("${declName} = " + templateBody + ";").substitute(replacements)), 8).define() if not member.defaultValue: raise TypeError("We don't support dictionary members without a " From 66c89f27aa8b0505c04f24b1bd9955c4c2726054 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 25 Apr 2014 11:33:18 +0200 Subject: [PATCH 8/9] Remove the 'retval' local variable from union TryConvertTo methods. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 78971532b3a..4df58fb5588 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -2914,12 +2914,9 @@ def getUnionTypeTemplateVars(type, descriptorProvider): jsConversion = string.Template(template).substitute({ "val": "value", "valPtr": None, - "declName": "retval", "holderName": None, }) - jsConversion = CGWrapper(CGGeneric(jsConversion), - pre="let retval;\nretval = ", - post=";\nOk(Some(retval))") + jsConversion = CGWrapper(CGGeneric(jsConversion), pre="Ok(Some(", post="))") return { "name": name, From 1d51e7d227943cc0b05303ac2450f58c0102af18 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 25 Apr 2014 11:51:47 +0200 Subject: [PATCH 9/9] Rewrite dictionary codegen to initialize members directly into the struct. --- .../dom/bindings/codegen/CodegenRust.py | 49 ++++++------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 4df58fb5588..be3d1a9fa23 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -4208,31 +4208,17 @@ class CGDictionary(CGThing): else: initParent = "" - memberInits = [CGIndenter(self.getMemberConversion(m), indentLevel=6).define() - for m in self.memberInfo] + def memberInit(memberInfo): + member, _ = memberInfo + name = self.makeMemberName(member.identifier.name) + conversion = self.getMemberConversion(memberInfo) + return CGGeneric("%s: %s,\n" % (name, conversion.define())) - def defaultValue(ty): - if ty is "bool": - return "false" - elif ty in ["i32", "u32", "i16", "u16"]: - return "0" - elif ty == "DOMString": - return '~""' - elif ty.startswith("Option"): - return "None" - elif ty == "JSVal": - return "UndefinedValue()" - else: - return "/* uh oh: %s */" % ty + memberInits = CGList([memberInit(m) for m in self.memberInfo]) return string.Template( "impl ${selfName} {\n" " pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n" - " let mut result = ${selfName} {\n" - "${initParent}" + - "\n".join(" %s: %s," % (self.makeMemberName(m[0].identifier.name), defaultValue(self.getMemberType(m))) for m in self.memberInfo) + "\n" - " };\n" - "\n" " let object = if val.is_null_or_undefined() {\n" " ptr::null()\n" " } else if val.is_object() {\n" @@ -4241,15 +4227,15 @@ class CGDictionary(CGThing): " //XXXjdm throw properly here\n" " return Err(());\n" " };\n" - " unsafe {\n" - "${initMembers}\n" - " }\n" - " Ok(result)\n" + " Ok(${selfName} {\n" + "${initParent}" + "${initMembers}" + " })\n" " }\n" "}").substitute({ "selfName": self.makeClassName(d), "initParent": CGIndenter(CGGeneric(initParent), indentLevel=6).define(), - "initMembers": "\n\n".join(memberInits), + "initMembers": CGIndenter(memberInits, indentLevel=6).define(), }) @staticmethod @@ -4280,22 +4266,15 @@ class CGDictionary(CGThing): def getMemberConversion(self, memberInfo): (member, (templateBody, declType, holderType, dealWithOptional, initialValue)) = memberInfo - replacements = { "val": "value.unwrap()", - "declName": ("result.%s" % self.makeMemberName(member.identifier.name)), - # We need a holder name for external interfaces, but - # it's scoped down to the conversion so we can just use - # anything we want. - "holderName": "holder"} + replacements = { "val": "value.unwrap()" } # We can't handle having a holderType here assert holderType is None - if dealWithOptional: - replacements["declName"] = "(" + replacements["declName"] + ".Value())" if member.defaultValue: replacements["haveValue"] = "value.is_some()" propName = member.identifier.name conversion = CGIndenter( - CGGeneric(string.Template("${declName} = " + templateBody + ";").substitute(replacements)), + CGGeneric(string.Template(templateBody).substitute(replacements)), 8).define() if not member.defaultValue: raise TypeError("We don't support dictionary members without a " @@ -4307,7 +4286,7 @@ class CGDictionary(CGThing): " Ok(value) => {\n" "%s\n" " },\n" - "}\n") % (propName, conversion) + "}") % (propName, conversion) return CGGeneric(conversion)