Auto merge of #9056 - ecoal95:sequence-args, r=nox

Implement WebIDL sequence arguments

And use it for `WebGLRenderingContext#uniform1fv`.

Blocked on https://github.com/servo/rust-mozjs/pull/226

Fixes #544

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9056)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-01-12 23:27:30 +05:30
commit c97d557720
5 changed files with 58 additions and 28 deletions

View file

@ -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():

View file

@ -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)]

View file

@ -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<i32> { vec![1] }
fn ReceiveNullableBoolean(&self) -> Option<bool> { Some(false) }
fn ReceiveNullableByte(&self) -> Option<i8> { Some(0) }
@ -216,6 +217,7 @@ impl TestBindingMethods for TestBinding {
fn ReceiveNullableUnion2(&self) -> Option<EventOrString> {
Some(EventOrString::eString(DOMString::new()))
}
fn ReceiveNullableSequence(&self) -> Option<Vec<i32>> { 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<Function>) {}
fn PassCallbackInterface(&self, _: Rc<EventListener>) {}
fn PassSequence(&self, _: Vec<i32>) {}
fn PassStringSequence(&self, _: Vec<DOMString>) {}
fn PassNullableBoolean(&self, _: Option<bool>) {}
fn PassNullableByte(&self, _: Option<i8>) {}
@ -266,6 +270,7 @@ impl TestBindingMethods for TestBinding {
fn PassNullableUnion2(&self, _: Option<EventOrString>) {}
fn PassNullableCallbackFunction(&self, _: Option<Rc<Function>>) {}
fn PassNullableCallbackInterface(&self, _: Option<Rc<EventListener>>) {}
fn PassNullableSequence(&self, _: Option<Vec<i32>>) {}
fn PassOptionalBoolean(&self, _: Option<bool>) {}
fn PassOptionalByte(&self, _: Option<i8>) {}
@ -291,6 +296,7 @@ impl TestBindingMethods for TestBinding {
fn PassOptionalObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {}
fn PassOptionalCallbackFunction(&self, _: Option<Rc<Function>>) {}
fn PassOptionalCallbackInterface(&self, _: Option<Rc<EventListener>>) {}
fn PassOptionalSequence(&self, _: Option<Vec<i32>>) {}
fn PassOptionalNullableBoolean(&self, _: Option<Option<bool>>) {}
fn PassOptionalNullableByte(&self, _: Option<Option<i8>>) {}
@ -315,6 +321,7 @@ impl TestBindingMethods for TestBinding {
fn PassOptionalNullableUnion2(&self, _: Option<Option<EventOrString>>) {}
fn PassOptionalNullableCallbackFunction(&self, _: Option<Option<Rc<Function>>>) {}
fn PassOptionalNullableCallbackInterface(&self, _: Option<Option<Rc<EventListener>>>) {}
fn PassOptionalNullableSequence(&self, _: Option<Option<Vec<i32>>>) {}
fn PassOptionalBooleanWithDefault(&self, _: bool) {}
fn PassOptionalByteWithDefault(&self, _: i8) {}

View file

@ -149,6 +149,7 @@ interface TestBinding {
object receiveObject();
(HTMLElement or long) receiveUnion();
(Event or DOMString) receiveUnion2();
sequence<long> receiveSequence();
byte? receiveNullableByte();
boolean? receiveNullableBoolean();
@ -171,6 +172,7 @@ interface TestBinding {
object? receiveNullableObject();
(HTMLElement or long)? receiveNullableUnion();
(Event or DOMString)? receiveNullableUnion2();
sequence<long>? 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<long> seq);
void passStringSequence(sequence<DOMString> 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<long>? 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<long> 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<long>? seq);
void passOptionalBooleanWithDefault(optional boolean arg = false);
void passOptionalByteWithDefault(optional byte arg = 0);

View file

@ -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,