Repository: denoland/deno_core
Pull request #19 (2023-07-07 18:26:06)

feat(ops): bool results for fast and slow


Patch:
diff --git a/core/runtime/ops.rs b/core/runtime/ops.rs
index a02750d..44e9208 100644
--- a/core/runtime/ops.rs
+++ b/core/runtime/ops.rs
@@ -320,6 +320,8 @@ mod tests {
       op_test_result_void_err,
       op_test_result_primitive_ok,
       op_test_result_primitive_err,
+      op_test_bool,
+      op_test_bool_result,
       op_test_string_owned,
       op_test_string_ref,
       op_test_string_cow,
@@ -513,6 +515,40 @@ mod tests {
     Ok(())
   }
 
+  #[op2(core, fast)]
+  pub fn op_test_bool(b: bool) -> bool {
+    b
+  }
+
+  #[op2(core, fast)]
+  pub fn op_test_bool_result(b: bool) -> Result<bool, AnyError> {
+    if b {
+      Ok(true)
+    } else {
+      Err(generic_error("false!!!"))
+    }
+  }
+
+  #[tokio::test]
+  pub async fn test_op_bool() -> Result<(), Box<dyn std::error::Error>> {
+    run_test2(
+      10000,
+      "op_test_bool",
+      "assert(op_test_bool(true) === true && op_test_bool(false) === false)",
+    )?;
+    run_test2(
+      10000,
+      "op_test_bool_result",
+      "assert(op_test_bool_result(true) === true)",
+    )?;
+    run_test2(
+      1,
+      "op_test_bool_result",
+      "try { op_test_bool_result(false); 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/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs
index 4708037..6363217 100644
--- a/ops/op2/dispatch_slow.rs
+++ b/ops/op2/dispatch_slow.rs
@@ -369,6 +369,10 @@ pub fn return_value_infallible(
     Arg::Void => {
       quote! {/* void */}
     }
+    Arg::Numeric(NumericArg::bool) => {
+      *needs_retval = true;
+      quote!(#retval.set_bool(#result as bool);)
+    }
     Arg::Numeric(NumericArg::u8)
     | Arg::Numeric(NumericArg::u16)
     | Arg::Numeric(NumericArg::u32) => {


Test patch:
diff --git a/ops/op2/test_cases/sync/bool.out b/ops/op2/test_cases/sync/bool.out
new file mode 100644
index 0000000..f9ca48f
--- /dev/null
+++ b/ops/op2/test_cases/sync/bool.out
@@ -0,0 +1,72 @@
+#[allow(non_camel_case_types)]
+pub struct op_bool {
+    _unconstructable: ::std::marker::PhantomData<()>,
+}
+impl deno_core::_ops::Op for op_bool {
+    const NAME: &'static str = stringify!(op_bool);
+    const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl {
+        name: stringify!(op_bool),
+        v8_fn_ptr: Self::v8_fn_ptr as _,
+        enabled: true,
+        fast_fn: Some({
+            use deno_core::v8::fast_api::Type;
+            use deno_core::v8::fast_api::CType;
+            deno_core::v8::fast_api::FastFunction::new(
+                &[Type::V8Value, Type::Bool],
+                CType::Bool,
+                Self::v8_fn_ptr_fast as *const ::std::ffi::c_void,
+            )
+        }),
+        is_async: false,
+        is_unstable: false,
+        is_v8: false,
+        arg_count: 1usize as u8,
+    };
+}
+impl op_bool {
+    pub const fn name() -> &'static str {
+        stringify!(op_bool)
+    }
+    pub const fn decl() -> deno_core::_ops::OpDecl {
+        deno_core::_ops::OpDecl {
+            name: stringify!(op_bool),
+            v8_fn_ptr: Self::v8_fn_ptr as _,
+            enabled: true,
+            fast_fn: Some({
+                use deno_core::v8::fast_api::Type;
+                use deno_core::v8::fast_api::CType;
+                deno_core::v8::fast_api::FastFunction::new(
+                    &[Type::V8Value, Type::Bool],
+                    CType::Bool,
+                    Self::v8_fn_ptr_fast as *const ::std::ffi::c_void,
+                )
+            }),
+            is_async: false,
+            is_unstable: false,
+            is_v8: false,
+            arg_count: 1usize as u8,
+        }
+    }
+    fn v8_fn_ptr_fast(
+        _: deno_core::v8::Local<deno_core::v8::Object>,
+        arg0: bool,
+    ) -> bool {
+        let arg0 = arg0 as _;
+        let result = Self::call(arg0);
+        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 arg0 = args.get(0usize as i32);
+        let arg0 = arg0.is_true();
+        let result = Self::call(arg0);
+        rv.set_bool(result as bool);
+    }
+    #[inline(always)]
+    pub fn call(arg: bool) -> bool {}
+}
diff --git a/ops/op2/test_cases/sync/bool.rs b/ops/op2/test_cases/sync/bool.rs
new file mode 100644
index 0000000..8e036cc
--- /dev/null
+++ b/ops/op2/test_cases/sync/bool.rs
@@ -0,0 +1,5 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+#[op2(fast)]
+pub fn op_bool(arg: bool) -> bool {
+}
diff --git a/ops/op2/test_cases/sync/bool_result.out b/ops/op2/test_cases/sync/bool_result.out
new file mode 100644
index 0000000..e996848
--- /dev/null
+++ b/ops/op2/test_cases/sync/bool_result.out
@@ -0,0 +1,120 @@
+#[allow(non_camel_case_types)]
+pub struct op_bool {
+    _unconstructable: ::std::marker::PhantomData<()>,
+}
+impl deno_core::_ops::Op for op_bool {
+    const NAME: &'static str = stringify!(op_bool);
+    const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl {
+        name: stringify!(op_bool),
+        v8_fn_ptr: Self::v8_fn_ptr as _,
+        enabled: true,
+        fast_fn: Some({
+            use deno_core::v8::fast_api::Type;
+            use deno_core::v8::fast_api::CType;
+            deno_core::v8::fast_api::FastFunction::new(
+                &[Type::V8Value, Type::Bool, Type::CallbackOptions],
+                CType::Bool,
+                Self::v8_fn_ptr_fast as *const ::std::ffi::c_void,
+            )
+        }),
+        is_async: false,
+        is_unstable: false,
+        is_v8: false,
+        arg_count: 1usize as u8,
+    };
+}
+impl op_bool {
+    pub const fn name() -> &'static str {
+        stringify!(op_bool)
+    }
+    pub const fn decl() -> deno_core::_ops::OpDecl {
+        deno_core::_ops::OpDecl {
+            name: stringify!(op_bool),
+            v8_fn_ptr: Self::v8_fn_ptr as _,
+            enabled: true,
+            fast_fn: Some({
+                use deno_core::v8::fast_api::Type;
+                use deno_core::v8::fast_api::CType;
+                deno_core::v8::fast_api::FastFunction::new(
+                    &[Type::V8Value, Type::Bool, Type::CallbackOptions],
+                    CType::Bool,
+                    Self::v8_fn_ptr_fast as *const ::std::ffi::c_void,
+                )
+            }),
+            is_async: false,
+            is_unstable: false,
+            is_v8: false,
+            arg_count: 1usize as u8,
+        }
+    }
+    fn v8_fn_ptr_fast(
+        _: deno_core::v8::Local<deno_core::v8::Object>,
+        arg0: bool,
+        fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions,
+    ) -> bool {
+        let fast_api_callback_options = unsafe { &mut *fast_api_callback_options };
+        let opctx = unsafe {
+            &*(deno_core::v8::Local::<
+                v8::External,
+            >::cast(unsafe { fast_api_callback_options.data.data })
+                .value() as *const deno_core::_ops::OpCtx)
+        };
+        let arg0 = arg0 as _;
+        let result = Self::call(arg0);
+        let result = match result {
+            Ok(result) => result,
+            Err(err) => {
+                unsafe {
+                    opctx.unsafely_set_last_error_for_ops_only(err);
+                }
+                fast_api_callback_options.fallback = true;
+                return ::std::default::Default::default();
+            }
+        };
+        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 opctx = unsafe {
+            &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+                as *const deno_core::_ops::OpCtx)
+        };
+        if let Some(err) = unsafe { opctx.unsafely_take_last_error_for_ops_only() } {
+            let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) };
+            let opstate = ::std::cell::RefCell::borrow(&*opctx.state);
+            let exception = deno_core::error::to_v8_error(
+                scope,
+                opstate.get_error_class_fn,
+                &err,
+            );
+            scope.throw_exception(exception);
+            return;
+        }
+        let arg0 = args.get(0usize as i32);
+        let arg0 = arg0.is_true();
+        let result = Self::call(arg0);
+        match result {
+            Ok(result) => {
+                rv.set_bool(result as bool);
+            }
+            Err(err) => {
+                let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) };
+                let opstate = ::std::cell::RefCell::borrow(&*opctx.state);
+                let exception = deno_core::error::to_v8_error(
+                    scope,
+                    opstate.get_error_class_fn,
+                    &err,
+                );
+                scope.throw_exception(exception);
+                return;
+            }
+        };
+    }
+    #[inline(always)]
+    pub fn call(arg: bool) -> Result<bool, AnyError> {}
+}
diff --git a/ops/op2/test_cases/sync/bool_result.rs b/ops/op2/test_cases/sync/bool_result.rs
new file mode 100644
index 0000000..6268b2e
--- /dev/null
+++ b/ops/op2/test_cases/sync/bool_result.rs
@@ -0,0 +1,5 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+#[op2(fast)]
+pub fn op_bool(arg: bool) -> Result<bool, AnyError> {
+}