aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2015-11-08 16:11:49 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2015-11-11 17:13:59 +0100
commit63aa6862b46bb342f0752fe4fc3b2f7d8d741087 (patch)
tree86cc8488357389689274468c6f1b21538466ea1f
parent75e01de627376d987cff8bc87b5f23c79e5f36af (diff)
downloadservo-63aa6862b46bb342f0752fe4fc3b2f7d8d741087.tar.gz
servo-63aa6862b46bb342f0752fe4fc3b2f7d8d741087.zip
Implement WebIDL sequence return values
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py7
-rw-r--r--components/script/dom/bindings/conversions.rs36
2 files changed, 40 insertions, 3 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 5ac6c455e39..260ef1e9006 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1295,7 +1295,12 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.isObject() or returnType.isSpiderMonkeyInterface():
return CGGeneric("*mut JSObject")
if returnType.isSequence():
- raise TypeError("We don't support sequence return values")
+ inner = returnType.unroll()
+ result = getRetvalDeclarationForType(inner, descriptorProvider)
+ result = CGWrapper(result, pre="Vec<", post=">")
+ if returnType.nullable():
+ result = CGWrapper(result, pre="Option<", post=">")
+ return result
if returnType.isDictionary():
nullable = returnType.nullable()
dictName = returnType.inner.name if nullable else returnType.name
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs
index 45279e7a966..3f4da2199db 100644
--- a/components/script/dom/bindings/conversions.rs
+++ b/components/script/dom/bindings/conversions.rs
@@ -38,14 +38,16 @@ use dom::bindings::js::Root;
use dom::bindings::num::Finite;
use dom::bindings::reflector::{Reflectable, Reflector};
use dom::bindings::str::{ByteString, USVString};
+use dom::bindings::trace::RootedVec;
use dom::bindings::utils::DOMClass;
use js;
use js::glue::{GetProxyPrivate, IsWrapper, RUST_JS_NumberValue};
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
-use js::jsapi::{HandleId, HandleObject, HandleValue, JS_GetClass};
+use js::jsapi::{HandleId, HandleObject, HandleValue, Heap, JS_GetClass};
use js::jsapi::{JSClass, JSContext, JSObject, JSString, MutableHandleValue};
use js::jsapi::{JS_GetLatin1StringCharsAndLength, JS_GetReservedSlot};
use js::jsapi::{JS_GetTwoByteStringCharsAndLength, JS_NewStringCopyN};
+use js::jsapi::{JS_NewArrayObject, HandleValueArray, RootedValue};
use js::jsapi::{JS_NewUCStringCopyN, JS_StringHasLatin1Chars, JS_WrapValue};
use js::jsval::{BooleanValue, Int32Value, NullValue, UInt32Value, UndefinedValue};
use js::jsval::{JSVal, ObjectOrNullValue, ObjectValue, StringValue};
@@ -56,7 +58,7 @@ use libc;
use num::Float;
use num::traits::{Bounded, Zero};
use std::rc::Rc;
-use std::{char, ptr, slice};
+use std::{char, mem, ptr, slice};
use util::str::DOMString;
trait As<O>: Copy {
@@ -811,6 +813,36 @@ impl<T: FromJSValConvertible> FromJSValConvertible for Option<T> {
}
}
+impl<T: ToJSValConvertible> ToJSValConvertible for Vec<T> {
+ fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
+ let mut js_objects = RootedVec::new();
+
+ for obj in self.iter() {
+ let mut heap = Heap::default();
+ let mut val = RootedValue::new(cx, UndefinedValue());
+ obj.to_jsval(cx, val.handle_mut());
+ heap.set(val.handle().get());
+ js_objects.push(heap);
+ }
+
+ let values: Vec<JSVal> = js_objects.iter()
+ .map(|heap| heap.handle().get())
+ .collect();
+
+ let handle = HandleValueArray {
+ length_: values.len() as u64,
+ elements_: values.as_ptr(),
+ };
+
+ unsafe {
+ let js_array = JS_NewArrayObject(cx, &handle);
+ assert!(!js_array.is_null());
+
+ rval.set(ObjectValue(mem::transmute(js_array)));
+ }
+ }
+}
+
//http://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for *mut JSObject {
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {