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