]> git.proxmox.com Git - rustc.git/blobdiff - vendor/wasm-bindgen/src/convert/slices.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / vendor / wasm-bindgen / src / convert / slices.rs
index 9d0970f4e6a423410c148101323084e0282cde41..58608b8c520faf77c05bc97a2fadf2123283a436 100644 (file)
@@ -1,12 +1,15 @@
 #[cfg(feature = "std")]
 use std::prelude::v1::*;
 
-use core::slice;
+use core::ops::{Deref, DerefMut};
 use core::str;
 
+use crate::__wbindgen_copy_to_typed_array;
 use crate::cast::JsObject;
 use crate::convert::OptionIntoWasmAbi;
-use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
+use crate::convert::{
+    FromWasmAbi, IntoWasmAbi, LongRefFromWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi,
+};
 use cfg_if::cfg_if;
 
 if_std! {
@@ -27,6 +30,50 @@ fn null_slice() -> WasmSlice {
     WasmSlice { ptr: 0, len: 0 }
 }
 
+if_std! {
+    #[repr(C)]
+    pub struct WasmMutSlice {
+        pub slice: WasmSlice,
+        pub idx: u32,
+    }
+
+    unsafe impl WasmAbi for WasmMutSlice {}
+
+    /// The representation of a mutable slice passed from JS to Rust.
+    pub struct MutSlice<T> {
+        /// A copy of the data in the JS typed array.
+        contents: Box<[T]>,
+        /// A reference to the original JS typed array.
+        js: JsValue,
+    }
+
+    impl<T> Drop for MutSlice<T> {
+        fn drop(&mut self) {
+            unsafe {
+                __wbindgen_copy_to_typed_array(
+                    self.contents.as_ptr() as *const u8,
+                    self.contents.len() * mem::size_of::<T>(),
+                    self.js.idx
+                );
+            }
+        }
+    }
+
+    impl<T> Deref for MutSlice<T> {
+        type Target = [T];
+
+        fn deref(&self) -> &[T] {
+            &self.contents
+        }
+    }
+
+    impl<T> DerefMut for MutSlice<T> {
+        fn deref_mut(&mut self) -> &mut [T] {
+            &mut self.contents
+        }
+    }
+}
+
 macro_rules! vectors {
     ($($t:ident)*) => ($(
         if_std! {
@@ -109,17 +156,24 @@ macro_rules! vectors {
         }
 
         impl RefMutFromWasmAbi for [$t] {
+            type Abi = WasmMutSlice;
+            type Anchor = MutSlice<$t>;
+
+            #[inline]
+            unsafe fn ref_mut_from_abi(js: WasmMutSlice) -> MutSlice<$t> {
+                let contents = <Box<[$t]>>::from_abi(js.slice);
+                let js = JsValue::from_abi(js.idx);
+                MutSlice { contents, js }
+            }
+        }
+
+        impl LongRefFromWasmAbi for [$t] {
             type Abi = WasmSlice;
-            type Anchor = &'static mut [$t];
+            type Anchor = Box<[$t]>;
 
             #[inline]
-            unsafe fn ref_mut_from_abi(js: WasmSlice)
-                -> &'static mut [$t]
-            {
-                slice::from_raw_parts_mut(
-                    <*mut $t>::from_abi(js.ptr),
-                    js.len as usize,
-                )
+            unsafe fn long_ref_from_abi(js: WasmSlice) -> Box<[$t]> {
+                Self::ref_from_abi(js)
             }
         }
     )*)
@@ -233,6 +287,16 @@ impl RefFromWasmAbi for str {
     }
 }
 
+impl LongRefFromWasmAbi for str {
+    type Abi = <[u8] as RefFromWasmAbi>::Abi;
+    type Anchor = Box<str>;
+
+    #[inline]
+    unsafe fn long_ref_from_abi(js: Self::Abi) -> Self::Anchor {
+        Self::ref_from_abi(js)
+    }
+}
+
 if_std! {
     use crate::JsValue;