diff --git a/CHANGELOG.md b/CHANGELOG.md index 3402f7ae975..afdbc73f5eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ ## Unreleased +### Added + +* Add a `copy_to_uninit()` method to all `TypedArray`s. It takes `&mut [MaybeUninit]` and returns `&mut [T]`. + [#4340](https://github.com/rustwasm/wasm-bindgen/pull/4340) + ### Changed * Optional parameters are now typed as `T | undefined | null` to reflect the actual JS behavior. diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index aa2f3a07b3b..e8588bdc24a 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -32,7 +32,7 @@ use core::convert::{self, Infallible, TryFrom}; use core::f64; use core::fmt; use core::iter::{self, Product, Sum}; -use core::mem; +use core::mem::{self, MaybeUninit}; use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub}; use core::str; use core::str::FromStr; @@ -6336,6 +6336,23 @@ macro_rules! arrays { unsafe { self.raw_copy_to_ptr(dst.as_mut_ptr()); } } + /// Copy the contents of this JS typed array into the destination + /// Rust slice. + /// + /// This function will efficiently copy the memory from a typed + /// array into this Wasm module's own linear memory, initializing + /// the memory destination provided. + /// + /// # Panics + /// + /// This function will panic if this typed array's length is + /// different than the length of the provided `dst` array. + pub fn copy_to_uninit<'dst>(&self, dst: &'dst mut [MaybeUninit<$ty>]) -> &'dst mut [$ty] { + core::assert_eq!(self.length() as usize, dst.len()); + unsafe { self.raw_copy_to_ptr(dst.as_mut_ptr().cast()); } + unsafe { &mut *(dst as *mut [MaybeUninit<$ty>] as *mut [$ty]) } + } + /// Copy the contents of the source Rust slice into this /// JS typed array. /// diff --git a/crates/js-sys/tests/wasm/TypedArray.rs b/crates/js-sys/tests/wasm/TypedArray.rs index 36459696d68..262021255ac 100644 --- a/crates/js-sys/tests/wasm/TypedArray.rs +++ b/crates/js-sys/tests/wasm/TypedArray.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use js_sys::*; use wasm_bindgen::prelude::*; use wasm_bindgen_test::*; @@ -174,6 +176,17 @@ fn copy_to() { } } +#[wasm_bindgen_test] +fn copy_to_uninit() { + let mut x = [MaybeUninit::uninit(); 10]; + let array = Int32Array::new(&10.into()); + array.fill(5, 0, 10); + let x = array.copy_to_uninit(&mut x); + for i in x.iter() { + assert_eq!(*i, 5); + } +} + #[wasm_bindgen_test] fn copy_from() { let x = [1, 2, 3];