Repository: denoland/deno_core (rust)

Issue:
`op2` async numeric return values 
The async return values for `op2` are sparse. We need to ensure that all numeric return values are supported.

As part of this work, `valid_retvals.md` needs to be updated with a new column for `async` support.

Example op that we cannot port:


```
#[op2(async)]
#[bigint]
pub async fn op_cache_storage_open<CA>(
  state: Rc<RefCell<OpState>>,
  #[string] cache_name: String,
) -> Result<i64, AnyError>
```

Pull request:
feat(ops): support most return types from async functions
Fixes #139 among other things

Patch:
diff --git a/ops/op2/README.md b/ops/op2/README.md
index 05ae44c..f212d73 100644
--- a/ops/op2/README.md
+++ b/ops/op2/README.md
@@ -736,7 +736,7 @@ Extracts an object from `OpState`.
 # Return Values
 
 <!-- START RV -->
-<table><tr><th>Rust</th><th>Fastcall</th><th>v8</th></tr>
+<table><tr><th>Rust</th><th>Fastcall</th><th>Async</th><th>v8</th></tr>
 <tr>
 <td>
 
@@ -744,6 +744,8 @@ Extracts an object from `OpState`.
 bool
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -758,6 +760,8 @@ Bool
 i8
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -772,6 +776,8 @@ Int32
 u8
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -786,6 +792,8 @@ Uint32
 i16
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -800,6 +808,8 @@ Int32
 u16
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -814,6 +824,8 @@ Uint32
 i32
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -828,6 +840,8 @@ Int32
 u32
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -842,6 +856,8 @@ Uint32
 #[smi] ResourceId
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -858,6 +874,8 @@ SMI is internally represented as a signed integer, but unsigned `#[smi]` types w
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 BigInt
 </td><td>
@@ -872,6 +890,8 @@ BigInt
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 BigInt
 </td><td>
@@ -886,6 +906,8 @@ BigInt
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 BigInt
 </td><td>
@@ -900,6 +922,8 @@ BigInt
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 BigInt
 </td><td>
@@ -912,6 +936,8 @@ BigInt
 f32
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -926,6 +952,8 @@ Number
 f64
 ```
 
+</td><td>
+✅
 </td><td>
 ✅
 </td><td>
@@ -942,6 +970,8 @@ Number
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 String
 </td><td>
@@ -956,6 +986,8 @@ String
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 ArrayBuffer
 </td><td>
@@ -970,6 +1002,8 @@ ArrayBuffer
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 ArrayBuffer
 </td><td>
@@ -984,6 +1018,8 @@ ArrayBuffer
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 ArrayBuffer
 </td><td>
@@ -998,6 +1034,8 @@ ArrayBuffer
 
 </td><td>
 ✅
+</td><td>
+
 </td><td>
 External
 </td><td>
@@ -1012,6 +1050,8 @@ External
 
 </td><td>
 ✅
+</td><td>
+
 </td><td>
 External
 </td><td>
@@ -1026,6 +1066,8 @@ v8::Local<v8::Value>
 
 </td><td>
 
+</td><td>
+
 </td><td>
 any
 </td><td>
@@ -1040,6 +1082,8 @@ v8::Local<v8::String>
 
 </td><td>
 
+</td><td>
+
 </td><td>
 String
 </td><td>
@@ -1054,6 +1098,8 @@ v8::Local<v8::Object>
 
 </td><td>
 
+</td><td>
+
 </td><td>
 Object
 </td><td>
@@ -1068,6 +1114,8 @@ v8::Local<v8::Function>
 
 </td><td>
 
+</td><td>
+
 </td><td>
 Function
 </td><td>
@@ -1082,6 +1130,8 @@ v8::Local<v8::...>
 
 </td><td>
 
+</td><td>
+
 </td><td>
 ...
 </td><td>
@@ -1096,6 +1146,8 @@ v8::Local<v8::...>
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 any
 </td><td>
@@ -1110,6 +1162,8 @@ any
 
 </td><td>
 
+</td><td>
+✅
 </td><td>
 any
 </td><td>
diff --git a/ops/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs
index 154f46d..1f1ba8e 100644
--- a/ops/op2/dispatch_slow.rs
+++ b/ops/op2/dispatch_slow.rs
@@ -670,6 +670,21 @@ pub fn return_value_v8_value(
     Arg::Numeric(NumericArg::u8 | NumericArg::u16 | NumericArg::u32) => {
       quote!(Ok(#deno_core::v8::Integer::new_from_unsigned(#scope, #result).into()))
     }
+    Arg::Numeric(NumericArg::f32 | NumericArg::f64) => {
+      quote!(Ok(#deno_core::v8::Number::new(#scope, #result as _).into()))
+    }
+    Arg::Numeric(NumericArg::i64 | NumericArg::isize) => {
+      quote!(Ok(#deno_core::v8::BigInt::new_from_i64(#scope, #result as _).into()))
+    }
+    Arg::Numeric(NumericArg::u64 | NumericArg::usize) => {
+      quote!(Ok(#deno_core::v8::BigInt::new_from_u64(#scope, #result as _).into()))
+    }
+    Arg::String(Strings::String) => {
+      quote!(match #deno_core::v8::String::new(#scope, &#result) {
+        Some(s) => Ok(s.into()),
+        None => Err(#deno_core::serde_v8::Error::Message("Failed to convert string return value".into()))
+      })
+    }
     Arg::Buffer(
       Buffer::JsBuffer(BufferMode::Default)
       | Buffer::Vec(NumericArg::u8)
diff --git a/ops/op2/mod.rs b/ops/op2/mod.rs
index a948ba7..1d94d50 100644
--- a/ops/op2/mod.rs
+++ b/ops/op2/mod.rs
@@ -397,8 +397,7 @@ deno_ops_compile_test_runner::prelude!();";
 
     parse_md(md, |line, components| {
       let type_param = components.first().unwrap().to_owned();
-      let fastcall = components.get(1).unwrap().to_owned();
-      let fast = fastcall == "X";
+      let fast = components.get(1).unwrap() == &"X";
       let v8 = components.get(2).unwrap().to_owned();
       let notes = components.get(3).unwrap().to_owned();
       let (attr, ty) = if type_param.starts_with('#') {
@@ -451,14 +450,14 @@ deno_ops_compile_test_runner::prelude!();";
     let end_separator = "\n<!-- END RV -->\n";
     let readme = std::fs::read_to_string("op2/README.md").unwrap();
     let (header, remainder) = split_readme(&readme, separator, end_separator);
-    let mut actual = format!("{header}{separator}<table><tr><th>Rust</th><th>Fastcall</th><th>v8</th></tr>\n");
+    let mut actual = format!("{header}{separator}<table><tr><th>Rust</th><th>Fastcall</th><th>Async</th><th>v8</th></tr>\n");
 
     parse_md(md, |line, components| {
       let type_param = components.first().unwrap().to_owned();
-      let fastcall = components.get(1).unwrap().to_owned();
-      let fast = fastcall == "X";
-      let v8 = components.get(2).unwrap().to_owned();
-      let notes = components.get(3).unwrap().to_owned();
+      let fast = components.get(1).unwrap() == &"X";
+      let async_support = components.get(2).unwrap() == &"X";
+      let v8 = components.get(3).unwrap().to_owned();
+      let notes = components.get(4).unwrap().to_owned();
       let (attr, ty) = if type_param.starts_with('#') {
         type_param.split_once(' ').expect(
           "Expected an attribute separated by a space (ie: #[attr] type)",
@@ -482,8 +481,26 @@ deno_ops_compile_test_runner::prelude!();";
           function,
         )
         .expect("Failed to generate op");
+
+        if async_support {
+          let function = format!("{} async fn op_test() -> {} {{}}", attr, ty);
+          let function =
+            syn::parse_str::<ItemFn>(&function).expect("Failed to parse type");
+          let sig =
+            parse_signature(function.attrs.clone(), function.sig.clone())
+              .expect("Failed to parse signature");
+          println!("Parsed signature: {sig:?}");
+          generate_op2(
+            MacroConfig {
+              r#async: true,
+              ..Default::default()
+            },
+            function,
+          )
+          .expect("Failed to generate op");
+        }
       }
-      actual += &format!("<tr>\n<td>\n\n```text\n{}\n```\n\n</td><td>\n{}\n</td><td>\n{}\n</td><td>\n{}\n</td></tr>\n", type_param, if fast { "✅" } else { "" }, v8, notes);
+      actual += &format!("<tr>\n<td>\n\n```text\n{}\n```\n\n</td><td>\n{}\n</td><td>\n{}\n</td><td>\n{}\n</td><td>\n{}\n</td></tr>\n", type_param, if fast { "✅" } else { "" }, if async_support { "✅" } else { "" }, v8, notes);
     });
 
     actual += "</table>\n";
diff --git a/ops/op2/valid_retvals.md b/ops/op2/valid_retvals.md
index 62764ed..452c6c0 100644
--- a/ops/op2/valid_retvals.md
+++ b/ops/op2/valid_retvals.md
@@ -1,31 +1,31 @@
-| Supported | Rust                             | Fastcall | V8          | Notes                                                                                                                                                                                            |
-| --------- | -------------------------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| X         | bool                             | X        | Bool        |                                                                                                                                                                                                  |
-| X         | i8                               | X        | Int32       |                                                                                                                                                                                                  |
-| X         | u8                               | X        | Uint32      |                                                                                                                                                                                                  |
-| X         | i16                              | X        | Int32       |                                                                                                                                                                                                  |
-| X         | u16                              | X        | Uint32      |                                                                                                                                                                                                  |
-| X         | i32                              | X        | Int32       |                                                                                                                                                                                                  |
-| X         | u32                              | X        | Uint32      |                                                                                                                                                                                                  |
-| X         | #[smi] ResourceId                | X        | Int32       | SMI is internally represented as a signed integer, but unsigned `#[smi]` types will be bit-converted to unsigned values for the Rust call. JavaScript code will continue to see signed integers. |
-| X         | #[bigint] i64                    |          | BigInt      |                                                                                                                                                                                                  |
-| X         | #[bigint] u64                    |          | BigInt      |                                                                                                                                                                                                  |
-| X         | #[bigint] isize                  |          | BigInt      |                                                                                                                                                                                                  |
-| X         | #[bigint] usize                  |          | BigInt      |                                                                                                                                                                                                  |
-| X         | f32                              | X        | Number      |                                                                                                                                                                                                  |
-| X         | f64                              | X        | Number      |                                                                                                                                                                                                  |
-| X         | #[string] String                 |          | String      |                                                                                                                                                                                                  |
-|           | #[string] &str                   |          | String      |                                                                                                                                                                                                  |
-|           | #[string] Cow<str>               |          | String      |                                                                                                                                                                                                  |
-|           | #[string(onebyte)] Cow<[u8]>     |          | String      |                                                                                                                                                                                                  |
-| X         | #[buffer] Vec<u8>                |          | ArrayBuffer |                                                                                                                                                                                                  |
-| X         | #[buffer] Box<[u8]>              |          | ArrayBuffer |                                                                                                                                                                                                  |
-| X         | #[buffer] bytes::BytesMut        |          | ArrayBuffer |                                                                                                                                                                                                  |
-| X         | *const std::ffi::c_void          | X        | External    |                                                                                                                                                                                                  |
-| X         | *mut std::ffi::c_void            | X        | External    |                                                                                                                                                                                                  |
-| X         | v8::Local<v8::Value>             |          | any         |                                                                                                                                                                                                  |
-| X         | v8::Local<v8::**V8**>            |          | **V8**      |                                                                                                                                                                                                  |
-|           | #[global] v8::Global<v8::Value>  |          | any         |                                                                                                                                                                                                  |
-|           | #[global] v8::Global<v8::**V8**> |          | **V8**      |                                                                                                                                                                                                  |
-| X         | #[serde] SerdeType               |          | any         |                                                                                                                                                                                                  |
-| X         | #[serde] (Tuple, Tuple)          |          | any         |                                                                                                                                                                                                  |
+| Supported | Rust                             | Fastcall | Async | V8          | Notes                                                                                                                                                                                            |
+| --------- | -------------------------------- | -------- | ----- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| X         | bool                             | X        | X     | Bool        |                                                                                                                                                                                                  |
+| X         | i8                               | X        | X     | Int32       |                                                                                                                                                                                                  |
+| X         | u8                               | X        | X     | Uint32      |                                                                                                                                                                                                  |
+| X         | i16                              | X        | X     | Int32       |                                                                                                                                                                                                  |
+| X         | u16                              | X        | X     | Uint32      |                                                                                                                                                                                                  |
+| X         | i32                              | X        | X     | Int32       |                                                                                                                                                                                                  |
+| X         | u32                              | X        | X     | Uint32      |                                                                                                                                                                                                  |
+| X         | #[smi] ResourceId                | X        | X     | Int32       | SMI is internally represented as a signed integer, but unsigned `#[smi]` types will be bit-converted to unsigned values for the Rust call. JavaScript code will continue to see signed integers. |
+| X         | #[bigint] i64                    |          | X     | BigInt      |                                                                                                                                                                                                  |
+| X         | #[bigint] u64                    |          | X     | BigInt      |                                                                                                                                                                                                  |
+| X         | #[bigint] isize                  |          | X     | BigInt      |                                                                                                                                                                                                  |
+| X         | #[bigint] usize                  |          | X     | BigInt      |                                                                                                                                                                                                  |
+| X         | f32                              | X        | X     | Number      |                                                                                                                                                                                                  |
+| X         | f64                              | X        | X     | Number      |                                                                                                                                                                                                  |
+| X         | #[string] String                 |          | X     | String      |                                                                                                                                                                                                  |
+|           | #[string] &str                   |          |       | String      |                                                                                                                                                                                                  |
+|           | #[string] Cow<str>               |          |       | String      |                                                                                                                                                                                                  |
+|           | #[string(onebyte)] Cow<[u8]>     |          |       | String      |                                                                                                                                                                                                  |
+| X         | #[buffer] Vec<u8>                |          | X     | ArrayBuffer |                                                                                                                                                                                                  |
+| X         | #[buffer] Box<[u8]>              |          | X     | ArrayBuffer |                                                                                                                                                                                                  |
+| X         | #[buffer] bytes::BytesMut        |          | X     | ArrayBuffer |                                                                                                                                                                                                  |
+| X         | *const std::ffi::c_void          | X        |       | External    |                                                                                                                                                                                                  |
+| X         | *mut std::ffi::c_void            | X        |       | External    |                                                                                                                                                                                                  |
+| X         | v8::Local<v8::Value>             |          |       | any         |                                                                                                                                                                                                  |
+| X         | v8::Local<v8::**V8**>            |          |       | **V8**      |                                                                                                                                                                                                  |
+|           | #[global] v8::Global<v8::Value>  |          |       | any         |                                                                                                                                                                                                  |
+|           | #[global] v8::Global<v8::**V8**> |          |       | **V8**      |                                                                                                                                                                                                  |
+| X         | #[serde] SerdeType               |          | X     | any         |                                                                                                                                                                                                  |
+| X         | #[serde] (Tuple, Tuple)          |          | X     | any         |                                                                                                                                                                                                  |


Test patch:
diff --git a/ops/op2/test_cases/compiler_pass/async.rs b/ops/op2/test_cases/compiler_pass/async.rs
index de63161..b3db841 100644
--- a/ops/op2/test_cases/compiler_pass/async.rs
+++ b/ops/op2/test_cases/compiler_pass/async.rs
@@ -16,35 +16,46 @@ pub async fn op_async1() {}
 
 #[op2(async)]
 pub async fn op_async2(x: i32) -> i32 {
-    x
+  x
 }
 
 #[op2(async)]
 pub async fn op_async3(x: i32) -> std::io::Result<i32> {
-    Ok(x)
+  Ok(x)
 }
 
 #[op2(async)]
 pub fn op_async4(x: i32) -> Result<impl Future<Output = i32>, AnyError> {
-    Ok(async move {
-        x
-    })
+  Ok(async move {
+    x
+  })
 }
 
 #[op2(async)]
 pub fn op_async5(x: i32) -> Result<impl Future<Output = std::io::Result<i32>>, AnyError> {
-    Ok(async move {
-        Ok(x)
-    })
+  Ok(async move {
+    Ok(x)
+  })
+}
+
+#[op2(async)]
+pub async fn op_async6(x: f32) -> f32 {
+  x
 }
 
 #[op2(async)]
 pub async fn op_async_opstate(state: Rc<RefCell<OpState>>) -> std::io::Result<i32> {
-    Ok(*state.borrow().borrow::<i32>())
+  Ok(*state.borrow().borrow::<i32>())
 }
 
 #[op2(async)]
 #[buffer]
 pub async fn op_async_buffer(#[buffer] buf: JsBuffer) -> JsBuffer {
   buf
-}
\ No newline at end of file
+}
+
+#[op2(async)]
+#[string]
+pub async fn op_async_string(#[string] s: String) -> String {
+  s
+}