From 177ef22673bca632005a534b590336eee7db444c Mon Sep 17 00:00:00 2001 From: Chinedu Francis Nwafili Date: Mon, 14 Jan 2019 17:45:43 -0500 Subject: [PATCH 1/2] Add maybe adjust function --- crates/webidl/src/util.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index 412e45d7..629b94e8 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -433,7 +433,10 @@ impl<'src> FirstPassRecord<'src> { ); signatures.push((signature, idl_args.clone())); } - idl_args.push(arg.ty.to_idl_type(self)); + + let idl_type = arg.ty.to_idl_type(self); + let idl_type = maybe_adjust(idl_type, id); + idl_args.push(idl_type); } signatures.push((signature, idl_args)); } @@ -707,3 +710,21 @@ pub fn public() -> syn::Visibility { pub_token: Default::default(), }) } + +/// When generating our web_sys APIs we default to setting slice references that +/// get passed to JS as mutable in case they get mutated in JS. +/// +/// In certain cases we know for sure that the slice will not get mutated - for +/// example when working with the WebGlRenderingContext APIs. +/// +/// Here we implement a whitelist for those cases. This whitelist is currently +/// maintained by hand. +fn maybe_adjust<'a> (idl_type: IdlType<'a>, id: &'a OperationId) -> IdlType<'a> { + match id { + OperationId::Operation(Some(op)) => { + // TODO: `match op` and return an adjusted idl_type if necessary + idl_type + } + _ => idl_type + } +} From 1d0c2fee9ef14ea484e83c524c365e90809dacdb Mon Sep 17 00:00:00 2001 From: Chinedu Francis Nwafili Date: Thu, 17 Jan 2019 13:20:53 -0500 Subject: [PATCH 2/2] Add failing immutable slice test --- crates/web-sys/tests/wasm/element.js | 5 ++++ crates/web-sys/tests/wasm/immutable_slices.rs | 26 +++++++++++++++++++ crates/web-sys/tests/wasm/main.rs | 1 + crates/webidl-tests/lib.rs | 2 ++ 4 files changed, 34 insertions(+) create mode 100644 crates/web-sys/tests/wasm/immutable_slices.rs diff --git a/crates/web-sys/tests/wasm/element.js b/crates/web-sys/tests/wasm/element.js index ed51fbdb..3f34bc5f 100644 --- a/crates/web-sys/tests/wasm/element.js +++ b/crates/web-sys/tests/wasm/element.js @@ -151,6 +151,11 @@ export function new_title() { return document.createElement("title"); } +export function new_webgl_rendering_context() { + const canvas = document.createElement('canvas'); + return canvas.getContext('webgl'); +} + export function new_xpath_result() { let xmlDoc = new DOMParser().parseFromString("tomato", "application/xml"); let xpathResult = xmlDoc.evaluate("/root//value", xmlDoc, null, XPathResult.ANY_TYPE, null); diff --git a/crates/web-sys/tests/wasm/immutable_slices.rs b/crates/web-sys/tests/wasm/immutable_slices.rs new file mode 100644 index 00000000..92b4cbd3 --- /dev/null +++ b/crates/web-sys/tests/wasm/immutable_slices.rs @@ -0,0 +1,26 @@ +//! When generating our web_sys APIs we default to setting slice references that +//! get passed to JS as mutable in case they get mutated in JS. +//! +//! In certain cases we know for sure that the slice will not get mutated - for +//! example when working with the WebGlRenderingContext APIs. +//! +//! These tests ensure that whitelisted methods do indeed accept mutable slices. +//! +//! @see https://github.com/rustwasm/wasm-bindgen/issues/1005 + +use wasm_bindgen::prelude::*; +use wasm_bindgen_test::*; +use web_sys::WebGlRenderingContext; + +#[wasm_bindgen(module = "./tests/wasm/element.js")] +extern "C" { + fn new_webgl_rendering_context() -> WebGlRenderingContext; +} + +// Ensure that our whitelisted WebGlRenderingContext methods work +#[wasm_bindgen_test] +fn test_webgl_rendering_context_immutable_slices() { + let gl = new_webgl_rendering_context(); + + gl.vertex_attrib1fv_with_f32_array(0, &[5000.]); +} diff --git a/crates/web-sys/tests/wasm/main.rs b/crates/web-sys/tests/wasm/main.rs index 8f2fd5ff..3b57604a 100644 --- a/crates/web-sys/tests/wasm/main.rs +++ b/crates/web-sys/tests/wasm/main.rs @@ -56,6 +56,7 @@ pub mod style_element; pub mod table_element; pub mod title_element; pub mod xpath_result; +pub mod immutable_slices; #[wasm_bindgen_test] fn deref_works() { diff --git a/crates/webidl-tests/lib.rs b/crates/webidl-tests/lib.rs index 44425d9c..7d245db2 100644 --- a/crates/webidl-tests/lib.rs +++ b/crates/webidl-tests/lib.rs @@ -1 +1,3 @@ // intentionally left blank + +// QUESTION FOR REVIEWER: WHY? (I'll include this context in the comment)