35 lines
1.3 KiB
Rust
35 lines
1.3 KiB
Rust
use sub_core::fnv1;
|
|
|
|
#[inline(always)]
|
|
pub unsafe fn find_import_hashed(module_name: u64, func_name: u64) -> Option<usize> {
|
|
crate::modules::loaded_modules()
|
|
.filter( |&(_,slice)|fnv1::hash_utf16(slice) == module_name).next()
|
|
.and_then(|(i,_)|i.exports())
|
|
.and_then(|v|{
|
|
v.filter_map(|(p,n)|(fnv1::hash_utf8(n) == func_name).then_some(p)).next()
|
|
})
|
|
}
|
|
|
|
|
|
|
|
pub macro lazy_import ( $module:literal $($v:vis fn $name:ident($($pname:ident: $ptype:ty),*) $(-> $rtype:ty)?; )* ) {
|
|
$(
|
|
#[allow(unused, non_snake_case)] #[inline(always)]
|
|
$v fn $name($($pname: $ptype),*) $(-> $rtype)? {
|
|
type FTYPE = extern "C" fn($($pname: $ptype),*) $(-> $rtype)?;
|
|
static mut FUNC: Option<FTYPE> = None;
|
|
let function = match unsafe { FUNC } {
|
|
Some(function) => function,
|
|
None => unsafe {
|
|
let import = core::mem::transmute(find_import_hashed(
|
|
const { fnv1::hash_utf8($module.as_bytes()) },
|
|
const { fnv1::hash_utf8(stringify!($name).as_bytes()) }
|
|
).unwrap_or(0));
|
|
FUNC = Some(import);
|
|
import
|
|
}
|
|
};
|
|
function($($pname),*)
|
|
}
|
|
)*
|
|
} |