]> Repositorios git - scryer-prolog.git/commitdiff
upgrade libffi dependency
authorSkgland <[email protected]>
Fri, 8 May 2026 20:36:41 +0000 (22:36 +0200)
committerSkgland <[email protected]>
Fri, 8 May 2026 20:36:41 +0000 (22:36 +0200)
Cargo.lock
Cargo.toml
src/ffi.rs
src/machine/machine_errors.rs

index d00508e5e1ba80fff3f42afe330fcfff67c8cd31..ed7a312a0cab399f00e56bd33f619f002f5ba812 100644 (file)
@@ -1625,9 +1625,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "libffi"
-version = "4.1.0"
+version = "5.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebfd30a67b482a08116e753d0656cb626548cf4242543e5cc005be7639d99838"
+checksum = "0498fe5655f857803e156523e644dcdcdc3b3c7edda42ea2afdae2e09b2db87b"
 dependencies = [
  "libc",
  "libffi-sys",
@@ -1635,9 +1635,9 @@ dependencies = [
 
 [[package]]
 name = "libffi-sys"
-version = "3.3.1"
+version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f003aa318c9f0ee69eb0ada7c78f5c9d2fedd2ceb274173b5c7ff475eee584a3"
+checksum = "71d4f1d4ce15091955144350b75db16a96d4a63728500122706fb4d29a26afbb"
 dependencies = [
  "cc",
 ]
index 39801345b6847e8f34d9171f7a808e4c9e612abd..d0bb1ef45e695c5bcadaa6e00c760bbf7de0263c 100644 (file)
@@ -94,7 +94,7 @@ parking_lot = "0.12.4"
 crossterm = { version = "0.28.1", optional = true }
 ctrlc = { version = "3.4.4", optional = true }
 hostname = { version = "0.4.0", optional = true }
-libffi = { version = "4.0.0", optional = true }
+libffi = { version = "5.1.0", optional = true }
 native-tls = { version = "0.2.12", optional = true }
 # the version requirement of reqwest is kept low for compatibility with old deno versions
 # that pin reqwest to 0.11.20
index c1762fb625ec31180c0e81ae1b77649750f59a71..e7957dece0325fbb1ba6999c3bb9f705f748e37a 100644 (file)
@@ -26,7 +26,7 @@ use crate::machine::machine_errors::DomainErrorType;
 use crate::parser::ast::{Fixnum, MightNotFitInFixnum};
 
 use dashu::Integer;
-use libffi::middle::{Arg, Cif, CodePtr, Type};
+use libffi::middle::{Arg, Cif, CodePtr, Ret, Type};
 use libloading::{Library, Symbol};
 use ordered_float::OrderedFloat;
 use std::alloc::{self, Layout};
@@ -36,7 +36,6 @@ use std::ffi::{c_char, c_void, CStr, CString};
 use std::fmt::Debug;
 use std::marker::PhantomData;
 use std::mem::ManuallyDrop;
-use std::ops::Deref;
 use std::ptr::NonNull;
 
 pub struct FunctionDefinition {
@@ -55,7 +54,7 @@ pub struct FunctionImpl {
 
 impl FunctionImpl {
     unsafe fn call_void(&self, args: &[Arg], _: &mut Arena) -> Result<Value, FfiError> {
-        self.cif.call::<()>(self.code_ptr, args);
+        self.cif.call_return_into(self.code_ptr, args, Ret::void());
         Ok(Value::Number(Number::Fixnum(Fixnum::build_with(0))))
     }
 
@@ -114,12 +113,8 @@ impl FunctionImpl {
         let alloc = FfiStruct::new(layout, FfiAllocator::Rust)?;
 
         unsafe {
-            libffi::raw::ffi_call(
-                self.cif.as_raw_ptr(),
-                Some(*self.code_ptr.as_safe_fun()),
-                alloc.ptr.as_ptr(),
-                args.as_ptr() as *mut *mut c_void,
-            )
+            self.cif
+                .call_return_into(self.code_ptr, args, alloc.as_ret())
         };
 
         let struct_val =
@@ -336,7 +331,9 @@ impl StructImpl {
                             substruct_type.read(field_ptr, *substruct, struct_table, arena)?;
                         Ok(struct_val)
                     }
-                    FfiType::Void => return Err(FfiError::VoidArgumentType),
+                    FfiType::Void => {
+                        return Err(FfiError::UnsupportedArgumentType(Some(atom!("void"))))
+                    }
                 };
                 returns.push(val?);
             }
@@ -345,48 +342,6 @@ impl StructImpl {
     }
 }
 
-struct PointerArgs<'a, 'val> {
-    memory: Vec<Arg>,
-    phantom: PhantomData<&'a mut ArgValue<'val>>,
-}
-
-impl<'args, 'val> PointerArgs<'args, 'val> {
-    fn new(args: &'args [ArgValue<'val>]) -> Self {
-        let args = args
-            .iter()
-            .map(|arg| match arg {
-                ArgValue::U8(a) => libffi::middle::arg(a),
-                ArgValue::I8(a) => libffi::middle::arg(a),
-                ArgValue::U16(a) => libffi::middle::arg(a),
-                ArgValue::I16(a) => libffi::middle::arg(a),
-                ArgValue::U32(a) => libffi::middle::arg(a),
-                ArgValue::I32(a) => libffi::middle::arg(a),
-                ArgValue::U64(a) => libffi::middle::arg(a),
-                ArgValue::I64(a) => libffi::middle::arg(a),
-                ArgValue::F32(a) => libffi::middle::arg(a),
-                ArgValue::F64(a) => libffi::middle::arg(a),
-                ArgValue::Ptr(ptr, _) => Arg::new(ptr),
-                ArgValue::Struct(s) => unsafe {
-                    std::mem::transmute::<*mut c_void, Arg>(s.ptr.as_ptr())
-                },
-            })
-            .collect();
-
-        PointerArgs {
-            memory: args,
-            phantom: PhantomData,
-        }
-    }
-}
-
-impl Deref for PointerArgs<'_, '_> {
-    type Target = [Arg];
-
-    fn deref(&self) -> &Self::Target {
-        &self.memory
-    }
-}
-
 #[derive(Debug, Clone, Copy)]
 enum FfiType {
     Void,
@@ -543,7 +498,7 @@ impl<'val> ArgValue<'val> {
                     args,
                 )?))
             }
-            FfiType::Void => Err(FfiError::VoidArgumentType),
+            FfiType::Void => Err(FfiError::UnsupportedArgumentType(Some(atom!("void")))),
         }
     }
 
@@ -568,6 +523,28 @@ impl<'val> ArgValue<'val> {
             .map(|(arg, arg_type)| ArgValue::new(arg, arg_type, structs_table))
             .collect::<Result<Vec<_>, _>>()
     }
+
+    fn as_arg<'res, 'this: 'res>(&'this self) -> Arg<'res>
+    where
+        'val: 'res,
+    {
+        match self {
+            ArgValue::U8(a) => libffi::middle::arg(a),
+            ArgValue::I8(a) => libffi::middle::arg(a),
+            ArgValue::U16(a) => libffi::middle::arg(a),
+            ArgValue::I16(a) => libffi::middle::arg(a),
+            ArgValue::U32(a) => libffi::middle::arg(a),
+            ArgValue::I32(a) => libffi::middle::arg(a),
+            ArgValue::U64(a) => libffi::middle::arg(a),
+            ArgValue::I64(a) => libffi::middle::arg(a),
+            ArgValue::F32(a) => libffi::middle::arg(a),
+            ArgValue::F64(a) => libffi::middle::arg(a),
+            ArgValue::Ptr(ptr, _) => Arg::new(ptr),
+            ArgValue::Struct(s) => unsafe {
+                std::mem::transmute::<*mut c_void, Arg>(s.ptr.as_ptr())
+            },
+        }
+    }
 }
 
 struct FfiStruct {
@@ -628,6 +605,10 @@ impl FfiStruct {
             allocator,
         })
     }
+
+    fn as_ret(&self) -> libffi::middle::Ret<'_> {
+        unsafe { std::mem::transmute::<*mut c_void, Ret>(self.ptr.as_ptr()) }
+    }
 }
 
 impl Drop for FfiStruct {
@@ -727,7 +708,7 @@ impl ForeignFunctionTable {
             &self.structs,
         )?;
 
-        let args = PointerArgs::new(&args);
+        let args: Vec<_> = args.iter().map(|v| v.as_arg()).collect();
 
         fn_impl.call(&args, arena, &self.structs)
     }
@@ -755,7 +736,7 @@ impl ForeignFunctionTable {
         }
 
         match FfiType::from_atom(&kind) {
-            FfiType::Void => Err(FfiError::VoidArgumentType),
+            FfiType::Void => Err(FfiError::UnsupportedArgumentType(Some(atom!("void")))),
             FfiType::Bool => {
                 let val = args.as_int::<i8>()?;
                 let init = match val {
@@ -819,7 +800,7 @@ impl ForeignFunctionTable {
         };
 
         match FfiType::from_atom(&kind) {
-            FfiType::Void => Err(FfiError::VoidArgumentType),
+            FfiType::Void => Err(FfiError::UnsupportedArgumentType(Some(atom!("void")))),
             FfiType::U8 => Ok(unsafe { read_int::<u8>(ptr, arena) }),
             FfiType::Bool | FfiType::I8 => Ok(unsafe { read_int::<i8>(ptr, arena) }),
             FfiType::U16 => Ok(unsafe { read_int::<u16>(ptr, arena) }),
@@ -869,7 +850,7 @@ impl ForeignFunctionTable {
         };
 
         match FfiType::from_atom(&kind) {
-            FfiType::Void => return Err(FfiError::VoidArgumentType),
+            FfiType::Void => return Err(FfiError::UnsupportedArgumentType(Some(atom!("void")))),
             FfiType::Bool => deallocate_primitive::<bool>(allocator, ptr),
             FfiType::U8 => deallocate_primitive::<u8>(allocator, ptr),
             FfiType::I8 => deallocate_primitive::<i8>(allocator, ptr),
@@ -966,10 +947,11 @@ impl Value {
 }
 
 #[derive(Debug)]
+#[non_exhaustive]
 pub enum FfiError {
     ValueCast(Atom, Atom),
     ValueOutOfRange(DomainErrorType, Value),
-    VoidArgumentType,
+    UnsupportedArgumentType(Option<Atom>),
     FunctionNotFound(Atom, usize),
     StructNotFound(Atom),
     ArgCountMismatch {
@@ -987,6 +969,9 @@ pub enum FfiError {
     UnsupportedAbi,
     CStrFieldType,
     NullPtr,
+    #[doc(hidden)]
+    #[non_exhaustive]
+    Other,
 }
 
 #[derive(Debug)]
@@ -1008,6 +993,8 @@ impl From<libffi::low::Error> for FfiError {
         match value {
             libffi::low::Error::Typedef => FfiError::UnsupportedTypedef,
             libffi::low::Error::Abi => FfiError::UnsupportedAbi,
+            libffi::low::Error::ArgType => FfiError::UnsupportedArgumentType(None),
+            _ => FfiError::Other,
         }
     }
 }
index 2dccd1c871ef748cdf1ca6a2ae08dba5f0b177a5..52a87dfeafd8ffb804901d3b45bddcf64091ef6f 100644 (file)
@@ -737,10 +737,13 @@ impl MachineState {
             FfiError::LayoutError => self.representation_error(RepFlag::FfiLayout),
             FfiError::UnsupportedTypedef => self.representation_error(RepFlag::FfiLayout),
             FfiError::UnsupportedAbi => self.representation_error(RepFlag::FfiAbi),
-            FfiError::VoidArgumentType => self.domain_error(
+            FfiError::UnsupportedArgumentType(None) => self.domain_error(
                 DomainErrorType::FfiArgumentType,
-                atom_as_cell!(atom!("void")),
+                atom_as_cell!(atom!("unknown")),
             ),
+            FfiError::UnsupportedArgumentType(Some(kind)) => {
+                self.domain_error(DomainErrorType::FfiArgumentType, atom_as_cell!(kind))
+            }
             FfiError::CStrFieldType => self.domain_error(
                 DomainErrorType::NonCStrFfiArgumentType,
                 atom_as_cell!(atom!("cstr")),
@@ -749,6 +752,7 @@ impl MachineState {
                 DomainErrorType::NonNullPtr,
                 fixnum_as_cell!(Fixnum::build_with(0)),
             ),
+            FfiError::Other => self.unreachable_error(),
         }
     }