diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index e87feadf9e0..db723ad141c 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -48,7 +48,7 @@ use js::glue::{RUST_JSID_IS_INT, RUST_JSID_TO_INT}; use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject}; use js::jsapi::{HandleId, HandleObject, HandleValue, JSClass, JSContext}; use js::jsapi::{JSObject, JSString, JS_GetArrayBufferViewType, JS_GetClass}; -use js::jsapi::{JS_GetLatin1StringCharsAndLength, JS_GetObjectAsArrayBufferView}; +use js::jsapi::{JS_GetLatin1StringCharsAndLength, JS_GetObjectAsArrayBuffer, JS_GetObjectAsArrayBufferView}; use js::jsapi::{JS_GetReservedSlot, JS_GetTwoByteStringCharsAndLength, ToWindowProxyIfWindow}; use js::jsapi::{JS_IsArrayObject, JS_NewStringCopyN, JS_StringHasLatin1Chars}; use js::jsapi::{JS_WrapValue, MutableHandleValue, Type, IsObjectInContextCompartment}; @@ -580,6 +580,29 @@ pub unsafe fn array_buffer_view_to_vec_checked(abv: *mut JSObject) -> Option< array_buffer_view_data_checked(abv).map(|data| data.to_vec()) } +/// Similar API as the array_buffer_view_xxx functions, but for ArrayBuffer +/// objects. +pub unsafe fn array_buffer_data<'a, T>(ab: *mut JSObject) -> Option<&'a mut [T]> + where T: ArrayBufferViewContents +{ + assert!(!ab.is_null()); + + let mut byte_length = 0; + let mut ptr = ptr::null_mut(); + let ret = JS_GetObjectAsArrayBuffer(ab, &mut byte_length, &mut ptr); + if ret.is_null() { + return None; + } + Some(slice::from_raw_parts_mut(ptr as *mut T, byte_length as usize / mem::size_of::())) +} + +/// Similar API to array_buffer_view_to_vec, but for ArrayBuffer objects. +pub unsafe fn array_buffer_to_vec(ab: *mut JSObject) -> Option> + where T: ArrayBufferViewContents +{ + array_buffer_data(ab).map(|data| data.to_vec()) +} + /// Returns whether `value` is an array-like object. /// Note: Currently only Arrays are supported. /// TODO: Expand this to support sequences and other array-like objects diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index ae971503864..90e622be6c2 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -9,8 +9,8 @@ use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderi use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::conversions::{ArrayBufferViewContents, ConversionResult, FromJSValConvertible, ToJSValConvertible}; -use dom::bindings::conversions::{array_buffer_view_data, array_buffer_view_data_checked, array_buffer_view_to_vec}; -use dom::bindings::conversions::array_buffer_view_to_vec_checked; +use dom::bindings::conversions::{array_buffer_to_vec, array_buffer_view_data, array_buffer_view_data_checked}; +use dom::bindings::conversions::{array_buffer_view_to_vec, array_buffer_view_to_vec_checked}; use dom::bindings::error::{Error, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; @@ -883,7 +883,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return Ok(self.webgl_error(InvalidValue)); } - let data_vec = try!(unsafe { fallible_array_buffer_view_to_vec::(data) }); + let data_vec = unsafe { + match array_buffer_to_vec::(data) { + Some(data) => data, + // Not an ArrayBuffer object, maybe an ArrayBufferView? + None => try!(fallible_array_buffer_view_to_vec::(data)), + } + }; let bound_buffer = match target { constants::ARRAY_BUFFER => self.bound_buffer_array.get(), @@ -915,7 +921,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return Ok(self.webgl_error(InvalidValue)); } - let data_vec = try!(unsafe { fallible_array_buffer_view_to_vec::(data) }); + let data_vec = unsafe { + match array_buffer_to_vec::(data) { + Some(data) => data, + // Not an ArrayBuffer object, maybe an ArrayBufferView? + None => try!(fallible_array_buffer_view_to_vec::(data)), + } + }; let bound_buffer = match target { constants::ARRAY_BUFFER => self.bound_buffer_array.get(),