From d89f867b14e0472f3021297ba85c68fa701bc210 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 9 Jun 2014 10:32:02 +0200 Subject: [PATCH 1/3] Implement variadic arguments (fixes #1985). --- .../dom/bindings/codegen/CodegenRust.py | 66 +++++++++++++------ 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 300c8b6ab8a..a5e43e69755 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -890,9 +890,6 @@ class CGArgumentConverter(CGThing): def __init__(self, argument, index, argv, argc, descriptorProvider, invalidEnumValueFatal=True): CGThing.__init__(self) - if argument.variadic: - raise TypeError("We don't support variadic arguments yet " + - str(argument.location)) assert(not argument.defaultValue or argument.optional) replacer = { @@ -914,26 +911,57 @@ class CGArgumentConverter(CGThing): treatNullAs=argument.treatNullAs, isEnforceRange=argument.enforceRange, isClamp=argument.clamp, + isMember="Variadic" if argument.variadic else False, allowTreatNonObjectAsNull=argument.allowTreatNonCallableAsNull()) - if argument.optional: - if argument.defaultValue: - assert default - template = CGIfElseWrapper(condition, - CGGeneric(template), - CGGeneric(default)).define() + if not argument.variadic: + if argument.optional: + if argument.defaultValue: + assert default + template = CGIfElseWrapper(condition, + CGGeneric(template), + CGGeneric(default)).define() + else: + assert not default + declType = CGWrapper(declType, pre="Option<", post=">") + template = CGIfElseWrapper(condition, + CGGeneric("Some(%s)" % template), + CGGeneric("None")).define() else: assert not default - declType = CGWrapper(declType, pre="Option<", post=">") - template = CGIfElseWrapper(condition, - CGGeneric("Some(%s)" % template), - CGGeneric("None")).define() - else: - assert not default - self.converter = instantiateJSToNativeConversionTemplate( - template, replacementVariables, declType, "arg%d" % index, - needsRooting) + self.converter = instantiateJSToNativeConversionTemplate( + template, replacementVariables, declType, "arg%d" % index, + needsRooting) + else: + assert argument.optional + variadicConversion = { + "val": string.Template("(*${argv}.offset(variadicArg as int))").substitute(replacer), + } + innerConverter = instantiateJSToNativeConversionTemplate( + template, variadicConversion, declType, "slot", + needsRooting) + + seqType = CGTemplatedType("Vec", declType) + variadicConversion = string.Template( + "{\n" + " let mut vector: ${seqType} = vec![];\n" + " for variadicArg in range(${index}, ${argc}) {\n" + "${inner}\n" + " vector.push(slot);\n" + " }\n" + " vector\n" + "}" + ).substitute({ + "index": index, + "argc": argc, + "seqType": seqType.define(), + "inner": CGIndenter(innerConverter, 4).define(), + }) + + self.converter = instantiateJSToNativeConversionTemplate( + variadicConversion, replacementVariables, seqType, "arg%d" % index, + False) def define(self): return self.converter.define() @@ -4023,7 +4051,7 @@ class CGDictionary(CGThing): (member, getJSToNativeConversionTemplate(member.type, descriptorProvider, - isMember=True, + isMember="Dictionary", defaultValue=member.defaultValue, failureCode="return Err(());", exceptionCode="return Err(());")) From 78f368d33619406fcbf2c9efe38d08693cc4d1be Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 9 Jun 2014 12:00:36 +0200 Subject: [PATCH 2/3] Support union variadic arguments and add tests. --- .../dom/bindings/codegen/CodegenRust.py | 4 ---- src/components/script/dom/testbinding.rs | 20 +++++++++++++++++++ .../script/dom/webidls/TestBinding.webidl | 20 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index a5e43e69755..069254b7c16 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -551,10 +551,6 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, raise TypeError("Can't handle sequence arguments yet") if type.isUnion(): - if isMember: - raise TypeError("Can't handle unions as members, we have a " - "holderType") - declType = CGGeneric(type.name + "::" + type.name) if type.nullable(): declType = CGWrapper(declType, pre="Option<", post=" >") diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index dd439a1622a..4f0a2081bf7 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -255,6 +255,26 @@ pub trait TestBindingMethods { // fn PassOptionalNullableDoubleWithNonNullDefault(&self, _: Option) {} fn PassOptionalNullableStringWithNonNullDefault(&self, _: Option) {} // fn PassOptionalNullableEnumWithNonNullDefault(&self, _: Option) {} + + fn PassVariadicBoolean(&self, _: Vec) {} + fn PassVariadicByte(&self, _: Vec) {} + fn PassVariadicOctet(&self, _: Vec) {} + fn PassVariadicShort(&self, _: Vec) {} + fn PassVariadicUnsignedShort(&self, _: Vec) {} + fn PassVariadicLong(&self, _: Vec) {} + fn PassVariadicUnsignedLong(&self, _: Vec) {} + fn PassVariadicLongLong(&self, _: Vec) {} + fn PassVariadicUnsignedLongLong(&self, _: Vec) {} + fn PassVariadicFloat(&self, _: Vec) {} + fn PassVariadicDouble(&self, _: Vec) {} + fn PassVariadicString(&self, _: Vec) {} + fn PassVariadicByteString(&self, _: Vec) {} + fn PassVariadicEnum(&self, _: Vec) {} + // fn PassVariadicInterface(&self, _: Vec>) {} + fn PassVariadicUnion(&self, _: Vec) {} + fn PassVariadicUnion2(&self, _: Vec) {} + fn PassVariadicUnion3(&self, _: Vec) {} + fn PassVariadicAny(&self, _: *mut JSContext, _: Vec) {} } impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index 6d2137cdd60..2437514a2c1 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -246,4 +246,24 @@ interface TestBinding { // void passOptionalNullableEnumWithNonNullDefault(optional TestEnum? arg = "foo"); // void passOptionalNullableUnionWithNonNullDefault(optional (HTMLElement or long)? arg = 7); // void passOptionalNullableUnion2WithNonNullDefault(optional (Event or DOMString)? data = "foo"); + + void passVariadicBoolean(boolean... args); + void passVariadicByte(byte... args); + void passVariadicOctet(octet... args); + void passVariadicShort(short... args); + void passVariadicUnsignedShort(unsigned short... args); + void passVariadicLong(long... args); + void passVariadicUnsignedLong(unsigned long... args); + void passVariadicLongLong(long long... args); + void passVariadicUnsignedLongLong(unsigned long long... args); + void passVariadicFloat(float... args); + void passVariadicDouble(double... args); + void passVariadicString(DOMString... args); + void passVariadicByteString(ByteString... args); + void passVariadicEnum(TestEnum... args); + // void passVariadicInterface(Blob... args); + void passVariadicUnion((HTMLElement or long)... args); + void passVariadicUnion2((Event or DOMString)... args); + void passVariadicUnion3((Blob or DOMString)... args); + void passVariadicAny(any... args); }; From 406acd17af7f6f41186216fdb054c0f4a5d6580e Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 9 Jun 2014 14:06:03 +0200 Subject: [PATCH 3/3] Avoid reallocations with variadic arguments. Thanks to huon for pointing that out. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 069254b7c16..0f8de8249cb 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -941,7 +941,7 @@ class CGArgumentConverter(CGThing): seqType = CGTemplatedType("Vec", declType) variadicConversion = string.Template( "{\n" - " let mut vector: ${seqType} = vec![];\n" + " let mut vector: ${seqType} = Vec::with_capacity((${argc} - ${index}) as uint);\n" " for variadicArg in range(${index}, ${argc}) {\n" "${inner}\n" " vector.push(slot);\n"