use sub_core::fnv1; #[inline(always)] pub unsafe fn find_import_hashed(module_name: u64, func_name: u64) -> Option { 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 = 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),*) } )* }