summaryrefslogtreecommitdiff
path: root/ext/ffi/call.rs
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2024-10-14 15:05:49 -0700
committerGitHub <noreply@github.com>2024-10-14 15:05:49 -0700
commitee7d4501435f0ebd655c8b50bd6e41ca19e71abc (patch)
tree00b3fce4c8d36320f360000b4b22024f9935ad8e /ext/ffi/call.rs
parent8dbe77dd29a3791db58fda392dea45d8249b6bc9 (diff)
refactor(ext/ffi): use concrete error types (#26170)
Diffstat (limited to 'ext/ffi/call.rs')
-rw-r--r--ext/ffi/call.rs54
1 files changed, 35 insertions, 19 deletions
diff --git a/ext/ffi/call.rs b/ext/ffi/call.rs
index 3572b9e81..d337b29b0 100644
--- a/ext/ffi/call.rs
+++ b/ext/ffi/call.rs
@@ -7,9 +7,6 @@ use crate::symbol::NativeType;
use crate::symbol::Symbol;
use crate::FfiPermissions;
use crate::ForeignFunction;
-use deno_core::anyhow::anyhow;
-use deno_core::error::type_error;
-use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::serde_json::Value;
use deno_core::serde_v8::ExternalPointer;
@@ -24,6 +21,20 @@ use std::ffi::c_void;
use std::future::Future;
use std::rc::Rc;
+#[derive(Debug, thiserror::Error)]
+pub enum CallError {
+ #[error(transparent)]
+ IR(#[from] IRError),
+ #[error("Nonblocking FFI call failed: {0}")]
+ NonblockingCallFailure(#[source] tokio::task::JoinError),
+ #[error("Invalid FFI symbol name: '{0}'")]
+ InvalidSymbol(String),
+ #[error(transparent)]
+ Permission(deno_core::error::AnyError),
+ #[error(transparent)]
+ Callback(#[from] super::CallbackError),
+}
+
// SAFETY: Makes an FFI call
unsafe fn ffi_call_rtype_struct(
cif: &libffi::middle::Cif,
@@ -45,7 +56,7 @@ pub(crate) fn ffi_call_sync<'scope>(
args: v8::FunctionCallbackArguments,
symbol: &Symbol,
out_buffer: Option<OutBuffer>,
-) -> Result<NativeValue, AnyError>
+) -> Result<NativeValue, CallError>
where
'scope: 'scope,
{
@@ -201,7 +212,7 @@ fn ffi_call(
parameter_types: &[NativeType],
result_type: NativeType,
out_buffer: Option<OutBuffer>,
-) -> Result<FfiValue, AnyError> {
+) -> FfiValue {
let call_args: Vec<Arg> = call_args
.iter()
.enumerate()
@@ -214,7 +225,7 @@ fn ffi_call(
// SAFETY: types in the `Cif` match the actual calling convention and
// types of symbol.
unsafe {
- Ok(match result_type {
+ match result_type {
NativeType::Void => {
cif.call::<()>(fun_ptr, &call_args);
FfiValue::Value(Value::from(()))
@@ -267,7 +278,7 @@ fn ffi_call(
ffi_call_rtype_struct(cif, &fun_ptr, call_args, out_buffer.unwrap().0);
FfiValue::Value(Value::Null)
}
- })
+ }
}
}
@@ -280,14 +291,16 @@ pub fn op_ffi_call_ptr_nonblocking<FP>(
#[serde] def: ForeignFunction,
parameters: v8::Local<v8::Array>,
out_buffer: Option<v8::Local<v8::TypedArray>>,
-) -> Result<impl Future<Output = Result<FfiValue, AnyError>>, AnyError>
+) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError>
where
FP: FfiPermissions + 'static,
{
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
- permissions.check_partial_no_path()?;
+ permissions
+ .check_partial_no_path()
+ .map_err(CallError::Permission)?;
};
let symbol = PtrSymbol::new(pointer, &def)?;
@@ -309,7 +322,7 @@ where
Ok(async move {
let result = join_handle
.await
- .map_err(|err| anyhow!("Nonblocking FFI call failed: {}", err))??;
+ .map_err(CallError::NonblockingCallFailure)?;
// SAFETY: Same return type declared to libffi; trust user to have it right beyond that.
Ok(result)
})
@@ -325,16 +338,17 @@ pub fn op_ffi_call_nonblocking(
#[string] symbol: String,
parameters: v8::Local<v8::Array>,
out_buffer: Option<v8::Local<v8::TypedArray>>,
-) -> Result<impl Future<Output = Result<FfiValue, AnyError>>, AnyError> {
+) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError> {
let symbol = {
let state = state.borrow();
- let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?;
+ let resource = state
+ .resource_table
+ .get::<DynamicLibraryResource>(rid)
+ .map_err(CallError::Permission)?;
let symbols = &resource.symbols;
*symbols
.get(&symbol)
- .ok_or_else(|| {
- type_error(format!("Invalid FFI symbol name: '{symbol}'"))
- })?
+ .ok_or_else(|| CallError::InvalidSymbol(symbol))?
.clone()
};
@@ -362,7 +376,7 @@ pub fn op_ffi_call_nonblocking(
Ok(async move {
let result = join_handle
.await
- .map_err(|err| anyhow!("Nonblocking FFI call failed: {}", err))??;
+ .map_err(CallError::NonblockingCallFailure)?;
// SAFETY: Same return type declared to libffi; trust user to have it right beyond that.
Ok(result)
})
@@ -377,14 +391,16 @@ pub fn op_ffi_call_ptr<FP>(
#[serde] def: ForeignFunction,
parameters: v8::Local<v8::Array>,
out_buffer: Option<v8::Local<v8::TypedArray>>,
-) -> Result<FfiValue, AnyError>
+) -> Result<FfiValue, CallError>
where
FP: FfiPermissions + 'static,
{
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
- permissions.check_partial_no_path()?;
+ permissions
+ .check_partial_no_path()
+ .map_err(CallError::Permission)?;
};
let symbol = PtrSymbol::new(pointer, &def)?;
@@ -399,7 +415,7 @@ where
&def.parameters,
def.result.clone(),
out_buffer_ptr,
- )?;
+ );
// SAFETY: Same return type declared to libffi; trust user to have it right beyond that.
Ok(result)
}