mirror of
https://github.com/lune-org/lune.git
synced 2025-04-03 18:10:54 +01:00
Add gitignore for core dump file, Callable optimization (#243)
This commit is contained in:
parent
72fac28dab
commit
12bf3bd9ef
2 changed files with 104 additions and 3 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -30,3 +30,7 @@ scripts/physical_properties_enum_map.rs
|
|||
# Files generated by tests
|
||||
|
||||
/tests/ffi/**/*.so
|
||||
|
||||
# Core dump file
|
||||
|
||||
/core
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use core::ffi::c_void;
|
||||
use std::ptr;
|
||||
use std::{
|
||||
mem::{self, MaybeUninit},
|
||||
ptr,
|
||||
};
|
||||
|
||||
use libffi::{
|
||||
low::{ffi_cif, CodePtr},
|
||||
|
@ -17,6 +20,95 @@ pub struct CallableData {
|
|||
code: CodePtr,
|
||||
}
|
||||
|
||||
const VOID_RESULT_PTR: *mut () = ptr::null_mut();
|
||||
const ZERO_SIZE_ARG_PTR: *mut *mut c_void = ptr::null_mut();
|
||||
|
||||
macro_rules! create_caller {
|
||||
($len:expr) => {
|
||||
|callable: &CallableData, result: LuaValue, args: LuaMultiValue| unsafe {
|
||||
let mut arg_list: [MaybeUninit<*mut c_void>; $len] = [MaybeUninit::uninit(); $len];
|
||||
|
||||
let result_pointer = if callable.result_info.size == 0 {
|
||||
VOID_RESULT_PTR
|
||||
} else {
|
||||
let result_data = result.get_ffi_data()?;
|
||||
if !result_data.check_inner_boundary(0, callable.result_info.size) {
|
||||
return Err(LuaError::external("Result boundary check failed"));
|
||||
}
|
||||
result_data.get_inner_pointer()
|
||||
}
|
||||
.cast::<c_void>();
|
||||
|
||||
for (index, arg) in arg_list.iter_mut().enumerate() {
|
||||
let arg_value = args
|
||||
.get(index)
|
||||
.ok_or_else(|| LuaError::external(format!("argument {index} required")))?
|
||||
.as_userdata()
|
||||
.ok_or_else(|| LuaError::external("argument should be Ref"))?;
|
||||
|
||||
let arg_ref = arg_value.borrow::<RefData>()?;
|
||||
|
||||
arg.write(arg_ref.get_inner_pointer().cast::<c_void>());
|
||||
}
|
||||
|
||||
ffi_call(
|
||||
callable.cif,
|
||||
Some(*callable.code.as_safe_fun()),
|
||||
result_pointer,
|
||||
// SAFETY: MaybeUninit<T> has the same layout as `T`, and initialized above
|
||||
mem::transmute::<[MaybeUninit<*mut c_void>; $len], [*mut c_void; $len]>(arg_list)
|
||||
.as_mut_ptr(),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
unsafe fn zero_size_caller(
|
||||
callable: &CallableData,
|
||||
result: LuaValue,
|
||||
_args: LuaMultiValue,
|
||||
) -> LuaResult<()> {
|
||||
let result_pointer = if callable.result_info.size == 0 {
|
||||
VOID_RESULT_PTR
|
||||
} else {
|
||||
let result_data = result.get_ffi_data()?;
|
||||
if !result_data.check_inner_boundary(0, callable.result_info.size) {
|
||||
return Err(LuaError::external("Result boundary check failed"));
|
||||
}
|
||||
result_data.get_inner_pointer()
|
||||
}
|
||||
.cast::<c_void>();
|
||||
|
||||
ffi_call(
|
||||
callable.cif,
|
||||
Some(*callable.code.as_safe_fun()),
|
||||
result_pointer,
|
||||
ZERO_SIZE_ARG_PTR,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
type Caller =
|
||||
unsafe fn(callable: &CallableData, result: LuaValue, args: LuaMultiValue) -> LuaResult<()>;
|
||||
const SIZED_CALLERS: [Caller; 13] = [
|
||||
zero_size_caller,
|
||||
create_caller!(1),
|
||||
create_caller!(2),
|
||||
create_caller!(3),
|
||||
create_caller!(4),
|
||||
create_caller!(5),
|
||||
create_caller!(6),
|
||||
create_caller!(7),
|
||||
create_caller!(8),
|
||||
create_caller!(9),
|
||||
create_caller!(10),
|
||||
create_caller!(11),
|
||||
create_caller!(12),
|
||||
];
|
||||
|
||||
impl CallableData {
|
||||
pub unsafe fn new(
|
||||
cif: *mut ffi_cif,
|
||||
|
@ -33,10 +125,15 @@ impl CallableData {
|
|||
}
|
||||
|
||||
pub unsafe fn call(&self, result: LuaValue, args: LuaMultiValue) -> LuaResult<()> {
|
||||
let mut arg_list = Vec::<*mut c_void>::with_capacity(self.arg_info_list.len());
|
||||
let arg_len = self.arg_info_list.len();
|
||||
if arg_len < SIZED_CALLERS.len() {
|
||||
return SIZED_CALLERS[arg_len](self, result, args);
|
||||
}
|
||||
|
||||
let mut arg_list = Vec::<*mut c_void>::with_capacity(arg_len);
|
||||
|
||||
let result_pointer = if self.result_info.size == 0 {
|
||||
ptr::null_mut()
|
||||
VOID_RESULT_PTR
|
||||
} else {
|
||||
let result_data = result.get_ffi_data()?;
|
||||
if !result_data.check_inner_boundary(0, self.result_info.size) {
|
||||
|
|
Loading…
Add table
Reference in a new issue