Repository: denoland/deno_core
Pull request #35 (2023-07-12 21:35:20)

feat(op2): Remove support for &mut v8, add support for f32/f64
Cleanup PR to ensure that already-implemented ops are working as expected:

 - `&mut v8:...` is not a valid type at this time
 - `f32` and `f64` were missing support
 - Add extensive tests for transmutation
 - Fix doc bugs



Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 87c5fb5..1b7faa0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -93,15 +93,6 @@ version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
 
-[[package]]
-name = "basic-toml"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1"
-dependencies = [
- "serde",
-]
-
 [[package]]
 name = "bencher"
 version = "0.1.5"
@@ -236,7 +227,7 @@ checksum = "3c65c2ffdafc1564565200967edc4851c7b55422d3913466688907efd05ea26f"
 dependencies = [
  "deno-proc-macro-rules-macros",
  "proc-macro2",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -248,7 +239,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -341,10 +332,9 @@ dependencies = [
  "strum",
  "strum_macros",
  "syn 1.0.109",
- "syn 2.0.18",
+ "syn 2.0.22",
  "testing_macros",
  "thiserror",
- "trybuild",
  "v8",
 ]
 
@@ -492,7 +482,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -958,7 +948,7 @@ checksum = "d1fef411b303e3e12d534fb6e7852de82da56edd937d895125821fb7c09436c7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -992,7 +982,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1026,7 +1016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
 dependencies = [
  "proc-macro2",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1235,7 +1225,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1409,24 +1399,24 @@ dependencies = [
 
 [[package]]
 name = "strum"
-version = "0.24.1"
+version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
+checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
 dependencies = [
  "strum_macros",
 ]
 
 [[package]]
 name = "strum_macros"
-version = "0.24.3"
+version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
+checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232"
 dependencies = [
  "heck",
  "proc-macro2",
  "quote",
  "rustversion",
- "syn 1.0.109",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1783,24 +1773,15 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.18"
+version = "2.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
+checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-ident",
 ]
 
-[[package]]
-name = "termcolor"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
-dependencies = [
- "winapi-util",
-]
-
 [[package]]
 name = "testing_macros"
 version = "0.2.11"
@@ -1815,7 +1796,7 @@ dependencies = [
  "quote",
  "regex",
  "relative-path",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1844,7 +1825,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1890,7 +1871,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1930,7 +1911,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1952,21 +1933,6 @@ dependencies = [
  "stable_deref_trait",
 ]
 
-[[package]]
-name = "trybuild"
-version = "1.0.80"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a"
-dependencies = [
- "basic-toml",
- "glob",
- "once_cell",
- "serde",
- "serde_derive",
- "serde_json",
- "termcolor",
-]
-
 [[package]]
 name = "typed-arena"
 version = "2.0.2"
@@ -2075,15 +2041,6 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
 [[package]]
 name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
diff --git a/Cargo.toml b/Cargo.toml
index 0dff841..6f0f359 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,8 +42,8 @@ serde_bytes = "0.11"
 serde_json = "1.0.85"
 sha2 = { version = "0.10.6", features = ["oid"] }
 smallvec = "1.8"
-strum = { version = "0.24", features = ["derive"] }
-strum_macros = "0.24"
+strum = { version = "0.25.0", features = ["derive"] }
+strum_macros = "0.25.0"
 tempfile = "3.4.0"
 thiserror = "1.0.40"
 tokio = { version = "1.28.1", features = ["full"] }
@@ -56,7 +56,7 @@ url = { version = "2.3.1", features = ["serde", "expose_internals"] }
 proc-macro2 = "1"
 quote = "1"
 syn = { version = "1", features = ["full", "extra-traits"] }
-syn2 = { package = "syn", version = "=2.0.18", features = ["full", "extra-traits"] }
+syn2 = { package = "syn", version = "=2.0.22", features = ["full", "extra-traits"] }
 # Temporary fork while we wait for a more modern version to be published
 deno-proc-macro-rules = "0.3.2"
 
diff --git a/core/runtime/ops.rs b/core/runtime/ops.rs
index 0c339ba..14dc5c5 100644
--- a/core/runtime/ops.rs
+++ b/core/runtime/ops.rs
@@ -147,7 +147,7 @@ macro_rules! try_number {
   ($n:ident $type:ident $is:ident) => {
     if $n.$is() {
       // SAFETY: v8 handles can be transmuted
-      let n: &v8::Uint32 = unsafe { std::mem::transmute($n) };
+      let n: &v8::$type = unsafe { std::mem::transmute($n) };
       return n.value() as _;
     }
   };
@@ -177,7 +177,6 @@ pub fn to_i32(number: &v8::Value) -> i32 {
   0
 }
 
-#[allow(unused)]
 pub fn to_u64(number: &v8::Value) -> u32 {
   try_number!(number Uint32 is_uint32);
   try_number!(number Int32 is_int32);
@@ -190,7 +189,6 @@ pub fn to_u64(number: &v8::Value) -> u32 {
   0
 }
 
-#[allow(unused)]
 pub fn to_i64(number: &v8::Value) -> i32 {
   try_number!(number Uint32 is_uint32);
   try_number!(number Int32 is_int32);
@@ -203,6 +201,30 @@ pub fn to_i64(number: &v8::Value) -> i32 {
   0
 }
 
+pub fn to_f32(number: &v8::Value) -> f32 {
+  try_number!(number Uint32 is_uint32);
+  try_number!(number Int32 is_int32);
+  try_number!(number Number is_number);
+  if number.is_big_int() {
+    // SAFETY: v8 handles can be transmuted
+    let n: &v8::BigInt = unsafe { std::mem::transmute(number) };
+    return n.i64_value().0 as _;
+  }
+  0.0
+}
+
+pub fn to_f64(number: &v8::Value) -> f64 {
+  try_number!(number Uint32 is_uint32);
+  try_number!(number Int32 is_int32);
+  try_number!(number Number is_number);
+  if number.is_big_int() {
+    // SAFETY: v8 handles can be transmuted
+    let n: &v8::BigInt = unsafe { std::mem::transmute(number) };
+    return n.i64_value().0 as _;
+  }
+  0.0
+}
+
 /// Expands `inbuf` to `outbuf`, assuming that `outbuf` has at least 2x `input_length`.
 #[inline(always)]
 unsafe fn latin1_to_utf8(
@@ -401,6 +423,8 @@ mod tests {
       op_test_result_primitive_err,
       op_test_bool,
       op_test_bool_result,
+      op_test_float,
+      op_test_float_result,
       op_test_string_owned,
       op_test_string_ref,
       op_test_string_cow,
@@ -494,17 +518,28 @@ mod tests {
   }
 
   #[op2(core, fast)]
-  pub fn op_test_add(a: u32, b: u32) -> u32 {
-    a + b
+  pub fn op_test_add(a: u32, b: i32) -> u32 {
+    (a as i32 + b) as u32
   }
 
+  /// Test various numeric coercions in fast and slow mode.
   #[tokio::test(flavor = "current_thread")]
   pub async fn test_op_add() -> Result<(), Box<dyn std::error::Error>> {
-    Ok(run_test2(
+    run_test2(10000, "op_test_add", "assert(op_test_add(1, 11) == 12)")?;
+    run_test2(10000, "op_test_add", "assert(op_test_add(11, -1) == 10)")?;
+    run_test2(10000, "op_test_add", "assert(op_test_add(1.5, 11.5) == 12)")?;
+    run_test2(10000, "op_test_add", "assert(op_test_add(11.5, -1) == 10)")?;
+    run_test2(
       10000,
       "op_test_add",
-      "assert(op_test_add(1, 11) == 12)",
-    )?)
+      "assert(op_test_add(4096n, 4096n) == 4096 + 4096)",
+    )?;
+    run_test2(
+      10000,
+      "op_test_add",
+      "assert(op_test_add(8192n, -4096n) == 4096)",
+    )?;
+    Ok(())
   }
 
   #[op2(core)]
@@ -644,6 +679,37 @@ mod tests {
     Ok(())
   }
 
+  #[op2(core, fast)]
+  pub fn op_test_float(a: f32, b: f64) -> f32 {
+    a + b as f32
+  }
+
+  #[op2(core, fast)]
+  pub fn op_test_float_result(a: f32, b: f64) -> Result<f64, AnyError> {
+    let a = a as f64;
+    if a + b >= 0. {
+      Ok(a + b)
+    } else {
+      Err(generic_error("negative!!!"))
+    }
+  }
+
+  #[tokio::test]
+  pub async fn test_op_float() -> Result<(), Box<dyn std::error::Error>> {
+    run_test2(10000, "op_test_float", "assert(op_test_float(1, 10) == 11)")?;
+    run_test2(
+      10000,
+      "op_test_float_result",
+      "assert(op_test_float_result(1, 10) == 11)",
+    )?;
+    run_test2(
+      1,
+      "op_test_float_result",
+      "try { op_test_float_result(-1, -1); assert(false) } catch (e) {}",
+    )?;
+    Ok(())
+  }
+
   #[op2(core, fast)]
   pub fn op_test_string_owned(#[string] s: String) -> u32 {
     s.len() as _
diff --git a/ops/Cargo.toml b/ops/Cargo.toml
index 3f0297f..f4bf41d 100644
--- a/ops/Cargo.toml
+++ b/ops/Cargo.toml
@@ -33,5 +33,4 @@ v8.workspace = true
 [dev-dependencies]
 pretty_assertions.workspace = true
 prettyplease = "0.2.9"
-testing_macros = "0.2.7"
-trybuild = "1.0.71"
+testing_macros = "0.2.11"
diff --git a/ops/op2/README.md b/ops/op2/README.md
index 9490447..a7982d9 100644
--- a/ops/op2/README.md
+++ b/ops/op2/README.md
@@ -149,55 +149,27 @@ Uint32, Int32, Number, BigInt
 <td>
 
 ```rust
-#[string] String
-```
-
-</td><td>
-✅
-</td><td>
-String
-</td><td>
-Fastcall available only if string is Latin-1. Will always create an allocated, UTF-8 copy of the String data.
-</td></tr>
-<tr>
-<td>
-
-```rust
-#[string] &str
+f32
 ```
 
 </td><td>
 ✅
 </td><td>
-String
+Uint32, Int32, Number, BigInt
 </td><td>
-Fastcall available only if string is Latin-1. Will create an owned `String` copy of the String data if it doesn't fit on the stack. Will never allocate in a fastcall, but will copy Latin-1 -> UTF-8.
-</td></tr>
-<tr>
-<td>
 
-```rust
-#[string] Cow<str>
-```
-
-</td><td>
-✅
-</td><td>
-String
-</td><td>
-Fastcall available only if string is Latin-1. Will create a `Cow::Owned` copy of the String data if it doesn't fit on the stack. Will always be `Cow::Borrowed` in a fastcall, but will copy Latin-1 -> UTF-8.
 </td></tr>
 <tr>
 <td>
 
 ```rust
-&v8::Value
+f64
 ```
 
 </td><td>
 ✅
 </td><td>
-any
+Uint32, Int32, Number, BigInt
 </td><td>
 
 </td></tr>
@@ -205,7 +177,7 @@ any
 <td>
 
 ```rust
-&v8::String
+#[string] String
 ```
 
 </td><td>
@@ -213,55 +185,41 @@ any
 </td><td>
 String
 </td><td>
-
-</td></tr>
-<tr>
-<td>
-
-```rust
-&v8::Object
-```
-
-</td><td>
-✅
-</td><td>
-Object
-</td><td>
-
+Fastcall available only if string is Latin-1. Will always create an allocated, UTF-8 copy of the String data.
 </td></tr>
 <tr>
 <td>
 
 ```rust
-&v8::Function
+#[string] &str
 ```
 
 </td><td>
 ✅
 </td><td>
-Function
+String
 </td><td>
-
+Fastcall available only if string is Latin-1. Will create an owned `String` copy of the String data if it doesn't fit on the stack. Will never allocate in a fastcall, but will copy Latin-1 -> UTF-8.
 </td></tr>
 <tr>
 <td>
 
 ```rust
-&v8::...
+#[string] Cow<str>
 ```
 
 </td><td>
 ✅
 </td><td>
-...
+String
 </td><td>
-
+Fastcall available only if string is Latin-1. Will create a `Cow::Owned` copy of the String data if it doesn't fit on the stack. Will always be `Cow::Borrowed` in a fastcall, but will copy Latin-1 -> UTF-8.
 </td></tr>
 <tr>
 <td>
 
 ```rust
-&mut v8::Value
+&v8::Value
 ```
 
 </td><td>
@@ -275,7 +233,7 @@ any
 <td>
 
 ```rust
-&mut v8::String
+&v8::String
 ```
 
 </td><td>
@@ -289,7 +247,7 @@ String
 <td>
 
 ```rust
-&mut v8::Object
+&v8::Object
 ```
 
 </td><td>
@@ -303,7 +261,7 @@ Object
 <td>
 
 ```rust
-&mut v8::Function
+&v8::Function
 ```
 
 </td><td>
@@ -317,7 +275,7 @@ Function
 <td>
 
 ```rust
-&mut v8::...
+&v8::...
 ```
 
 </td><td>
@@ -463,7 +421,7 @@ UInt8Array (resizable=true,false)
 </td><td>
 ✅
 </td><td>
-ArrayBuffer, ArrayBufferView, SharedArrayBuffer
+UInt8Array (resizable=true,false)
 </td><td>
 Safe, but forces a copy.
 </td></tr>
@@ -477,7 +435,7 @@ Safe, but forces a copy.
 </td><td>
 ✅
 </td><td>
-ArrayBuffer, ArrayBufferView, SharedArrayBuffer
+UInt8Array (resizable=true,false)
 </td><td>
 Safe, but forces a copy.
 </td></tr>
@@ -491,7 +449,7 @@ Safe, but forces a copy.
 </td><td>
 ✅
 </td><td>
-ArrayBuffer, ArrayBufferView, SharedArrayBuffer
+UInt8Array (resizable=true,false)
 </td><td>
 Safe, but forces a copy.
 </td></tr>
diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs
index a23c246..9b8e50b 100644
--- a/ops/op2/dispatch_fast.rs
+++ b/ops/op2/dispatch_fast.rs
@@ -414,10 +414,10 @@ fn map_arg_to_v8_fastcall_type(
     // We don't support v8 global arguments
     Arg::V8Global(_) => return Ok(None),
     // We don't support v8 type arguments
-    Arg::V8Ref(..)
+    Arg::V8Ref(RefType::Ref, _)
     | Arg::V8Local(_)
     | Arg::OptionV8Local(_)
-    | Arg::OptionV8Ref(..) => V8FastCallType::V8Value,
+    | Arg::OptionV8Ref(RefType::Ref, _) => V8FastCallType::V8Value,
 
     Arg::Numeric(NumericArg::bool) => V8FastCallType::Bool,
     Arg::Numeric(NumericArg::u32)
@@ -433,6 +433,8 @@ fn map_arg_to_v8_fastcall_type(
     Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => {
       V8FastCallType::I64
     }
+    Arg::Numeric(NumericArg::f32) => V8FastCallType::F32,
+    Arg::Numeric(NumericArg::f64) => V8FastCallType::F64,
     // Ref strings that are one byte internally may be passed as a SeqOneByteString,
     // which gives us a FastApiOneByteString.
     Arg::Special(Special::RefStr) => V8FastCallType::SeqOneByteString,
@@ -464,6 +466,8 @@ fn map_retval_to_v8_fastcall_type(
     Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => {
       V8FastCallType::I64
     }
+    Arg::Numeric(NumericArg::f32) => V8FastCallType::F32,
+    Arg::Numeric(NumericArg::f64) => V8FastCallType::F64,
     // We don't return special return types
     Arg::Option(_) => return Ok(None),
     Arg::Special(_) => return Ok(None),
diff --git a/ops/op2/dispatch_shared.rs b/ops/op2/dispatch_shared.rs
index f8ad474..562dab2 100644
--- a/ops/op2/dispatch_shared.rs
+++ b/ops/op2/dispatch_shared.rs
@@ -12,7 +12,7 @@ use quote::quote;
 pub fn v8_intermediate_to_arg(i: &Ident, arg: &Arg) -> TokenStream {
   let arg = match arg {
     Arg::V8Ref(RefType::Ref, _) => quote!(&#i),
-    Arg::V8Ref(RefType::Mut, _) => quote!(&mut #i),
+    Arg::V8Ref(RefType::Mut, _) => quote!(::std::ops::DerefMut::deref_mut(#i)),
     Arg::V8Local(_) => quote!(#i),
     Arg::OptionV8Ref(RefType::Ref, _) => {
       quote!(match &#i { None => None, Some(v) => Some(::std::ops::Deref::deref(v)) })
diff --git a/ops/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs
index e63f5ea..467572d 100644
--- a/ops/op2/dispatch_slow.rs
+++ b/ops/op2/dispatch_slow.rs
@@ -229,6 +229,16 @@ pub fn from_arg(
         let #arg_ident = #deno_core::_ops::to_i64(&#arg_ident) as _;
       }
     }
+    Arg::Numeric(NumericArg::f32) => {
+      quote! {
+        let #arg_ident = #deno_core::_ops::to_f32(&#arg_ident) as _;
+      }
+    }
+    Arg::Numeric(NumericArg::f64) => {
+      quote! {
+        let #arg_ident = #deno_core::_ops::to_f64(&#arg_ident) as _;
+      }
+    }
     Arg::OptionNumeric(numeric) => {
       // Ends the borrow of generator_state
       let arg_ident = arg_ident.clone();
@@ -328,8 +338,8 @@ pub fn from_arg(
     }
     Arg::V8Local(v8)
     | Arg::OptionV8Local(v8)
-    | Arg::V8Ref(_, v8)
-    | Arg::OptionV8Ref(_, v8) => {
+    | Arg::V8Ref(RefType::Ref, v8)
+    | Arg::OptionV8Ref(RefType::Ref, v8) => {
       let arg_ident = arg_ident.clone();
       let deno_core = deno_core.clone();
       let throw_type_error =
@@ -484,6 +494,10 @@ pub fn return_value_infallible(
       *needs_retval = true;
       quote!(#retval.set_int32(#result as i32);)
     }
+    Arg::Numeric(NumericArg::f32 | NumericArg::f64) => {
+      *needs_retval = true;
+      quote!(#retval.set_double(#result as _);)
+    }
     Arg::Special(Special::String) => {
       *needs_retval = true;
       *needs_scope = true;
diff --git a/ops/op2/valid_args.md b/ops/op2/valid_args.md
index 5d8436c..662edd5 100644
--- a/ops/op2/valid_args.md
+++ b/ops/op2/valid_args.md
@@ -9,24 +9,22 @@
 | X         | u32                            | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | isize                          | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | usize                          | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
-|           | f32                            | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
-|           | f64                            | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
+| X         | f32                            | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
+| X         | f64                            | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | #[string] String               | X        | String                                              | Fastcall available only if string is Latin-1. Will always create an allocated, UTF-8 copy of the String data.                                                                                                  |
 | X         | #[string] &str                 | X        | String                                              | Fastcall available only if string is Latin-1. Will create an owned `String` copy of the String data if it doesn't fit on the stack. Will never allocate in a fastcall, but will copy Latin-1 -> UTF-8.         |
 | X         | #[string] Cow<str>             | X        | String                                              | Fastcall available only if string is Latin-1. Will create a `Cow::Owned` copy of the String data if it doesn't fit on the stack. Will always be `Cow::Borrowed` in a fastcall, but will copy Latin-1 -> UTF-8. |
 | X         | &v8::Value                     | X        | any                                                 |                                                                                                                                                                                                                |
 | X         | &v8::**V8**                    | X        | **V8**                                              |                                                                                                                                                                                                                |
-| X         | &mut v8::Value                 | X        | any                                                 |                                                                                                                                                                                                                |
-| X         | &mut v8::**V8**                | X        | **V8**                                              |                                                                                                                                                                                                                |
 | X         | v8::Local<v8::Value>           | X        | any                                                 |                                                                                                                                                                                                                |
 | X         | v8::Local<v8::**V8**>          | X        | **V8**                                              |                                                                                                                                                                                                                |
 | X         | #[serde] SerdeType             |          | any                                                 | ⚠️ May be slow.                                                                                                                                                                                                 |
 | X         | #[serde] (Tuple, Tuple)        |          | any                                                 | ⚠️ May be slow.                                                                                                                                                                                                 |
 | X         | #[buffer] &mut [u8]            | X        | UInt8Array (resizable=true,false)                   | ⚠️ JS may modify the contents of the slice if V8 is called re-entrantly.                                                                                                                                        |
 | X         | #[buffer] &[u8]                | X        | UInt8Array (resizable=true,false)                   | ⚠️ JS may modify the contents of the slice if V8 is called re-entrantly.                                                                                                                                        |
-| X         | #[buffer(copy)] Vec<u8>        | X        | ArrayBuffer, ArrayBufferView, SharedArrayBuffer     | Safe, but forces a copy.                                                                                                                                                                                       |
-| X         | #[buffer(copy)] Box<[u8]>      | X        | ArrayBuffer, ArrayBufferView, SharedArrayBuffer     | Safe, but forces a copy.                                                                                                                                                                                       |
-| X         | #[buffer(copy)] bytes::Bytes   | X        | ArrayBuffer, ArrayBufferView, SharedArrayBuffer     | Safe, but forces a copy.                                                                                                                                                                                       |
+| X         | #[buffer(copy)] Vec<u8>        | X        | UInt8Array (resizable=true,false)                   | Safe, but forces a copy.                                                                                                                                                                                       |
+| X         | #[buffer(copy)] Box<[u8]>      | X        | UInt8Array (resizable=true,false)                   | Safe, but forces a copy.                                                                                                                                                                                       |
+| X         | #[buffer(copy)] bytes::Bytes   | X        | UInt8Array (resizable=true,false)                   | Safe, but forces a copy.                                                                                                                                                                                       |
 |           | #[buffer] V8Slice              | X        | ArrayBuffer, ArrayBufferView (resizable=false)      | ⚠️ JS may modify the contents of slices obtained from buffer.                                                                                                                                                   |
 |           | #[buffer(detach)] V8Slice      | X        | ArrayBuffer, ArrayBufferView (resizable=true,false) | Safe.                                                                                                                                                                                                          |
 |           | #[buffer] V8ResizableSlice     | X        | ArrayBuffer, ArrayBufferView (resizable=true)       | ⚠️ JS may modify the contents of slices obtained from buffer.                                                                                                                                                   |


Test patch:
diff --git a/ops/op2/test_cases/sync/v8_ref_option.out b/ops/op2/test_cases/sync/v8_ref_option.out
index bb083cd..968518f 100644
--- a/ops/op2/test_cases/sync/v8_ref_option.out
+++ b/ops/op2/test_cases/sync/v8_ref_option.out
@@ -53,7 +53,7 @@ impl op_v8_lifetime {
     };
         let arg1 = match &arg1 {
             None => None,
-            Some(v) => Some(::std::ops::DerefMut::deref_mut(v)),
+            Some(v) => Some(::std::ops::Deref::deref(v)),
         };
         let result = Self::call(arg0, arg1);
         result
@@ -98,10 +98,10 @@ impl op_v8_lifetime {
     };
         let arg1 = match &arg1 {
             None => None,
-            Some(v) => Some(::std::ops::DerefMut::deref_mut(v)),
+            Some(v) => Some(::std::ops::Deref::deref(v)),
         };
         let result = Self::call(arg0, arg1);
     }
     #[inline(always)]
-    pub fn call<'s>(s: Option<&v8::String>, s2: Option<&mut v8::String>) {}
+    pub fn call<'s>(s: Option<&v8::String>, s2: Option<&v8::String>) {}
 }
diff --git a/ops/op2/test_cases/sync/v8_ref_option.rs b/ops/op2/test_cases/sync/v8_ref_option.rs
index 863a04c..eec0146 100644
--- a/ops/op2/test_cases/sync/v8_ref_option.rs
+++ b/ops/op2/test_cases/sync/v8_ref_option.rs
@@ -1,5 +1,5 @@
 // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
 
 #[op2(fast)]
-pub fn op_v8_lifetime<'s>(s: Option<&v8::String>, s2: Option<&mut v8::String>) {}
+pub fn op_v8_lifetime<'s>(s: Option<&v8::String>, s2: Option<&v8::String>) {}