From ab1b429aefce97474b6bb40567b653ec6ec70b54 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 16 Apr 2014 14:33:13 +0200 Subject: [PATCH 1/4] Move assignments outside match expressions in getJSToNativeConversionTemplate. This is a first step towards making getJSToNativeConversionTemplate return an expression, which will improve dictionary codegen in particular. --- .../dom/bindings/codegen/CodegenRust.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index cba5bd0b333..320224c3fab 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -104,12 +104,12 @@ class CastableObjectUnwrapper(): def __str__(self): return string.Template( -"""match unwrap_jsmanaged(${source}, ${prototype}, ${depth}) { - Ok(val) => ${target} = ${unwrapped_val}, +"""${target} = match unwrap_jsmanaged(${source}, ${prototype}, ${depth}) { + Ok(val) => ${unwrapped_val}, Err(()) => { ${codeOnFailure} } -} +}; """).substitute(self.substitution) #"""{ @@ -586,10 +586,10 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, declType = CGWrapper(declType, pre="Option<", post=" >") value = CGWrapper(value, pre="Some(", post=")") - templateBody = CGGeneric("match %s::from_value(cx, ${val}) {\n" + templateBody = CGGeneric("${declName} = match %s::from_value(cx, ${val}) {\n" " Err(()) => { %s },\n" - " Ok(value) => ${declName} = %s,\n" - "}" % (type.name, exceptionCode, value.define())) + " Ok(value) => %s,\n" + "};" % (type.name, exceptionCode, value.define())) if type.nullable(): templateBody = CGIfElseWrapper( @@ -668,10 +668,10 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, strval = "Some(%s)" % strval conversionCode = ( - "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" - " Ok(strval) => ${declName} = %s,\n" + "${declName} = 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 @@ -837,10 +837,10 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, #XXXjdm support conversionBehavior here template = ( - "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" - " Ok(v) => ${declName} = %s,\n" + "${declName} = 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): From 82afae123e772c7a4eefa7c0fb3ef9e99eed38ed Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 16 Apr 2014 21:21:19 +0200 Subject: [PATCH 2/4] Move responsability for the assignment out of CastableObjectUnwrapper. This is a second step towards making getJSToNativeConversionTemplate return an expression, which will improve dictionary codegen in particular. This commit does not make any change to the generated code. --- .../dom/bindings/codegen/CodegenRust.py | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 320224c3fab..a0bbc521f5a 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -87,30 +87,28 @@ numericTags = [ class CastableObjectUnwrapper(): """ A class for unwrapping an object named by the "source" argument - based on the passed-in descriptor and storing it in a variable - called by the name in the "target" argument. + based on the passed-in descriptor. Stringifies to a Rust expression of + the appropriate type. codeOnFailure is the code to run if unwrapping fails. """ - def __init__(self, descriptor, source, target, codeOnFailure, isOptional=False): + def __init__(self, descriptor, source, codeOnFailure, isOptional=False): self.substitution = { "type" : descriptor.nativeType, "depth": descriptor.interface.inheritanceDepth(), "prototype": "PrototypeList::id::" + descriptor.name, "protoID" : "PrototypeList::id::" + descriptor.name + " as uint", "source" : source, - "target" : target, "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define(), "unwrapped_val" : "Some(val)" if isOptional else "val"} def __str__(self): return string.Template( -"""${target} = match unwrap_jsmanaged(${source}, ${prototype}, ${depth}) { +"""match unwrap_jsmanaged(${source}, ${prototype}, ${depth}) { Ok(val) => ${unwrapped_val}, Err(()) => { ${codeOnFailure} } -}; -""").substitute(self.substitution) +}""").substitute(self.substitution) #"""{ # nsresult rv = UnwrapObject<${protoID}, ${type}>(cx, ${source}, ${target}); @@ -123,8 +121,8 @@ class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper): """ As CastableObjectUnwrapper, but defaulting to throwing if unwrapping fails """ - def __init__(self, descriptor, source, target, isOptional): - CastableObjectUnwrapper.__init__(self, descriptor, source, target, + def __init__(self, descriptor, source, isOptional): + CastableObjectUnwrapper.__init__(self, descriptor, source, "return 0; //XXXjdm return Throw(cx, rv);", isOptional) @@ -622,19 +620,20 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, raise TypeError("Consequential interface %s being used as an " "argument" % descriptor.interface.identifier.name) + + templateBody = "${declName} = " if failureCode is not None: templateBody += str(CastableObjectUnwrapper( descriptor, "(${val}).to_object()", - "${declName}", failureCode, isOptional or type.nullable())) else: templateBody += str(FailureFatalCastableObjectUnwrapper( descriptor, "(${val}).to_object()", - "${declName}", isOptional or type.nullable())) + templateBody += ";\n" templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject, type, failureCode) @@ -2495,9 +2494,9 @@ class CGAbstractBindingMethod(CGAbstractExternMethod): # know that we're the real deal. So fake a descriptor here for # consumption by FailureFatalCastableObjectUnwrapper. unwrapThis = CGIndenter(CGGeneric( - str(CastableObjectUnwrapper( + "this = " + str(CastableObjectUnwrapper( FakeCastableDescriptor(self.descriptor), - "obj", "this", self.unwrapFailureCode)))) + "obj", self.unwrapFailureCode)) + ";\n")) return CGList([ self.getThis(), unwrapThis, self.generate_code() ], "\n").define() From a6a06e0ffc1e84af1ec5d105c439fc23a59eec95 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 24 Apr 2014 23:52:25 +0200 Subject: [PATCH 3/4] Inline CGAbstractBindingMethod.getThis. There's no good reason to keep this separate; it's only called once, and inlining the function makes the code a little clearer. This commit does not make any change to the generated code. --- .../script/dom/bindings/codegen/CodegenRust.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index a0bbc521f5a..769674a0b3a 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -2493,21 +2493,18 @@ class CGAbstractBindingMethod(CGAbstractExternMethod): # we're someone's consequential interface. But for this-unwrapping, we # know that we're the real deal. So fake a descriptor here for # consumption by FailureFatalCastableObjectUnwrapper. - unwrapThis = CGIndenter(CGGeneric( - "this = " + str(CastableObjectUnwrapper( + unwrapThis = str(CastableObjectUnwrapper( FakeCastableDescriptor(self.descriptor), - "obj", self.unwrapFailureCode)) + ";\n")) - return CGList([ self.getThis(), unwrapThis, - self.generate_code() ], "\n").define() - - def getThis(self): - return CGIndenter( + "obj", self.unwrapFailureCode)) + unwrapThis = CGIndenter( CGGeneric("let obj: *JSObject = JS_THIS_OBJECT(cx, vp as *mut JSVal);\n" "if obj.is_null() {\n" " return false as JSBool;\n" "}\n" "\n" - "let this: JS<%s>;" % self.descriptor.concreteType)) + "let this: JS<%s>;\n" + "this = %s;\n" % (self.descriptor.concreteType, unwrapThis))) + return CGList([ unwrapThis, self.generate_code() ], "\n").define() def generate_code(self): assert(False) # Override me From de8f123b1d695e6c378f221bcaec3408d553ea7e Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 24 Apr 2014 23:57:25 +0200 Subject: [PATCH 4/4] Assign to 'this' immediately in CGAbstractBindingMethod. This makes the generated code a bit more rustic. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 769674a0b3a..ea5cd0ea6ec 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -2502,8 +2502,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod): " return false as JSBool;\n" "}\n" "\n" - "let this: JS<%s>;\n" - "this = %s;\n" % (self.descriptor.concreteType, unwrapThis))) + "let this: JS<%s> = %s;\n" % (self.descriptor.concreteType, unwrapThis))) return CGList([ unwrapThis, self.generate_code() ], "\n").define() def generate_code(self):