Repository: denoland/deno_core
Pull request #220 (2023-09-20 14:21:56)

chore: add a test for empty slices
Will not pass until we get https://github.com/denoland/rusty_v8/pull/1326 pulled in


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 836d925..f8b3ba1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2024,9 +2024,9 @@ checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
 
 [[package]]
 name = "v8"
-version = "0.77.0"
+version = "0.78.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2c1cc5961099892fa7a60b2486cf07065c6006118bc34ae12ef18f36d0d2489"
+checksum = "f6c96f70e8fc6c009af99d4e8ac4f5e84655a0fc3ec6e58147933b9c99f8b43c"
 dependencies = [
  "bitflags 1.3.2",
  "fslock",
diff --git a/Cargo.toml b/Cargo.toml
index b5b87f2..c2a114c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,7 +21,7 @@ deno_core = { version = "0.215.0", path = "./core" }
 deno_ops = { version = "0.91.0", path = "./ops" }
 serde_v8 = { version = "0.124.0", path = "./serde_v8" }
 
-v8 = { version = "0.77.0", default-features = false }
+v8 = { version = "0.78.0", default-features = false }
 deno_ast = { version = "0.29.1", features = ["transpiling"] }
 deno_unsync = "0.3.0"
 
diff --git a/core/runtime/ops.rs b/core/runtime/ops.rs
index f059a29..4d66ccd 100644
--- a/core/runtime/ops.rs
+++ b/core/runtime/ops.rs
@@ -1506,7 +1506,9 @@ mod tests {
   ) {
     assert_eq!(inlen, input.len());
     assert_eq!(outlen, output.len());
-    output[0] = input[0];
+    if inlen > 0 && outlen > 0 {
+      output[0] = input[0];
+    }
   }
 
   #[op2(core, fast)]
@@ -1518,7 +1520,9 @@ mod tests {
   ) {
     assert_eq!(inlen, input.len());
     assert_eq!(outlen, output.len());
-    output[0] = input[0];
+    if inlen > 0 && outlen > 0 {
+      output[0] = input[0];
+    }
   }
 
   #[tokio::test]
@@ -1528,6 +1532,11 @@ mod tests {
       ("op_buffer_slice", "Uint8Array", 1),
       ("op_buffer_slice_32", "Uint32Array", 4),
     ] {
+      run_test2(
+        10000,
+        op,
+        &format!("{op}(new {arr}(0), 0, new {arr}(0), 0);"),
+      )?;
       // UintXArray -> UintXArray
       run_test2(
         10000,
diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs
index 36046ce..cab6cb8 100644
--- a/ops/op2/dispatch_fast.rs
+++ b/ops/op2/dispatch_fast.rs
@@ -317,18 +317,23 @@ fn map_v8_fastcall_arg_to_arg(
   } = generator_state;
 
   let arg_temp = format_ident!("{}_temp", arg_ident);
+  let buf = quote!((
+    // SAFETY: we are certain the implied lifetime is valid here as the slices never escape the
+    // fastcall
+    unsafe { #deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(#arg_ident) }.expect("Invalid buffer"))
+  );
   let res = match arg {
     Arg::Buffer(Buffer::Slice(_, NumericArg::u8 | NumericArg::u32)) => {
-      quote!(let #arg_ident = unsafe { #arg_ident.as_mut().unwrap() }.get_storage_if_aligned().unwrap();)
+      quote!(let #arg_ident = #buf;)
     }
     Arg::Buffer(Buffer::Vec(NumericArg::u8 | NumericArg::u32)) => {
-      quote!(let #arg_ident = unsafe { #arg_ident.as_mut().unwrap() }.get_storage_if_aligned().unwrap().to_vec();)
+      quote!(let #arg_ident = #buf.to_vec();)
     }
     Arg::Buffer(Buffer::BoxSlice(NumericArg::u8 | NumericArg::u32)) => {
-      quote!(let #arg_ident = unsafe { #arg_ident.as_mut().unwrap() }.get_storage_if_aligned().unwrap().to_vec().into_boxed_slice();)
+      quote!(let #arg_ident = #buf.to_vec().into_boxed_slice();)
     }
     Arg::Buffer(Buffer::Bytes(BufferMode::Copy)) => {
-      quote!(let #arg_ident = unsafe { #arg_ident.as_mut().unwrap() }.get_storage_if_aligned().unwrap().to_vec().into();)
+      quote!(let #arg_ident = #buf.to_vec().into();)
     }
     Arg::Ref(RefType::Ref, Special::OpState) => {
       *needs_opctx = true;


Test patch:
diff --git a/ops/op2/test_cases/sync/buffers.out b/ops/op2/test_cases/sync/buffers.out
index 4bd833f..a7dc06e 100644
--- a/ops/op2/test_cases/sync/buffers.out
+++ b/ops/op2/test_cases/sync/buffers.out
@@ -40,12 +40,18 @@ impl op_buffers {
         arg1: *mut deno_core::v8::fast_api::FastApiTypedArray<u8>,
     ) -> () {
         let result = {
-            let arg0 = unsafe { arg0.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap();
-            let arg1 = unsafe { arg1.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap();
+            let arg0 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg0,
+                )
+            }
+                .expect("Invalid buffer"));
+            let arg1 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg1,
+                )
+            }
+                .expect("Invalid buffer"));
             Self::call(arg0, arg1)
         };
         result as _
@@ -148,12 +154,18 @@ impl op_buffers_32 {
         arg1: *mut deno_core::v8::fast_api::FastApiTypedArray<u32>,
     ) -> () {
         let result = {
-            let arg0 = unsafe { arg0.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap();
-            let arg1 = unsafe { arg1.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap();
+            let arg0 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg0,
+                )
+            }
+                .expect("Invalid buffer"));
+            let arg1 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg1,
+                )
+            }
+                .expect("Invalid buffer"));
             Self::call(arg0, arg1)
         };
         result as _
diff --git a/ops/op2/test_cases/sync/buffers_copy.out b/ops/op2/test_cases/sync/buffers_copy.out
index fabb766..6245a48 100644
--- a/ops/op2/test_cases/sync/buffers_copy.out
+++ b/ops/op2/test_cases/sync/buffers_copy.out
@@ -42,18 +42,27 @@ impl op_buffers {
         arg2: *mut deno_core::v8::fast_api::FastApiTypedArray<u8>,
     ) -> () {
         let result = {
-            let arg0 = unsafe { arg0.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap()
+            let arg0 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg0,
+                )
+            }
+                .expect("Invalid buffer"))
                 .to_vec();
-            let arg1 = unsafe { arg1.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap()
+            let arg1 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg1,
+                )
+            }
+                .expect("Invalid buffer"))
                 .to_vec()
                 .into_boxed_slice();
-            let arg2 = unsafe { arg2.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap()
+            let arg2 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg2,
+                )
+            }
+                .expect("Invalid buffer"))
                 .to_vec()
                 .into();
             Self::call(arg0, arg1, arg2)
@@ -177,13 +186,19 @@ impl op_buffers_32 {
         arg1: *mut deno_core::v8::fast_api::FastApiTypedArray<u32>,
     ) -> () {
         let result = {
-            let arg0 = unsafe { arg0.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap()
+            let arg0 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg0,
+                )
+            }
+                .expect("Invalid buffer"))
                 .to_vec();
-            let arg1 = unsafe { arg1.as_mut().unwrap() }
-                .get_storage_if_aligned()
-                .unwrap()
+            let arg1 = (unsafe {
+                deno_core::v8::fast_api::FastApiTypedArray::get_storage_from_pointer_if_aligned(
+                    arg1,
+                )
+            }
+                .expect("Invalid buffer"))
                 .to_vec()
                 .into_boxed_slice();
             Self::call(arg0, arg1)