From 63aa6862b46bb342f0752fe4fc3b2f7d8d741087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 8 Nov 2015 16:11:49 +0100 Subject: [PATCH 1/4] Implement WebIDL sequence return values --- .../dom/bindings/codegen/CodegenRust.py | 7 +++- components/script/dom/bindings/conversions.rs | 36 +++++++++++++++++-- 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: Copy { @@ -811,6 +813,36 @@ impl FromJSValConvertible for Option { } } +impl ToJSValConvertible for Vec { + 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 = 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) { From b740b90b8d106120393bdccc36a1da823f98a583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 8 Nov 2015 16:12:41 +0100 Subject: [PATCH 2/4] webgl: Implement getSupportedExtensions --- components/script/dom/webglrenderingcontext.rs | 5 +++++ components/script/dom/webidls/WebGLRenderingContext.webidl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 875f88628f4..4855bcc36de 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -244,6 +244,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { }) } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.14 + fn GetSupportedExtensions(&self) -> Option> { + Some(vec![]) + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.14 fn GetExtension(&self, _cx: *mut JSContext, _name: DOMString) -> *mut JSObject { // TODO(ecoal95) we actually do not support extensions. diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 957220efa54..27019ed7754 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -471,7 +471,7 @@ interface WebGLRenderingContextBase [WebGLHandlesContextLoss] WebGLContextAttributes? getContextAttributes(); //[WebGLHandlesContextLoss] boolean isContextLost(); - //sequence? getSupportedExtensions(); + sequence? getSupportedExtensions(); object? getExtension(DOMString name); void activeTexture(GLenum texture); From 75ecb67e62f2f6db5e71405f16813208e8d6274a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 8 Nov 2015 16:22:43 +0100 Subject: [PATCH 3/4] webgl: Add test for getSupportedExtensions --- tests/wpt/mozilla/meta/MANIFEST.json | 12 ++++++++--- .../context_creation_error.html} | 0 .../webgl/get_supported_extensions.html | 20 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) rename tests/wpt/mozilla/tests/mozilla/{webgl_context_creation_error.html => webgl/context_creation_error.html} (100%) create mode 100644 tests/wpt/mozilla/tests/mozilla/webgl/get_supported_extensions.html diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 117bdbf5407..30c6d7f71a4 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5047,10 +5047,16 @@ "url": "/_mozilla/mozilla/variadic-interface.html" } ], - "mozilla/webgl_context_creation_error.html": [ + "mozilla/webgl/context_creation_error.html": [ { - "path": "mozilla/webgl_context_creation_error.html", - "url": "/_mozilla/mozilla/webgl_context_creation_error.html" + "path": "mozilla/webgl/context_creation_error.html", + "url": "/_mozilla/mozilla/webgl/context_creation_error.html" + } + ], + "mozilla/webgl/get_supported_extensions.html": [ + { + "path": "mozilla/webgl/get_supported_extensions.html", + "url": "/_mozilla/mozilla/webgl/get_supported_extensions.html" } ], "mozilla/websocket_connection_fail.html": [ diff --git a/tests/wpt/mozilla/tests/mozilla/webgl_context_creation_error.html b/tests/wpt/mozilla/tests/mozilla/webgl/context_creation_error.html similarity index 100% rename from tests/wpt/mozilla/tests/mozilla/webgl_context_creation_error.html rename to tests/wpt/mozilla/tests/mozilla/webgl/context_creation_error.html diff --git a/tests/wpt/mozilla/tests/mozilla/webgl/get_supported_extensions.html b/tests/wpt/mozilla/tests/mozilla/webgl/get_supported_extensions.html new file mode 100644 index 00000000000..691535db476 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/webgl/get_supported_extensions.html @@ -0,0 +1,20 @@ + + +WebGLContextEvent getSupportedExtensions test + + + From e33330db4eb9d9187c98139aad732ff86ab9d828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 11 Nov 2015 18:07:51 +0100 Subject: [PATCH 4/4] Implement WebIDL sequence return value using `JS_NewArrayObject1` This commits changes the creation of the array to use the length, and sets the elements later. Reference implementation: https://github.com/mozilla/gecko-dev/blob/07ed19e582faf40f5f72567169db62452f6c6dc9/js/xpconnect/public/nsTArrayHelpers.h#L16 --- components/script/dom/bindings/conversions.rs | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 3f4da2199db..493ed4c0c27 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -38,16 +38,15 @@ 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, Heap, JS_GetClass}; +use js::jsapi::{HandleId, HandleObject, HandleValue, 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_NewArrayObject1, JS_DefineElement, RootedValue, RootedObject}; use js::jsapi::{JS_NewUCStringCopyN, JS_StringHasLatin1Chars, JS_WrapValue}; use js::jsval::{BooleanValue, Int32Value, NullValue, UInt32Value, UndefinedValue}; use js::jsval::{JSVal, ObjectOrNullValue, ObjectValue, StringValue}; @@ -58,7 +57,7 @@ use libc; use num::Float; use num::traits::{Bounded, Zero}; use std::rc::Rc; -use std::{char, mem, ptr, slice}; +use std::{char, ptr, slice}; use util::str::DOMString; trait As: Copy { @@ -815,30 +814,22 @@ impl FromJSValConvertible for Option { impl ToJSValConvertible for Vec { fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { - let mut js_objects = RootedVec::new(); + let js_array = RootedObject::new(cx, + unsafe { JS_NewArrayObject1(cx, self.len() as libc::size_t) }); + assert!(!js_array.handle().is_null()); - for obj in self.iter() { - let mut heap = Heap::default(); + for (index, obj) in self.iter().enumerate() { let mut val = RootedValue::new(cx, UndefinedValue()); obj.to_jsval(cx, val.handle_mut()); - heap.set(val.handle().get()); - js_objects.push(heap); + + unsafe { + assert!(JS_DefineElement(cx, js_array.handle(), + index as u32, val.handle(), js::JSPROP_ENUMERATE, None, None)); + } } - let values: Vec = 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))); + rval.set(ObjectValue(&*js_array.handle().get())); } } }