Repository: denoland/deno_core
Pull request #87 (2023-07-25 21:32:32)

chore(ops): Update README with #[smi] support 
Includes commits from #86


Patch:
diff --git a/ops/op2/README.md b/ops/op2/README.md
index e5f4413..e436073 100644
--- a/ops/op2/README.md
+++ b/ops/op2/README.md
@@ -144,6 +144,20 @@ Uint32, Int32, Number, BigInt
 <tr>
 <td>
 
+```rust
+#[smi] ResourceId
+```
+
+</td><td>
+✅
+</td><td>
+Uint32, Int32, Number, BigInt
+</td><td>
+
+</td></tr>
+<tr>
+<td>
+
 ```rust
 #[bigint] i64
 ```
@@ -782,6 +796,20 @@ Uint32
 <tr>
 <td>
 
+```rust
+#[smi] ResourceId
+```
+
+</td><td>
+✅
+</td><td>
+Int32
+</td><td>
+
+</td></tr>
+<tr>
+<td>
+
 ```rust
 #[bigint] i64
 ```
diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs
index 0592664..0d309da 100644
--- a/ops/op2/dispatch_fast.rs
+++ b/ops/op2/dispatch_fast.rs
@@ -471,7 +471,8 @@ fn map_retval_to_v8_fastcall_type(
     Arg::Numeric(NumericArg::u32)
     | Arg::Numeric(NumericArg::u16)
     | Arg::Numeric(NumericArg::u8) => V8FastCallType::U32,
-    Arg::Numeric(NumericArg::i32)
+    Arg::Numeric(NumericArg::__SMI__)
+    | Arg::Numeric(NumericArg::i32)
     | Arg::Numeric(NumericArg::i16)
     | Arg::Numeric(NumericArg::i8) => V8FastCallType::I32,
     Arg::Numeric(NumericArg::u64) | Arg::Numeric(NumericArg::usize) => {
diff --git a/ops/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs
index b559ad5..58c4b3a 100644
--- a/ops/op2/dispatch_slow.rs
+++ b/ops/op2/dispatch_slow.rs
@@ -522,7 +522,8 @@ pub fn return_value_infallible(
     }
     Arg::Numeric(NumericArg::i8)
     | Arg::Numeric(NumericArg::i16)
-    | Arg::Numeric(NumericArg::i32) => {
+    | Arg::Numeric(NumericArg::i32)
+    | Arg::Numeric(NumericArg::__SMI__) => {
       quote!(#retval.set_int32(#result as i32);)
     }
     Arg::Numeric(NumericArg::i64 | NumericArg::isize) => {
@@ -644,8 +645,10 @@ pub fn return_value_v8_value(
     Arg::Numeric(NumericArg::bool) => {
       quote!(Ok(#deno_core::v8::Boolean::new(#result).into()))
     }
-    Arg::Numeric(NumericArg::i8 | NumericArg::i16 | NumericArg::i32) => {
-      quote!(Ok(#deno_core::v8::Integer::new(#scope, #result).into()))
+    Arg::Numeric(
+      NumericArg::i8 | NumericArg::i16 | NumericArg::i32 | NumericArg::__SMI__,
+    ) => {
+      quote!(Ok(#deno_core::v8::Integer::new(#scope, #result as i32).into()))
     }
     Arg::Numeric(NumericArg::u8 | NumericArg::u16 | NumericArg::u32) => {
       quote!(Ok(#deno_core::v8::Integer::new_from_unsigned(#scope, #result).into()))
diff --git a/ops/op2/mod.rs b/ops/op2/mod.rs
index 3a95126..c1e9be8 100644
--- a/ops/op2/mod.rs
+++ b/ops/op2/mod.rs
@@ -472,8 +472,8 @@ deno_ops_compile_test_runner::prelude!();";
     let md = include_str!("valid_args.md");
     let separator = "\n<!-- START ARGS -->\n";
     let end_separator = "\n<!-- END ARGS -->\n";
-    let (header, remainder) =
-      split_readme(include_str!("README.md"), separator, end_separator);
+    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");
 
@@ -517,10 +517,8 @@ deno_ops_compile_test_runner::prelude!();";
       std::fs::write("op2/README.md", actual)
         .expect("Failed to write expectation file");
     } else {
-      let expected = std::fs::read_to_string("op2/README.md")
-        .expect("Failed to read expectation file");
       assert_eq!(
-        expected, actual,
+        readme, actual,
         "Failed to match expectation. Use UPDATE_EXPECTED=1."
       );
     }
@@ -533,8 +531,8 @@ deno_ops_compile_test_runner::prelude!();";
     let md = include_str!("valid_retvals.md");
     let separator = "\n<!-- START RV -->\n";
     let end_separator = "\n<!-- END RV -->\n";
-    let (header, remainder) =
-      split_readme(include_str!("README.md"), separator, end_separator);
+    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");
 
     parse_md(md, |line, components| {
@@ -578,10 +576,8 @@ deno_ops_compile_test_runner::prelude!();";
       std::fs::write("op2/README.md", actual)
         .expect("Failed to write expectation file");
     } else {
-      let expected = std::fs::read_to_string("op2/README.md")
-        .expect("Failed to read expectation file");
       assert_eq!(
-        expected, actual,
+        readme, actual,
         "Failed to match expectation. Use UPDATE_EXPECTED=1."
       );
     }
diff --git a/ops/op2/signature.rs b/ops/op2/signature.rs
index 1bfa790..26a0bff 100644
--- a/ops/op2/signature.rs
+++ b/ops/op2/signature.rs
@@ -1231,6 +1231,10 @@ mod tests {
     fn op_resource(#[smi] rid: ResourceId, #[buffer] buffer: &[u8]);
     (Numeric(__SMI__), Buffer(Slice(Ref, u8))) ->  Infallible(Void)
   );
+  test!(
+    #[smi] fn op_resource2(#[smi] rid: ResourceId) -> Result<ResourceId, Error>;
+    (Numeric(__SMI__)) -> Result(Numeric(__SMI__))
+  );
   test!(
     fn op_option_numeric_result(state: &mut OpState) -> Result<Option<u32>, AnyError>;
     (Ref(Mut, OpState)) -> Result(OptionNumeric(u32))
diff --git a/ops/op2/valid_args.md b/ops/op2/valid_args.md
index 0131155..fd46cba 100644
--- a/ops/op2/valid_args.md
+++ b/ops/op2/valid_args.md
@@ -7,6 +7,7 @@
 | X         | u16                              | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | i32                              | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | u32                              | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
+| X         | #[smi] ResourceId                | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | #[bigint] i64                    | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | #[bigint] u64                    | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
 | X         | #[bigint] isize                  | X        | Uint32, Int32, Number, BigInt                       |                                                                                                                                                                                                                |
diff --git a/ops/op2/valid_retvals.md b/ops/op2/valid_retvals.md
index bdac9e5..1dda39a 100644
--- a/ops/op2/valid_retvals.md
+++ b/ops/op2/valid_retvals.md
@@ -7,6 +7,7 @@
 | X         | u16                              | X        | Uint32 |       |
 | X         | i32                              | X        | Int32  |       |
 | X         | u32                              | X        | Uint32 |       |
+| X         | #[smi] ResourceId                | X        | Int32  |       |
 | X         | #[bigint] i64                    |          | BigInt |       |
 | X         | #[bigint] u64                    |          | BigInt |       |
 | X         | #[bigint] isize                  |          | BigInt |       |


Test patch:
diff --git a/ops/op2/test_cases/async/async_arg_return.out b/ops/op2/test_cases/async/async_arg_return.out
index 56a063b..3f01cfe 100644
--- a/ops/op2/test_cases/async/async_arg_return.out
+++ b/ops/op2/test_cases/async/async_arg_return.out
@@ -58,7 +58,9 @@ impl op_async {
                 opctx,
                 promise_id,
                 result,
-                |scope, result| { Ok(deno_core::v8::Integer::new(scope, result).into()) },
+                |scope, result| {
+                    Ok(deno_core::v8::Integer::new(scope, result as i32).into())
+                },
             ) {
             rv.set_int32(result as i32);
         }
diff --git a/ops/op2/test_cases/async/async_arg_return_result.out b/ops/op2/test_cases/async/async_arg_return_result.out
index 2bfe2a2..caf693c 100644
--- a/ops/op2/test_cases/async/async_arg_return_result.out
+++ b/ops/op2/test_cases/async/async_arg_return_result.out
@@ -58,7 +58,9 @@ impl op_async {
                 opctx,
                 promise_id,
                 result,
-                |scope, result| { Ok(deno_core::v8::Integer::new(scope, result).into()) },
+                |scope, result| {
+                    Ok(deno_core::v8::Integer::new(scope, result as i32).into())
+                },
             ) {
             match result {
                 Ok(result) => {
diff --git a/ops/op2/test_cases/async/async_opstate.out b/ops/op2/test_cases/async/async_opstate.out
index d4cb2b8..4513d8b 100644
--- a/ops/op2/test_cases/async/async_opstate.out
+++ b/ops/op2/test_cases/async/async_opstate.out
@@ -46,7 +46,9 @@ impl op_async_opstate {
                 opctx,
                 promise_id,
                 result,
-                |scope, result| { Ok(deno_core::v8::Integer::new(scope, result).into()) },
+                |scope, result| {
+                    Ok(deno_core::v8::Integer::new(scope, result as i32).into())
+                },
             ) {
             match result {
                 Ok(result) => {
diff --git a/ops/op2/test_cases/async/async_result.out b/ops/op2/test_cases/async/async_result.out
index a9ac49a..d0838e3 100644
--- a/ops/op2/test_cases/async/async_result.out
+++ b/ops/op2/test_cases/async/async_result.out
@@ -42,7 +42,9 @@ impl op_async {
                 opctx,
                 promise_id,
                 result,
-                |scope, result| { Ok(deno_core::v8::Integer::new(scope, result).into()) },
+                |scope, result| {
+                    Ok(deno_core::v8::Integer::new(scope, result as i32).into())
+                },
             ) {
             match result {
                 Ok(result) => {
diff --git a/ops/op2/test_cases/async/async_result_impl.out b/ops/op2/test_cases/async/async_result_impl.out
index 7021f0f..43bc209 100644
--- a/ops/op2/test_cases/async/async_result_impl.out
+++ b/ops/op2/test_cases/async/async_result_impl.out
@@ -72,7 +72,9 @@ impl op_async_result_impl {
                 opctx,
                 promise_id,
                 result,
-                |scope, result| { Ok(deno_core::v8::Integer::new(scope, result).into()) },
+                |scope, result| {
+                    Ok(deno_core::v8::Integer::new(scope, result as i32).into())
+                },
             ) {
             match result {
                 Ok(result) => {
diff --git a/ops/op2/test_cases/async/async_result_smi.out b/ops/op2/test_cases/async/async_result_smi.out
new file mode 100644
index 0000000..fb55b89
--- /dev/null
+++ b/ops/op2/test_cases/async/async_result_smi.out
@@ -0,0 +1,87 @@
+#[allow(non_camel_case_types)]
+pub struct op_async {
+    _unconstructable: ::std::marker::PhantomData<()>,
+}
+impl deno_core::_ops::Op for op_async {
+    const NAME: &'static str = stringify!(op_async);
+    const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl::new_internal(
+        stringify!(op_async),
+        true,
+        false,
+        false,
+        2usize as u8,
+        Self::v8_fn_ptr as _,
+        None,
+    );
+}
+impl op_async {
+    pub const fn name() -> &'static str {
+        stringify!(op_async)
+    }
+    #[deprecated(note = "Use the const op::DECL instead")]
+    pub const fn decl() -> deno_core::_ops::OpDecl {
+        <Self as deno_core::_ops::Op>::DECL
+    }
+    extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) {
+        let mut scope = unsafe { deno_core::v8::CallbackScope::new(&*info) };
+        let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe {
+            &*info
+        });
+        let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe {
+            &*info
+        });
+        let opctx = unsafe {
+            &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+                as *const deno_core::_ops::OpCtx)
+        };
+        let result = {
+            let arg0 = args.get(1usize as i32);
+            let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
+                let mut scope = unsafe { deno_core::v8::CallbackScope::new(&*info) };
+                let msg = deno_core::v8::String::new_from_one_byte(
+                        &mut scope,
+                        "expected i32".as_bytes(),
+                        deno_core::v8::NewStringType::Normal,
+                    )
+                    .unwrap();
+                let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
+                scope.throw_exception(exc);
+                return;
+            };
+            let arg0 = arg0 as _;
+            Self::call(arg0)
+        };
+        let promise_id = deno_core::_ops::to_i32_option(&args.get(0))
+            .unwrap_or_default();
+        if let Some(result)
+            = deno_core::_ops::map_async_op_fallible(
+                opctx,
+                promise_id,
+                result,
+                |scope, result| {
+                    Ok(deno_core::v8::Integer::new(scope, result as i32).into())
+                },
+            ) {
+            match result {
+                Ok(result) => {
+                    rv.set_int32(result as i32);
+                }
+                Err(err) => {
+                    let err = err.into();
+                    let opstate = ::std::cell::RefCell::borrow(&*opctx.state);
+                    let exception = deno_core::error::to_v8_error(
+                        &mut scope,
+                        opstate.get_error_class_fn,
+                        &err,
+                    );
+                    scope.throw_exception(exception);
+                    return;
+                }
+            };
+        }
+    }
+    #[inline(always)]
+    pub async fn call(rid: ResourceId) -> std::io::Result<ResourceId> {
+        Ok(rid as _)
+    }
+}
diff --git a/ops/op2/test_cases/async/async_result_smi.rs b/ops/op2/test_cases/async/async_result_smi.rs
new file mode 100644
index 0000000..f620845
--- /dev/null
+++ b/ops/op2/test_cases/async/async_result_smi.rs
@@ -0,0 +1,11 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+#![deny(warnings)]
+deno_ops_compile_test_runner::prelude!();
+
+pub type ResourceId = i16;
+
+#[op2(async)]
+#[smi]
+pub async fn op_async(#[smi] rid: ResourceId) -> std::io::Result<ResourceId> {
+    Ok(rid as _)
+}
diff --git a/ops/op2/test_cases/sync/smi.out b/ops/op2/test_cases/sync/smi.out
index a61cfca..580f4ce 100644
--- a/ops/op2/test_cases/sync/smi.out
+++ b/ops/op2/test_cases/sync/smi.out
@@ -87,3 +87,93 @@ impl op_add {
         id as u32 + extra as u32
     }
 }
+
+#[allow(non_camel_case_types)]
+struct op_subtract {
+    _unconstructable: ::std::marker::PhantomData<()>,
+}
+impl deno_core::_ops::Op for op_subtract {
+    const NAME: &'static str = stringify!(op_subtract);
+    const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl::new_internal(
+        stringify!(op_subtract),
+        false,
+        false,
+        false,
+        2usize as u8,
+        Self::v8_fn_ptr as _,
+        Some({
+            use deno_core::v8::fast_api::Type;
+            use deno_core::v8::fast_api::CType;
+            deno_core::v8::fast_api::FastFunction::new_with_bigint(
+                &[Type::V8Value, Type::Int32, Type::Int32],
+                CType::Int32,
+                Self::v8_fn_ptr_fast as *const ::std::ffi::c_void,
+            )
+        }),
+    );
+}
+impl op_subtract {
+    pub const fn name() -> &'static str {
+        stringify!(op_subtract)
+    }
+    #[deprecated(note = "Use the const op::DECL instead")]
+    pub const fn decl() -> deno_core::_ops::OpDecl {
+        <Self as deno_core::_ops::Op>::DECL
+    }
+    fn v8_fn_ptr_fast(
+        _: deno_core::v8::Local<deno_core::v8::Object>,
+        arg0: i32,
+        arg1: i32,
+    ) -> i32 {
+        let result = {
+            let arg0 = arg0 as _;
+            let arg1 = arg1 as _;
+            Self::call(arg0, arg1)
+        };
+        result
+    }
+    extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) {
+        let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe {
+            &*info
+        });
+        let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe {
+            &*info
+        });
+        let result = {
+            let arg0 = args.get(0usize as i32);
+            let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
+                let mut scope = unsafe { deno_core::v8::CallbackScope::new(&*info) };
+                let msg = deno_core::v8::String::new_from_one_byte(
+                        &mut scope,
+                        "expected i32".as_bytes(),
+                        deno_core::v8::NewStringType::Normal,
+                    )
+                    .unwrap();
+                let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
+                scope.throw_exception(exc);
+                return;
+            };
+            let arg0 = arg0 as _;
+            let arg1 = args.get(1usize as i32);
+            let Some(arg1) = deno_core::_ops::to_i32_option(&arg1) else {
+                let mut scope = unsafe { deno_core::v8::CallbackScope::new(&*info) };
+                let msg = deno_core::v8::String::new_from_one_byte(
+                        &mut scope,
+                        "expected i32".as_bytes(),
+                        deno_core::v8::NewStringType::Normal,
+                    )
+                    .unwrap();
+                let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
+                scope.throw_exception(exc);
+                return;
+            };
+            let arg1 = arg1 as _;
+            Self::call(arg0, arg1)
+        };
+        rv.set_int32(result as i32);
+    }
+    #[inline(always)]
+    fn call(id: StubId, extra: i32) -> StubId {
+        id - extra
+    }
+}
diff --git a/ops/op2/test_cases/sync/smi.rs b/ops/op2/test_cases/sync/smi.rs
index 22db30d..2bb1ca2 100644
--- a/ops/op2/test_cases/sync/smi.rs
+++ b/ops/op2/test_cases/sync/smi.rs
@@ -8,3 +8,11 @@ pub type ResourceId = i16;
 fn op_add(#[smi] id: ResourceId, extra: u16) -> u32 {
     id as u32 + extra as u32
 }
+
+pub type StubId = i32;
+
+#[op2(fast)]
+#[smi]
+fn op_subtract(#[smi] id: StubId, extra: i32) -> StubId {
+    id - extra
+}