diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 489e1788f11..f9031d3369d 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -339,15 +339,62 @@ impl ToJSValConvertible for Root { } /// A JS ArrayBufferView contents can only be viewed as the types marked with this trait -pub unsafe trait ArrayBufferViewContents: Clone {} -unsafe impl ArrayBufferViewContents for u8 {} -unsafe impl ArrayBufferViewContents for i8 {} -unsafe impl ArrayBufferViewContents for u16 {} -unsafe impl ArrayBufferViewContents for i16 {} -unsafe impl ArrayBufferViewContents for u32 {} -unsafe impl ArrayBufferViewContents for i32 {} -unsafe impl ArrayBufferViewContents for f32 {} -unsafe impl ArrayBufferViewContents for f64 {} +pub unsafe trait ArrayBufferViewContents: Clone { + /// Check if the JS ArrayBufferView type is compatible with the implementor of the + /// trait + fn is_type_compatible(ty: Type) -> bool; +} + +unsafe impl ArrayBufferViewContents for u8 { + fn is_type_compatible(ty: Type) -> bool { + match ty { + Type::Uint8 | + Type::Uint8Clamped => true, + _ => false, + } + } +} + +unsafe impl ArrayBufferViewContents for i8 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Int8 as i32 + } +} + +unsafe impl ArrayBufferViewContents for u16 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Uint16 as i32 + } +} + +unsafe impl ArrayBufferViewContents for i16 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Int16 as i32 + } +} + +unsafe impl ArrayBufferViewContents for u32 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Uint32 as i32 + } +} + +unsafe impl ArrayBufferViewContents for i32 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Int32 as i32 + } +} + +unsafe impl ArrayBufferViewContents for f32 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Float32 as i32 + } +} +unsafe impl ArrayBufferViewContents for f64 { + fn is_type_compatible(ty: Type) -> bool { + ty as i32 == Type::Float64 as i32 + } +} /// Returns a mutable slice of the Array Buffer View data, viewed as T, without checking the real /// type of it. @@ -370,11 +417,10 @@ pub fn array_buffer_view_to_vec(abv: *mut JSObject) /// Returns a mutable slice of the Array Buffer View data, viewed as T, checking that the real type /// of it is ty. -pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv: *mut JSObject, - ty: Type) -> Option<&'a mut [T]> { +pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv: *mut JSObject) + -> Option<&'a mut [T]> { array_buffer_view_data::(abv).and_then(|data| { - let real_ty = JS_GetArrayBufferViewType(abv); - if real_ty as i32 == ty as i32 { + if T::is_type_compatible(JS_GetArrayBufferViewType(abv)) { Some(data) } else { None @@ -384,8 +430,8 @@ pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv /// Returns a copy of the ArrayBufferView data, viewed as T, checking that the real type /// of it is ty. -pub fn array_buffer_view_to_vec_checked(abv: *mut JSObject, ty: Type) -> Option> { +pub fn array_buffer_view_to_vec_checked(abv: *mut JSObject) -> Option> { unsafe { - array_buffer_view_data_checked(abv, ty).map(|data| data.to_vec()) + array_buffer_view_data_checked(abv).map(|data| data.to_vec()) } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 43fb4d1d325..6b6c310bcf0 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -28,7 +28,7 @@ use dom::webgltexture::{TexParameterValue, WebGLTexture}; use dom::webgluniformlocation::WebGLUniformLocation; use euclid::size::Size2D; use ipc_channel::ipc::{self, IpcSender}; -use js::jsapi::{JSContext, JSObject, RootedValue, Type}; +use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_task::ImageResponse; @@ -948,7 +948,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { None => return, }; - if let Some(data_vec) = array_buffer_view_to_vec_checked::(data, Type::Float32) { + if let Some(data_vec) = array_buffer_view_to_vec_checked::(data) { if data_vec.len() < 4 { return self.webgl_error(InvalidOperation); } @@ -976,7 +976,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = array_buffer_view_to_vec_checked::(data, Type::Float32) { + if let Some(data_vec) = array_buffer_view_to_vec_checked::(data) { if data_vec.len() < 4 { return self.webgl_error(InvalidOperation); } @@ -994,7 +994,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = array_buffer_view_to_vec_checked::(data, Type::Float32) { + if let Some(data_vec) = array_buffer_view_to_vec_checked::(data) { if data_vec.len() < 2 { return self.webgl_error(InvalidOperation); } @@ -1012,7 +1012,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib3fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = array_buffer_view_to_vec_checked::(data, Type::Float32) { + if let Some(data_vec) = array_buffer_view_to_vec_checked::(data) { if data_vec.len() < 3 { return self.webgl_error(InvalidOperation); } @@ -1029,7 +1029,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib4fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = array_buffer_view_to_vec_checked::(data, Type::Float32) { + if let Some(data_vec) = array_buffer_view_to_vec_checked::(data) { if data_vec.len() < 4 { return self.webgl_error(InvalidOperation); }