From 4567438ff5fd9e5619963a2d29570b40636c0ab2 Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Sat, 2 Nov 2019 21:59:35 -0400 Subject: [PATCH 1/7] adding .vscode folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index aedc2d91aed..4bc7132ff97 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ yarn.lock *.d.ts /publish /publish.exe +.vscode From bba3b86bcda4ef64ebdb83c3b176d0b65a13c48a Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Sun, 3 Nov 2019 20:00:05 -0500 Subject: [PATCH 2/7] Adding view_mut_raw to generated arrays --- crates/js-sys/src/lib.rs | 10 ++++++++++ crates/js-sys/tests/wasm/Array.rs | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index edb8bbe4e5f..783f0630fda 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -4792,6 +4792,16 @@ macro_rules! arrays { ) } + pub unsafe fn view_mut_raw(ptr: *mut $ty, length: usize) -> $name { + let buf = wasm_bindgen::memory(); + let mem = buf.unchecked_ref::(); + $name::new_with_byte_offset_and_length( + &mem.buffer(), + ptr as u32, + length as u32 + ) + } + fn raw_copy_to(&self, dst: &mut [$ty]) { let buf = wasm_bindgen::memory(); let mem = buf.unchecked_ref::(); diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index 46e6f1d6736..6fb84139eaa 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -466,3 +466,8 @@ fn array_inheritance() { assert!(array.is_instance_of::()); let _: &Object = array.as_ref(); } + +#[wasm_bindgen_test] +fn uint8_view_mut_raw() { + assert!(1 == 2); +} From bb3d38c219230f16d543d41829a907c6d8c241c7 Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Mon, 4 Nov 2019 21:41:52 -0500 Subject: [PATCH 3/7] test populating rust vector from JS function --- crates/js-sys/tests/wasm/Array.js | 6 ++++++ crates/js-sys/tests/wasm/Array.rs | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 crates/js-sys/tests/wasm/Array.js diff --git a/crates/js-sys/tests/wasm/Array.js b/crates/js-sys/tests/wasm/Array.js new file mode 100644 index 00000000000..8eac04b12a3 --- /dev/null +++ b/crates/js-sys/tests/wasm/Array.js @@ -0,0 +1,6 @@ +// Used for `Array.rs` tests +exports.populate_array = function(arr, len) { + for (i = 0; i < len; i++) { + arr[i] = i; + } +}; diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index 6fb84139eaa..e8bdafe9832 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -1,5 +1,6 @@ use js_sys::*; use std::iter::FromIterator; +use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use wasm_bindgen_test::*; @@ -467,7 +468,21 @@ fn array_inheritance() { let _: &Object = array.as_ref(); } +#[wasm_bindgen(module = "tests/wasm/Array.js")] +extern "C" { + fn populate_array(arr: JsValue, len: JsValue) -> JsValue; +} + #[wasm_bindgen_test] fn uint8_view_mut_raw() { - assert!(1 == 2); + let len: usize = 32; + let mut buffer: Vec = Vec::new(); + buffer.reserve(len); + unsafe { + let array = js_sys::Uint8Array::view_mut_raw(buffer.as_mut_ptr(), len); + populate_array(JsValue::from(array), JsValue::from(len as u32)); + buffer.set_len(len); + } + let expected: Vec = (0..(len as u8)).collect(); + assert_eq!(buffer, expected) } From 06c5a149f0d2b9ff8213c4a473d36386623460bb Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Mon, 4 Nov 2019 23:19:20 -0500 Subject: [PATCH 4/7] Uint32Array test, need to make it generic --- crates/js-sys/tests/wasm/Array.js | 4 ++-- crates/js-sys/tests/wasm/Array.rs | 34 +++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/crates/js-sys/tests/wasm/Array.js b/crates/js-sys/tests/wasm/Array.js index 8eac04b12a3..8810bd9db88 100644 --- a/crates/js-sys/tests/wasm/Array.js +++ b/crates/js-sys/tests/wasm/Array.js @@ -1,6 +1,6 @@ // Used for `Array.rs` tests -exports.populate_array = function(arr, len) { +exports.populate_array = function(arr, start, len) { for (i = 0; i < len; i++) { - arr[i] = i; + arr[i] = start + i; } }; diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index e8bdafe9832..60a5b8bb2bd 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -470,19 +470,45 @@ fn array_inheritance() { #[wasm_bindgen(module = "tests/wasm/Array.js")] extern "C" { - fn populate_array(arr: JsValue, len: JsValue) -> JsValue; + fn populate_array(arr: JsValue, start: JsValue, len: JsValue) -> JsValue; } #[wasm_bindgen_test] -fn uint8_view_mut_raw() { +fn uint8array_view_mut_raw() { + let start: u8 = 10; let len: usize = 32; + let end: u8 = start + len as u8; let mut buffer: Vec = Vec::new(); buffer.reserve(len); unsafe { let array = js_sys::Uint8Array::view_mut_raw(buffer.as_mut_ptr(), len); - populate_array(JsValue::from(array), JsValue::from(len as u32)); + populate_array( + JsValue::from(array), + JsValue::from(start), + JsValue::from(len as u32), + ); buffer.set_len(len); } - let expected: Vec = (0..(len as u8)).collect(); + let expected: Vec = (start..end).collect(); + assert_eq!(buffer, expected) +} + +#[wasm_bindgen_test] +fn uint32array_view_mut_raw() { + let start: u32 = 10; + let len: usize = 32; + let end: u32 = start + len as u32; + let mut buffer: Vec = Vec::new(); + buffer.reserve(len); + unsafe { + let array = js_sys::Uint32Array::view_mut_raw(buffer.as_mut_ptr(), len); + populate_array( + JsValue::from(array), + JsValue::from(start), + JsValue::from(len as u32), + ); + buffer.set_len(len); + } + let expected: Vec = (start..end).collect(); assert_eq!(buffer, expected) } From 982c2720b3c29b02be94e09cdb7b358d3c9d5808 Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Tue, 5 Nov 2019 21:09:36 -0500 Subject: [PATCH 5/7] Add doc + more test cases --- crates/js-sys/src/lib.rs | 15 +++++++ crates/js-sys/tests/wasm/Array.rs | 72 +++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 783f0630fda..f58e939d6a7 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -4792,6 +4792,21 @@ macro_rules! arrays { ) } + /// Creates a JS typed array which is a view into wasm's linear + /// memory at the slice specified. + /// + /// This function returns a new typed array which is a view into + /// wasm's memory. This view does not copy the underlying data. + /// + /// # Unsafety + /// + /// Views into WebAssembly memory are only valid so long as the + /// backing buffer isn't resized in JS. Once this function is called + /// any future calls to `Box::new` (or malloc of any form) may cause + /// the returned value here to be invalidated. Use with caution! + /// + /// Additionally the returned object can be safely mutated, + /// the changes are guranteed to be reflected in the input array. pub unsafe fn view_mut_raw(ptr: *mut $ty, length: usize) -> $name { let buf = wasm_bindgen::memory(); let mem = buf.unchecked_ref::(); diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index 60a5b8bb2bd..a68ac62926e 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -474,7 +474,7 @@ extern "C" { } #[wasm_bindgen_test] -fn uint8array_view_mut_raw() { +fn Uint8Array_view_mut_raw_no_macro() { let start: u8 = 10; let len: usize = 32; let end: u8 = start + len as u8; @@ -493,22 +493,78 @@ fn uint8array_view_mut_raw() { assert_eq!(buffer, expected) } +macro_rules! test_view_mut_raw { + ($($name:ident $ty:ident)?) => ($( + let start: $ty = 10 as $ty; + let len: usize = 32; + let end: $ty = start + len as $ty; + let mut buffer: Vec<$ty> = Vec::new(); + buffer.reserve(len); + unsafe { + let array = js_sys::$name::view_mut_raw(buffer.as_mut_ptr(), len); + populate_array( + JsValue::from(array), + JsValue::from(start), + JsValue::from(len as u32), + ); + buffer.set_len(len); + } + let expected: Vec<$ty> = (start..end).collect(); + assert_eq!(buffer, expected) + )?); +} + +#[wasm_bindgen_test] +fn Int8Array_view_mut_raw() { + test_view_mut_raw! { Int8Array i8 } +} + +#[wasm_bindgen_test] +fn Int16Array_view_mut_raw() { + test_view_mut_raw! { Int16Array i16 } +} + +#[wasm_bindgen_test] +fn Int32Array_view_mut_raw() { + test_view_mut_raw! { Int32Array i32 } +} + +#[wasm_bindgen_test] +fn Uint8Array_view_mut_raw() { + test_view_mut_raw! { Uint8Array u8 } +} + +#[wasm_bindgen_test] +fn Uint8ClampedArray_view_mut_raw() { + test_view_mut_raw! { Uint8ClampedArray u8 } +} + +#[wasm_bindgen_test] +fn Uint16Array_view_mut_raw() { + test_view_mut_raw! { Uint16Array u16 } +} + #[wasm_bindgen_test] -fn uint32array_view_mut_raw() { - let start: u32 = 10; +fn Uint32Array_view_mut_raw() { + test_view_mut_raw! { Uint32Array u32 } +} + +#[wasm_bindgen_test] +fn Float64Array_view_mut_raw() { + let start: u8 = 10; let len: usize = 32; - let end: u32 = start + len as u32; - let mut buffer: Vec = Vec::new(); + let end: u8 = start + len as u8; + let mut buffer: Vec = Vec::new(); buffer.reserve(len); unsafe { - let array = js_sys::Uint32Array::view_mut_raw(buffer.as_mut_ptr(), len); + let array = js_sys::Float64Array::view_mut_raw(buffer.as_mut_ptr(), len); populate_array( JsValue::from(array), - JsValue::from(start), + JsValue::from(f64::from(start)), JsValue::from(len as u32), ); buffer.set_len(len); } - let expected: Vec = (start..end).collect(); + let expected: Vec = (start..end).map(f64::from).collect(); assert_eq!(buffer, expected) } From 042f9be023193e84aff211b7268bb133593833ab Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Tue, 5 Nov 2019 22:38:19 -0500 Subject: [PATCH 6/7] replacing macro-generated tests with generic test function it is cleaner, safer and better that way --- crates/js-sys/tests/wasm/Array.rs | 83 ++++++++++++------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index a68ac62926e..44050325d86 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -473,98 +473,81 @@ extern "C" { fn populate_array(arr: JsValue, start: JsValue, len: JsValue) -> JsValue; } -#[wasm_bindgen_test] -fn Uint8Array_view_mut_raw_no_macro() { +fn test_array_view_mut_raw( + sut: unsafe fn(*mut ElemT, usize) -> ArrT, + u8ToElem: fn(u8) -> ElemT, + arrToJsValue: fn(ArrT) -> JsValue, +) { let start: u8 = 10; let len: usize = 32; let end: u8 = start + len as u8; - let mut buffer: Vec = Vec::new(); + let mut buffer: Vec = Vec::new(); buffer.reserve(len); unsafe { - let array = js_sys::Uint8Array::view_mut_raw(buffer.as_mut_ptr(), len); + let array: ArrT = sut(buffer.as_mut_ptr(), len); populate_array( - JsValue::from(array), + arrToJsValue(array), JsValue::from(start), JsValue::from(len as u32), ); buffer.set_len(len); } - let expected: Vec = (start..end).collect(); + let expected: Vec = (start..end).map(u8ToElem).collect(); assert_eq!(buffer, expected) } -macro_rules! test_view_mut_raw { - ($($name:ident $ty:ident)?) => ($( - let start: $ty = 10 as $ty; - let len: usize = 32; - let end: $ty = start + len as $ty; - let mut buffer: Vec<$ty> = Vec::new(); - buffer.reserve(len); - unsafe { - let array = js_sys::$name::view_mut_raw(buffer.as_mut_ptr(), len); - populate_array( - JsValue::from(array), - JsValue::from(start), - JsValue::from(len as u32), - ); - buffer.set_len(len); - } - let expected: Vec<$ty> = (start..end).collect(); - assert_eq!(buffer, expected) - )?); -} - #[wasm_bindgen_test] fn Int8Array_view_mut_raw() { - test_view_mut_raw! { Int8Array i8 } + fn u8Toi8_unsafe(x: u8) -> i8 { + x as i8 + } + test_array_view_mut_raw( + js_sys::Int8Array::view_mut_raw, + u8Toi8_unsafe, + JsValue::from, + ); } #[wasm_bindgen_test] fn Int16Array_view_mut_raw() { - test_view_mut_raw! { Int16Array i16 } + test_array_view_mut_raw(js_sys::Int16Array::view_mut_raw, i16::from, JsValue::from); } #[wasm_bindgen_test] fn Int32Array_view_mut_raw() { - test_view_mut_raw! { Int32Array i32 } + test_array_view_mut_raw(js_sys::Int32Array::view_mut_raw, i32::from, JsValue::from); } #[wasm_bindgen_test] fn Uint8Array_view_mut_raw() { - test_view_mut_raw! { Uint8Array u8 } + test_array_view_mut_raw(js_sys::Uint8Array::view_mut_raw, u8::from, JsValue::from); } #[wasm_bindgen_test] fn Uint8ClampedArray_view_mut_raw() { - test_view_mut_raw! { Uint8ClampedArray u8 } + test_array_view_mut_raw( + js_sys::Uint8ClampedArray::view_mut_raw, + u8::from, + JsValue::from, + ); } #[wasm_bindgen_test] fn Uint16Array_view_mut_raw() { - test_view_mut_raw! { Uint16Array u16 } + test_array_view_mut_raw(js_sys::Uint16Array::view_mut_raw, u16::from, JsValue::from); } #[wasm_bindgen_test] fn Uint32Array_view_mut_raw() { - test_view_mut_raw! { Uint32Array u32 } + test_array_view_mut_raw(js_sys::Uint32Array::view_mut_raw, u32::from, JsValue::from); +} + +#[wasm_bindgen_test] +fn Float32Array_view_mut_raw() { + test_array_view_mut_raw(js_sys::Float32Array::view_mut_raw, f32::from, JsValue::from); } #[wasm_bindgen_test] fn Float64Array_view_mut_raw() { - let start: u8 = 10; - let len: usize = 32; - let end: u8 = start + len as u8; - let mut buffer: Vec = Vec::new(); - buffer.reserve(len); - unsafe { - let array = js_sys::Float64Array::view_mut_raw(buffer.as_mut_ptr(), len); - populate_array( - JsValue::from(array), - JsValue::from(f64::from(start)), - JsValue::from(len as u32), - ); - buffer.set_len(len); - } - let expected: Vec = (start..end).map(f64::from).collect(); - assert_eq!(buffer, expected) + test_array_view_mut_raw(js_sys::Float64Array::view_mut_raw, f64::from, JsValue::from); } From df0e88c9193598dd29f38a58ef8afebc992ef72e Mon Sep 17 00:00:00 2001 From: lshlyapnikov Date: Tue, 5 Nov 2019 23:06:11 -0500 Subject: [PATCH 7/7] improving rustdoc --- crates/js-sys/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index f58e939d6a7..61cf8ccfc1a 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -4793,7 +4793,7 @@ macro_rules! arrays { } /// Creates a JS typed array which is a view into wasm's linear - /// memory at the slice specified. + /// memory at the specified pointer with specified length. /// /// This function returns a new typed array which is a view into /// wasm's memory. This view does not copy the underlying data.