diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 82fcc4581d5..2a04db77cc9 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -700,7 +700,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, raise TypeError("Can't handle array arguments yet") if type.isSequence(): - raise TypeError("Can't handle sequence arguments yet") + # Use the same type that for return values + declType = getRetvalDeclarationForType(type, descriptorProvider) + config = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs) + + templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" + " Ok(value) => value,\n" + " Err(()) => { %s },\n" + "}" % (config, exceptionCode)) + + return handleOptional(templateBody, declType, handleDefaultNull("None")) if type.isUnion(): declType = CGGeneric(union_native_type(type)) @@ -775,20 +784,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, raise TypeError("Can't handle SpiderMonkey interface arguments yet") if type.isDOMString(): - assert not isEnforceRange and not isClamp - - treatAs = { - "Default": "StringificationBehavior::Default", - "EmptyString": "StringificationBehavior::Empty", - } - if treatNullAs not in treatAs: - raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs) - if type.nullable(): - # Note: the actual behavior passed here doesn't matter for nullable - # strings. - nullBehavior = "StringificationBehavior::Default" - else: - nullBehavior = treatAs[treatNullAs] + nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs) conversionCode = ( "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" @@ -1002,16 +998,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if not type.isPrimitive(): raise TypeError("Need conversion for argument type '%s'" % str(type)) - if type.isInteger(): - if isEnforceRange: - conversionBehavior = "ConversionBehavior::EnforceRange" - elif isClamp: - conversionBehavior = "ConversionBehavior::Clamp" - else: - conversionBehavior = "ConversionBehavior::Default" - else: - assert not isEnforceRange and not isClamp - conversionBehavior = "()" + conversionBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs) if failureCode is None: failureCode = 'return false' @@ -1215,6 +1202,36 @@ def typeNeedsCx(type, retVal=False): return type.isAny() or type.isObject() +# Returns a conversion behavior suitable for a type +def getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs): + if type.isSequence(): + return getConversionConfigForType(type.unroll(), isEnforceRange, isClamp, treatNullAs) + if type.isDOMString(): + assert not isEnforceRange and not isClamp + + treatAs = { + "Default": "StringificationBehavior::Default", + "EmptyString": "StringificationBehavior::Empty", + } + if treatNullAs not in treatAs: + raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs) + if type.nullable(): + # Note: the actual behavior passed here doesn't matter for nullable + # strings. + return "StringificationBehavior::Default" + else: + return treatAs[treatNullAs] + if type.isInteger(): + if isEnforceRange: + return "ConversionBehavior::EnforceRange" + elif isClamp: + return "ConversionBehavior::Clamp" + else: + return "ConversionBehavior::Default" + assert not isEnforceRange and not isClamp + return "()" + + # Returns a CGThing containing the type of the return value. def getRetvalDeclarationForType(returnType, descriptorProvider): if returnType is None or returnType.isVoid(): diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 2ac927066b6..eeeb4d9766d 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -10,7 +10,7 @@ use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::root_from_object; -use dom::bindings::js::{JS, Root}; +use dom::bindings::js::Root; use dom::bindings::reflector::{Reflectable, Reflector}; use dom::window::{self, ScriptHelpers}; use dom::workerglobalscope::WorkerGlobalScope; @@ -25,7 +25,6 @@ use script_thread::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThread}; use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest}; use timers::{ScheduledCallback, TimerHandle}; use url::Url; -use util::mem::HeapSizeOf; /// A freely-copyable reference to a rooted global object. #[derive(Copy, Clone)] diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index ba57bce3bf1..687d68a5eb9 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -188,6 +188,7 @@ impl TestBindingMethods for TestBinding { fn ReceiveObject(&self, _: *mut JSContext) -> *mut JSObject { panic!() } fn ReceiveUnion(&self) -> HTMLElementOrLong { HTMLElementOrLong::eLong(0) } fn ReceiveUnion2(&self) -> EventOrString { EventOrString::eString(DOMString::new()) } + fn ReceiveSequence(&self) -> Vec { vec![1] } fn ReceiveNullableBoolean(&self) -> Option { Some(false) } fn ReceiveNullableByte(&self) -> Option { Some(0) } @@ -216,6 +217,7 @@ impl TestBindingMethods for TestBinding { fn ReceiveNullableUnion2(&self) -> Option { Some(EventOrString::eString(DOMString::new())) } + fn ReceiveNullableSequence(&self) -> Option> { Some(vec![1]) } fn PassBoolean(&self, _: bool) {} fn PassByte(&self, _: i8) {} @@ -242,6 +244,8 @@ impl TestBindingMethods for TestBinding { fn PassObject(&self, _: *mut JSContext, _: *mut JSObject) {} fn PassCallbackFunction(&self, _: Rc) {} fn PassCallbackInterface(&self, _: Rc) {} + fn PassSequence(&self, _: Vec) {} + fn PassStringSequence(&self, _: Vec) {} fn PassNullableBoolean(&self, _: Option) {} fn PassNullableByte(&self, _: Option) {} @@ -266,6 +270,7 @@ impl TestBindingMethods for TestBinding { fn PassNullableUnion2(&self, _: Option) {} fn PassNullableCallbackFunction(&self, _: Option>) {} fn PassNullableCallbackInterface(&self, _: Option>) {} + fn PassNullableSequence(&self, _: Option>) {} fn PassOptionalBoolean(&self, _: Option) {} fn PassOptionalByte(&self, _: Option) {} @@ -291,6 +296,7 @@ impl TestBindingMethods for TestBinding { fn PassOptionalObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} fn PassOptionalCallbackFunction(&self, _: Option>) {} fn PassOptionalCallbackInterface(&self, _: Option>) {} + fn PassOptionalSequence(&self, _: Option>) {} fn PassOptionalNullableBoolean(&self, _: Option>) {} fn PassOptionalNullableByte(&self, _: Option>) {} @@ -315,6 +321,7 @@ impl TestBindingMethods for TestBinding { fn PassOptionalNullableUnion2(&self, _: Option>) {} fn PassOptionalNullableCallbackFunction(&self, _: Option>>) {} fn PassOptionalNullableCallbackInterface(&self, _: Option>>) {} + fn PassOptionalNullableSequence(&self, _: Option>>) {} fn PassOptionalBooleanWithDefault(&self, _: bool) {} fn PassOptionalByteWithDefault(&self, _: i8) {} diff --git a/components/script/dom/webidls/TestBinding.webidl b/components/script/dom/webidls/TestBinding.webidl index e6495d90d66..7934182621e 100644 --- a/components/script/dom/webidls/TestBinding.webidl +++ b/components/script/dom/webidls/TestBinding.webidl @@ -149,6 +149,7 @@ interface TestBinding { object receiveObject(); (HTMLElement or long) receiveUnion(); (Event or DOMString) receiveUnion2(); + sequence receiveSequence(); byte? receiveNullableByte(); boolean? receiveNullableBoolean(); @@ -171,6 +172,7 @@ interface TestBinding { object? receiveNullableObject(); (HTMLElement or long)? receiveNullableUnion(); (Event or DOMString)? receiveNullableUnion2(); + sequence? receiveNullableSequence(); void passBoolean(boolean arg); void passByte(byte arg); @@ -197,6 +199,8 @@ interface TestBinding { void passObject(object arg); void passCallbackFunction(Function fun); void passCallbackInterface(EventListener listener); + void passSequence(sequence seq); + void passStringSequence(sequence seq); void passNullableBoolean(boolean? arg); void passNullableByte(byte? arg); @@ -221,6 +225,7 @@ interface TestBinding { void passNullableUnion2((Event or DOMString)? data); void passNullableCallbackFunction(Function? fun); void passNullableCallbackInterface(EventListener? listener); + void passNullableSequence(sequence? seq); void passOptionalBoolean(optional boolean arg); void passOptionalByte(optional byte arg); @@ -246,6 +251,7 @@ interface TestBinding { void passOptionalObject(optional object arg); void passOptionalCallbackFunction(optional Function fun); void passOptionalCallbackInterface(optional EventListener listener); + void passOptionalSequence(optional sequence seq); void passOptionalNullableBoolean(optional boolean? arg); void passOptionalNullableByte(optional byte? arg); @@ -270,6 +276,7 @@ interface TestBinding { void passOptionalNullableUnion2(optional (Event or DOMString)? data); void passOptionalNullableCallbackFunction(optional Function? fun); void passOptionalNullableCallbackInterface(optional EventListener? listener); + void passOptionalNullableSequence(optional sequence? seq); void passOptionalBooleanWithDefault(optional boolean arg = false); void passOptionalByteWithDefault(optional byte arg = 0); diff --git a/components/util/non_geckolib.rs b/components/util/non_geckolib.rs index f7e6fc401da..cb047a0ec18 100644 --- a/components/util/non_geckolib.rs +++ b/components/util/non_geckolib.rs @@ -25,7 +25,7 @@ use std::slice; use str::DOMString; /// Behavior for stringification of `JSVal`s. -#[derive(PartialEq)] +#[derive(PartialEq, Clone)] pub enum StringificationBehavior { /// Convert `null` to the string `"null"`. Default,