From cfc210e7d7adb61866ce2190e8fd8ec3d68cc54b Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Fri, 8 May 2020 09:48:08 +0200 Subject: [PATCH] misc: adds function prototype --- crates/mun/src/main.rs | 18 +- crates/mun_abi/c | 2 +- crates/mun_abi/src/autogen.rs | 98 ++++++---- crates/mun_abi/src/autogen_impl.rs | 202 +++++++++++---------- crates/mun_abi/src/function_info.rs | 51 +++--- crates/mun_abi/src/lib.rs | 6 +- crates/mun_codegen/src/code_gen/symbols.rs | 44 +++-- crates/mun_codegen/src/ir/abi_types.rs | 34 ++-- crates/mun_runtime/src/assembly.rs | 31 ++-- crates/mun_runtime/src/lib.rs | 43 ++--- crates/mun_runtime/src/macros.rs | 6 +- crates/mun_runtime/tests/marshalling.rs | 8 +- crates/mun_runtime/tests/memory.rs | 4 +- crates/mun_runtime/tests/util.rs | 4 +- crates/mun_runtime_capi/ffi | 2 +- crates/mun_runtime_capi/src/lib.rs | 21 +-- crates/mun_runtime_capi/src/tests.rs | 59 +++--- crates/tools/src/abi.rs | 2 +- 18 files changed, 348 insertions(+), 287 deletions(-) diff --git a/crates/mun/src/main.rs b/crates/mun/src/main.rs index 42dc10890..919cfb497 100644 --- a/crates/mun/src/main.rs +++ b/crates/mun/src/main.rs @@ -98,14 +98,16 @@ fn start(matches: &ArgMatches) -> Result<(), failure::Error> { let borrowed = runtime.borrow(); let entry_point = matches.value_of("entry").unwrap_or("main"); - let fn_info = borrowed.get_function_info(entry_point).ok_or_else(|| { - std::io::Error::new( - std::io::ErrorKind::InvalidInput, - format!("Failed to obtain entry point '{}'", entry_point), - ) - })?; - - if let Some(ret_type) = fn_info.signature.return_type() { + let fn_definition = borrowed + .get_function_definition(entry_point) + .ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::InvalidInput, + format!("Failed to obtain entry point '{}'", entry_point), + ) + })?; + + if let Some(ret_type) = fn_definition.prototype.signature.return_type() { let type_guid = &ret_type.guid; if *type_guid == bool::type_guid() { let result: bool = diff --git a/crates/mun_abi/c b/crates/mun_abi/c index 079ce3590..4bccc48f4 160000 --- a/crates/mun_abi/c +++ b/crates/mun_abi/c @@ -1 +1 @@ -Subproject commit 079ce3590ee5e3efcbcc34aac20f3833d5303808 +Subproject commit 4bccc48f4c782fa06c1ae911b2f7bf36e587280c diff --git a/crates/mun_abi/src/autogen.rs b/crates/mun_abi/src/autogen.rs index b8e34744a..26a35e3b7 100644 --- a/crates/mun_abi/src/autogen.rs +++ b/crates/mun_abi/src/autogen.rs @@ -3,7 +3,7 @@ /* automatically generated by rust-bindgen */ #![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] -use crate::{Privacy, StructMemoryKind, TypeGroup}; +use crate::{StructMemoryKind, TypeGroup}; #[doc = " Represents a globally unique identifier (GUID)."] #[doc = ""] @@ -122,22 +122,18 @@ fn bindgen_test_layout_TypeInfo() { #[repr(C)] #[derive(Clone, Debug)] pub struct FunctionSignature { - #[doc = " Function name"] - pub name: *const ::std::os::raw::c_char, #[doc = " Argument types"] pub arg_types: *const *const TypeInfo, #[doc = " Optional return type"] pub return_type: *const TypeInfo, #[doc = " Number of argument types"] pub num_arg_types: u16, - #[doc = " Function accessibility level"] - pub privacy: Privacy, } #[test] fn bindgen_test_layout_FunctionSignature() { assert_eq!( ::std::mem::size_of::(), - 32usize, + 24usize, concat!("Size of: ", stringify!(FunctionSignature)) ); assert_eq!( @@ -146,97 +142,123 @@ fn bindgen_test_layout_FunctionSignature() { concat!("Alignment of ", stringify!(FunctionSignature)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).name as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).arg_types as *const _ as usize }, 0usize, concat!( "Offset of field: ", stringify!(FunctionSignature), "::", - stringify!(name) + stringify!(arg_types) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).arg_types as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).return_type as *const _ as usize }, 8usize, concat!( "Offset of field: ", stringify!(FunctionSignature), "::", - stringify!(arg_types) + stringify!(return_type) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).return_type as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).num_arg_types as *const _ as usize }, 16usize, concat!( "Offset of field: ", stringify!(FunctionSignature), "::", - stringify!(return_type) + stringify!(num_arg_types) ) ); +} +#[doc = " Represents a function prototype. A function prototype contains the name,"] +#[doc = " type signature, but not an implementation."] +#[doc = ""] +#[doc = "
"] +#[repr(C)] +#[derive(Clone, Debug)] +pub struct FunctionPrototype { + #[doc = " Function name"] + pub name: *const ::std::os::raw::c_char, + #[doc = " The type signature of the function"] + pub signature: FunctionSignature, +} +#[test] +fn bindgen_test_layout_FunctionPrototype() { assert_eq!( - unsafe { &(*(::std::ptr::null::())).num_arg_types as *const _ as usize }, - 24usize, + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(FunctionPrototype)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(FunctionPrototype)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).name as *const _ as usize }, + 0usize, concat!( "Offset of field: ", - stringify!(FunctionSignature), + stringify!(FunctionPrototype), "::", - stringify!(num_arg_types) + stringify!(name) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).privacy as *const _ as usize }, - 26usize, + unsafe { &(*(::std::ptr::null::())).signature as *const _ as usize }, + 8usize, concat!( "Offset of field: ", - stringify!(FunctionSignature), + stringify!(FunctionPrototype), "::", - stringify!(privacy) + stringify!(signature) ) ); } -#[doc = " Represents a function declaration."] +#[doc = " Represents a function definition. A function definition contains the name,"] +#[doc = " type signature, and a pointer to the implementation."] #[doc = ""] #[doc = " `fn_ptr` can be used to call the declared function."] #[doc = ""] #[doc = "
"] #[repr(C)] #[derive(Clone, Debug)] -pub struct FunctionInfo { - #[doc = " Function signature"] - pub signature: FunctionSignature, +pub struct FunctionDefinition { + #[doc = " Function prototype"] + pub prototype: FunctionPrototype, #[doc = " Function pointer"] pub fn_ptr: *const ::std::os::raw::c_void, } #[test] -fn bindgen_test_layout_FunctionInfo() { +fn bindgen_test_layout_FunctionDefinition() { assert_eq!( - ::std::mem::size_of::(), + ::std::mem::size_of::(), 40usize, - concat!("Size of: ", stringify!(FunctionInfo)) + concat!("Size of: ", stringify!(FunctionDefinition)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::(), 8usize, - concat!("Alignment of ", stringify!(FunctionInfo)) + concat!("Alignment of ", stringify!(FunctionDefinition)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).signature as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).prototype as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(FunctionInfo), + stringify!(FunctionDefinition), "::", - stringify!(signature) + stringify!(prototype) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).fn_ptr as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).fn_ptr as *const _ as usize }, 32usize, concat!( "Offset of field: ", - stringify!(FunctionInfo), + stringify!(FunctionDefinition), "::", stringify!(fn_ptr) ) @@ -331,7 +353,7 @@ pub struct ModuleInfo { #[doc = " Module path"] pub path: *const ::std::os::raw::c_char, #[doc = " Module functions"] - pub functions: *const FunctionInfo, + pub functions: *const FunctionDefinition, #[doc = " Number of module functions"] pub num_functions: u32, #[doc = " Module types"] @@ -411,7 +433,7 @@ fn bindgen_test_layout_ModuleInfo() { #[derive(Debug)] pub struct DispatchTable { #[doc = " Function signatures"] - pub signatures: *const FunctionSignature, + pub prototypes: *const FunctionPrototype, #[doc = " Function pointers"] pub fn_ptrs: *mut *const ::std::os::raw::c_void, #[doc = " Number of functions"] @@ -430,13 +452,13 @@ fn bindgen_test_layout_DispatchTable() { concat!("Alignment of ", stringify!(DispatchTable)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).signatures as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).prototypes as *const _ as usize }, 0usize, concat!( "Offset of field: ", stringify!(DispatchTable), "::", - stringify!(signatures) + stringify!(prototypes) ) ); assert_eq!( diff --git a/crates/mun_abi/src/autogen_impl.rs b/crates/mun_abi/src/autogen_impl.rs index bae00ba8a..66ad3f220 100644 --- a/crates/mun_abi/src/autogen_impl.rs +++ b/crates/mun_abi/src/autogen_impl.rs @@ -71,16 +71,6 @@ unsafe impl Send for TypeInfo {} unsafe impl Sync for TypeInfo {} impl FunctionSignature { - /// Returns the function's name. - pub fn name(&self) -> &str { - unsafe { str::from_utf8_unchecked(CStr::from_ptr(self.name).to_bytes()) } - } - - /// Returns the function's privacy level. - pub fn privacy(&self) -> Privacy { - self.privacy - } - /// Returns the function's arguments' types. pub fn arg_types(&self) -> &[&TypeInfo] { if self.num_arg_types == 0 { @@ -103,7 +93,7 @@ impl FunctionSignature { impl fmt::Display for FunctionSignature { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "fn {}(", self.name())?; + write!(f, "fn(")?; for (i, arg) in self.arg_types().iter().enumerate() { if i > 0 { write!(f, ", ")?; @@ -121,8 +111,35 @@ impl fmt::Display for FunctionSignature { unsafe impl Send for FunctionSignature {} unsafe impl Sync for FunctionSignature {} -unsafe impl Send for FunctionInfo {} -unsafe impl Sync for FunctionInfo {} +impl FunctionPrototype { + /// Returns the function's name. + pub fn name(&self) -> &str { + unsafe { str::from_utf8_unchecked(CStr::from_ptr(self.name).to_bytes()) } + } +} + +impl fmt::Display for FunctionPrototype { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "fn {}(", self.name())?; + for (i, arg) in self.signature.arg_types().iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + write!(f, "{}", arg)?; + } + write!(f, ")")?; + if let Some(ret_type) = self.signature.return_type() { + write!(f, ":{}", ret_type)? + } + Ok(()) + } +} + +unsafe impl Send for FunctionPrototype {} +unsafe impl Sync for FunctionPrototype {} + +unsafe impl Send for FunctionDefinition {} +unsafe impl Sync for FunctionDefinition {} impl StructInfo { /// Returns the struct's field names. @@ -203,7 +220,7 @@ impl ModuleInfo { // } /// Returns the module's functions. - pub fn functions(&self) -> &[FunctionInfo] { + pub fn functions(&self) -> &[FunctionDefinition] { if self.num_functions == 0 { &[] } else { @@ -228,28 +245,28 @@ unsafe impl Sync for ModuleInfo {} impl DispatchTable { /// Returns an iterator over pairs of mutable function pointers and signatures. - pub fn iter_mut(&mut self) -> impl Iterator { + pub fn iter_mut(&mut self) -> impl Iterator { if self.num_entries == 0 { (&mut []).iter_mut().zip((&[]).iter()) } else { let ptrs = unsafe { slice::from_raw_parts_mut(self.fn_ptrs, self.num_entries as usize) }; let signatures = - unsafe { slice::from_raw_parts(self.signatures, self.num_entries as usize) }; + unsafe { slice::from_raw_parts(self.prototypes, self.num_entries as usize) }; ptrs.iter_mut().zip(signatures.iter()) } } /// Returns an iterator over pairs of function pointers and signatures. - pub fn iter(&self) -> impl Iterator { + pub fn iter(&self) -> impl Iterator { if self.num_entries == 0 { (&[]).iter().zip((&[]).iter()) } else { let ptrs = unsafe { slice::from_raw_parts_mut(self.fn_ptrs, self.num_entries as usize) }; let signatures = - unsafe { slice::from_raw_parts(self.signatures, self.num_entries as usize) }; + unsafe { slice::from_raw_parts(self.prototypes, self.num_entries as usize) }; ptrs.iter().zip(signatures.iter()) } @@ -264,12 +281,12 @@ impl DispatchTable { } } - /// Returns function signatures. - pub fn signatures(&self) -> &[FunctionSignature] { + /// Returns function prototypes. + pub fn prototypes(&self) -> &[FunctionPrototype] { if self.num_entries == 0 { &[] } else { - unsafe { slice::from_raw_parts(self.signatures, self.num_entries as usize) } + unsafe { slice::from_raw_parts(self.prototypes, self.num_entries as usize) } } } @@ -429,44 +446,41 @@ mod tests { } fn fake_fn_signature( - name: &CStr, arg_types: &[&TypeInfo], return_type: Option<&TypeInfo>, - privacy: Privacy, ) -> FunctionSignature { FunctionSignature { - name: name.as_ptr(), arg_types: arg_types.as_ptr().cast::<*const TypeInfo>(), return_type: return_type.map_or(ptr::null(), |t| t as *const TypeInfo), num_arg_types: arg_types.len() as u16, - privacy, + } + } + + fn fake_fn_prototype( + name: &CStr, + arg_types: &[&TypeInfo], + return_type: Option<&TypeInfo>, + ) -> FunctionPrototype { + FunctionPrototype { + name: name.as_ptr(), + signature: fake_fn_signature(arg_types, return_type), } } const FAKE_FN_NAME: &str = "fn-name"; #[test] - fn test_fn_signature_name() { + fn test_fn_prototype_name() { let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], None, Privacy::Public); + let fn_signature = fake_fn_prototype(&fn_name, &[], None); assert_eq!(fn_signature.name(), FAKE_FN_NAME); } - #[test] - fn test_fn_signature_privacy() { - let privacy = Privacy::Private; - let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], None, privacy); - - assert_eq!(fn_signature.privacy(), privacy); - } - #[test] fn test_fn_signature_arg_types_none() { let arg_types = &[]; - let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, arg_types, None, Privacy::Public); + let fn_signature = fake_fn_signature(arg_types, None); assert_eq!(fn_signature.arg_types(), arg_types); } @@ -477,8 +491,7 @@ mod tests { let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let arg_types = &[&type_info]; - let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, arg_types, None, Privacy::Public); + let fn_signature = fake_fn_signature(arg_types, None); assert_eq!(fn_signature.arg_types(), arg_types); } @@ -486,8 +499,7 @@ mod tests { #[test] fn test_fn_signature_return_type_none() { let return_type = None; - let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_signature = fake_fn_signature(&[], return_type); assert_eq!(fn_signature.return_type(), return_type); } @@ -498,8 +510,7 @@ mod tests { let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); - let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_signature = fake_fn_signature(&[], return_type); assert_eq!(fn_signature.return_type(), return_type); } @@ -572,7 +583,7 @@ mod tests { fn fake_module_info( path: &CStr, - functions: &[FunctionInfo], + functions: &[FunctionDefinition], types: &[&TypeInfo], ) -> ModuleInfo { ModuleInfo { @@ -613,10 +624,10 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let fn_info = FunctionInfo { - signature: fn_signature, + let fn_info = FunctionDefinition { + prototype: fn_prototype, fn_ptr: ptr::null(), }; let functions = &[fn_info]; @@ -633,10 +644,15 @@ mod tests { assert_eq!(result_functions.len(), functions.len()); for (lhs, rhs) in result_functions.iter().zip(functions.iter()) { assert_eq!(lhs.fn_ptr, rhs.fn_ptr); - assert_eq!(lhs.signature.name(), rhs.signature.name()); - assert_eq!(lhs.signature.arg_types(), rhs.signature.arg_types()); - assert_eq!(lhs.signature.return_type(), rhs.signature.return_type()); - assert_eq!(lhs.signature.privacy(), rhs.signature.privacy()); + assert_eq!(lhs.prototype.name(), rhs.prototype.name()); + assert_eq!( + lhs.prototype.signature.arg_types(), + rhs.prototype.signature.arg_types() + ); + assert_eq!( + lhs.prototype.signature.return_type(), + rhs.prototype.signature.return_type() + ); } let result_types: &[&TypeInfo] = module.types(); @@ -654,15 +670,15 @@ mod tests { } fn fake_dispatch_table( - fn_signatures: &[FunctionSignature], + fn_prototypes: &[FunctionPrototype], fn_ptrs: &mut [*const c_void], ) -> DispatchTable { - assert!(fn_signatures.len() == fn_ptrs.len()); + assert_eq!(fn_prototypes.len(), fn_ptrs.len()); DispatchTable { - signatures: fn_signatures.as_ptr(), + prototypes: fn_prototypes.as_ptr(), fn_ptrs: fn_ptrs.as_mut_ptr(), - num_entries: fn_signatures.len() as u32, + num_entries: fn_prototypes.len() as u32, } } @@ -683,21 +699,20 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let mut dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let mut dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); - let iter = fn_ptrs.iter_mut().zip(signatures.iter()); + let iter = fn_ptrs.iter_mut().zip(prototypes.iter()); assert_eq!(dispatch_table.iter_mut().count(), iter.len()); for (lhs, rhs) in dispatch_table.iter_mut().zip(iter) { assert_eq!(lhs.0, rhs.0); assert_eq!(lhs.1.name(), rhs.1.name()); - assert_eq!(lhs.1.arg_types(), rhs.1.arg_types()); - assert_eq!(lhs.1.return_type(), rhs.1.return_type()); - assert_eq!(lhs.1.privacy(), rhs.1.privacy()); + assert_eq!(lhs.1.signature.arg_types(), rhs.1.signature.arg_types()); + assert_eq!(lhs.1.signature.return_type(), rhs.1.signature.return_type()); } } @@ -717,11 +732,11 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let mut dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let mut dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); let result = dispatch_table.ptrs_mut(); assert_eq!(result.len(), fn_ptrs.len()); @@ -736,7 +751,7 @@ mod tests { let fn_ptrs = &mut []; let dispatch_table = fake_dispatch_table(signatures, fn_ptrs); - assert_eq!(dispatch_table.signatures().len(), 0); + assert_eq!(dispatch_table.prototypes().len(), 0); } #[test] @@ -746,19 +761,18 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); - let result = dispatch_table.signatures(); - assert_eq!(result.len(), signatures.len()); - for (lhs, rhs) in result.iter().zip(signatures.iter()) { + let result = dispatch_table.prototypes(); + assert_eq!(result.len(), prototypes.len()); + for (lhs, rhs) in result.iter().zip(prototypes.iter()) { assert_eq!(lhs.name(), rhs.name()); - assert_eq!(lhs.arg_types(), rhs.arg_types()); - assert_eq!(lhs.return_type(), rhs.return_type()); - assert_eq!(lhs.privacy(), rhs.privacy()); + assert_eq!(lhs.signature.arg_types(), rhs.signature.arg_types()); + assert_eq!(lhs.signature.return_type(), rhs.signature.return_type()); } } @@ -769,12 +783,12 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); assert_eq!(unsafe { dispatch_table.get_ptr_unchecked(0) }, fn_ptrs[0]); } @@ -785,12 +799,12 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototype = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let dispatch_table = fake_dispatch_table(prototype, fn_ptrs); assert_eq!(dispatch_table.get_ptr(1), None); } @@ -801,12 +815,12 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); assert_eq!(dispatch_table.get_ptr(0), Some(fn_ptrs[0])); } @@ -817,12 +831,12 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let mut dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let mut dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); assert_eq!( unsafe { dispatch_table.get_ptr_unchecked_mut(0) }, &mut fn_ptrs[0] @@ -836,12 +850,12 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let mut dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let mut dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); assert_eq!(dispatch_table.get_ptr_mut(1), None); } @@ -852,12 +866,12 @@ mod tests { let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); - let fn_signature = fake_fn_signature(&fn_name, &[], return_type, Privacy::Public); + let fn_prototype = fake_fn_prototype(&fn_name, &[], return_type); - let signatures = &[fn_signature]; + let prototypes = &[fn_prototype]; let fn_ptrs = &mut [ptr::null()]; - let mut dispatch_table = fake_dispatch_table(signatures, fn_ptrs); + let mut dispatch_table = fake_dispatch_table(prototypes, fn_ptrs); assert_eq!(dispatch_table.get_ptr_mut(0), Some(&mut fn_ptrs[0])); } diff --git a/crates/mun_abi/src/function_info.rs b/crates/mun_abi/src/function_info.rs index 79d5b49b8..700ce824d 100644 --- a/crates/mun_abi/src/function_info.rs +++ b/crates/mun_abi/src/function_info.rs @@ -1,21 +1,23 @@ -use crate::{FunctionInfo, FunctionSignature, HasStaticTypeInfo, Privacy, TypeInfo}; +use crate::{ + FunctionDefinition, FunctionPrototype, FunctionSignature, HasStaticTypeInfo, TypeInfo, +}; use std::{ffi::CString, ptr}; -/// Owned storage for C-style `FunctionInfo`. -pub struct FunctionInfoStorage { +/// Owned storage for C-style `FunctionDefinition`. +pub struct FunctionDefinitionStorage { _name: CString, _type_infos: Vec<&'static TypeInfo>, } -impl FunctionInfoStorage { - /// Constructs a new `FunctionInfo`, the data of which is stored in a `FunctionInfoStorage`. +impl FunctionDefinitionStorage { + /// Constructs a new `FunctionDefinition`, the data of which is stored in a + /// `FunctionDefinitionStorage`. pub fn new_function( name: &str, args: &[&'static TypeInfo], ret: Option<&'static TypeInfo>, - privacy: Privacy, fn_ptr: *const std::ffi::c_void, - ) -> (FunctionInfo, FunctionInfoStorage) { + ) -> (FunctionDefinition, FunctionDefinitionStorage) { let name = CString::new(name).unwrap(); let type_infos: Vec<&'static TypeInfo> = args.iter().copied().collect(); @@ -26,18 +28,19 @@ impl FunctionInfoStorage { ptr::null() }; - let fn_info = FunctionInfo { - signature: FunctionSignature { + let fn_info = FunctionDefinition { + prototype: FunctionPrototype { name: name.as_ptr(), - arg_types: type_infos.as_ptr() as *const *const _, - return_type, - num_arg_types, - privacy, + signature: FunctionSignature { + arg_types: type_infos.as_ptr() as *const *const _, + return_type, + num_arg_types, + }, }, fn_ptr, }; - let fn_storage = FunctionInfoStorage { + let fn_storage = FunctionDefinitionStorage { _name: name, _type_infos: type_infos, }; @@ -46,10 +49,10 @@ impl FunctionInfoStorage { } } -/// A value-to-`FunctionInfo` conversion that consumes the input value. -pub trait IntoFunctionInfo { +/// A value-to-`FunctionDefinition` conversion that consumes the input value. +pub trait IntoFunctionDefinition { /// Performs the conversion. - fn into>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage); + fn into>(self, name: S) -> (FunctionDefinition, FunctionDefinitionStorage); } macro_rules! into_function_info_impl { @@ -57,29 +60,27 @@ macro_rules! into_function_info_impl { extern "C" fn($($T:ident),*) -> $R:ident; )+) => { $( - impl<$R: HasStaticTypeInfo, $($T: HasStaticTypeInfo,)*> IntoFunctionInfo + impl<$R: HasStaticTypeInfo, $($T: HasStaticTypeInfo,)*> IntoFunctionDefinition for extern "C" fn($($T),*) -> $R { - fn into>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage) { - FunctionInfoStorage::new_function( + fn into>(self, name: S) -> (FunctionDefinition, FunctionDefinitionStorage) { + FunctionDefinitionStorage::new_function( name.as_ref(), &[$($T::type_info(),)*], Some($R::type_info()), - privacy, self as *const std::ffi::c_void, ) } } - impl<$($T: HasStaticTypeInfo,)*> IntoFunctionInfo + impl<$($T: HasStaticTypeInfo,)*> IntoFunctionDefinition for extern "C" fn($($T),*) { - fn into>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage) { - FunctionInfoStorage::new_function( + fn into>(self, name: S) -> (FunctionDefinition, FunctionDefinitionStorage) { + FunctionDefinitionStorage::new_function( name.as_ref(), &[$($T::type_info(),)*], None, - privacy, self as *const std::ffi::c_void, ) } diff --git a/crates/mun_abi/src/lib.rs b/crates/mun_abi/src/lib.rs index f4b4c958a..b20c489e0 100644 --- a/crates/mun_abi/src/lib.rs +++ b/crates/mun_abi/src/lib.rs @@ -12,7 +12,7 @@ mod static_type_map; mod type_info; pub use autogen::*; -pub use function_info::{FunctionInfoStorage, IntoFunctionInfo}; +pub use function_info::{FunctionDefinitionStorage, IntoFunctionDefinition}; pub use type_info::HasStaticTypeInfo; /// The Mun ABI prelude @@ -20,7 +20,9 @@ pub use type_info::HasStaticTypeInfo; /// The *prelude* contains imports that are used almost every time. pub mod prelude { pub use crate::autogen::*; - pub use crate::{HasStaticTypeInfo, IntoFunctionInfo, Privacy, StructMemoryKind, TypeGroup}; + pub use crate::{ + HasStaticTypeInfo, IntoFunctionDefinition, Privacy, StructMemoryKind, TypeGroup, + }; } /// Represents the kind of memory management a struct uses. diff --git a/crates/mun_codegen/src/code_gen/symbols.rs b/crates/mun_codegen/src/code_gen/symbols.rs index 5c7f293cd..9252e6bd8 100644 --- a/crates/mun_codegen/src/code_gen/symbols.rs +++ b/crates/mun_codegen/src/code_gen/symbols.rs @@ -16,8 +16,8 @@ use inkwell::{ }; use std::collections::HashSet; -/// Construct a `MunFunctionSignature` struct for the specified HIR function. -fn gen_signature_from_function( +/// Construct a `MunFunctionPrototype` struct for the specified HIR function. +fn gen_prototype_from_function( db: &D, module: &Module, types: &AbiTypes, @@ -52,8 +52,7 @@ fn gen_signature_from_function( ); let num_params = fn_sig.params().len(); - types.function_signature_type.const_named_struct(&[ - name_ir.into(), + let signature = types.function_signature_type.const_named_struct(&[ param_types.into(), ret_type_ir.into(), module @@ -61,12 +60,15 @@ fn gen_signature_from_function( .i16_type() .const_int(num_params as u64, false) .into(), - module.get_context().i8_type().const_int(0, false).into(), - ]) + ]); + + types + .function_prototype_type + .const_named_struct(&[name_ir.into(), signature.into()]) } -/// Construct a `MunFunctionSignature` struct for the specified dispatch table function. -fn gen_signature_from_dispatch_entry( +/// Construct a `MunFunctionPrototype` struct for the specified dispatch table function. +fn gen_prototype_from_dispatch_entry( module: &Module, types: &AbiTypes, function: &DispatchableFunction, @@ -103,8 +105,7 @@ fn gen_signature_from_dispatch_entry( ); let num_params = function.prototype.arg_types.len(); - types.function_signature_type.const_named_struct(&[ - name_str.into(), + let signature = types.function_signature_type.const_named_struct(&[ param_types.into(), ret_type_ir.into(), module @@ -112,8 +113,11 @@ fn gen_signature_from_dispatch_entry( .i16_type() .const_int(num_params as u64, false) .into(), - module.get_context().i8_type().const_int(0, false).into(), - ]) + ]); + + types + .function_prototype_type + .const_named_struct(&[name_str.into(), signature.into()]) } /// Given a function, construct a pointer to a `MunTypeInfo` global that represents the return type @@ -155,8 +159,8 @@ fn gen_signature_return_type_from_type_info( } /// Construct a global that holds a reference to all functions. e.g.: -/// MunFunctionInfo[] info = { ... } -fn gen_function_info_array<'a, D: IrDatabase>( +/// MunFunctionDefinition[] definitions = { ... } +fn get_function_definition_array<'a, D: IrDatabase>( db: &D, module: &Module, types: &AbiTypes, @@ -175,16 +179,16 @@ fn gen_function_info_array<'a, D: IrDatabase>( value.set_linkage(Linkage::Private); // Generate the signature from the function - let signature = gen_signature_from_function(db, module, types, *f); + let prototype = gen_prototype_from_function(db, module, types, *f); // Generate the function info value - types.function_info_type.const_named_struct(&[ - signature.into(), + types.function_definition_type.const_named_struct(&[ + prototype.into(), value.as_global_value().as_pointer_value().into(), ]) }) .collect(); - let function_infos = types.function_info_type.const_array(&function_infos); + let function_infos = types.function_definition_type.const_array(&function_infos); gen_global(module, &function_infos, "fn.get_info.functions") } @@ -201,7 +205,7 @@ fn gen_dispatch_table( let signatures: Vec = dispatch_table .entries() .iter() - .map(|entry| gen_signature_from_dispatch_entry(module, types, entry)) + .map(|entry| gen_prototype_from_dispatch_entry(module, types, entry)) .collect(); // Construct an IR array from the signatures @@ -255,7 +259,7 @@ pub(super) fn gen_reflection_ir( let abi_types = gen_abi_types(&module.get_context()); let num_functions = api.len(); - let function_info = gen_function_info_array(db, module, &abi_types, api.iter()); + let function_info = get_function_definition_array(db, module, &abi_types, api.iter()); let type_table_ir = if let Some(type_table) = module.get_global(TypeTable::NAME) { type_table.as_pointer_value() diff --git a/crates/mun_codegen/src/ir/abi_types.rs b/crates/mun_codegen/src/ir/abi_types.rs index 900ccf799..2df1f21f2 100644 --- a/crates/mun_codegen/src/ir/abi_types.rs +++ b/crates/mun_codegen/src/ir/abi_types.rs @@ -9,7 +9,8 @@ pub(crate) struct AbiTypes { pub privacy_type: IntType, pub type_info_type: StructType, pub function_signature_type: StructType, - pub function_info_type: StructType, + pub function_prototype_type: StructType, + pub function_definition_type: StructType, pub struct_info_type: StructType, pub module_info_type: StructType, pub dispatch_table_type: StructType, @@ -48,20 +49,28 @@ pub(crate) fn gen_abi_types(context: &Context) -> AbiTypes { let function_signature_type = context.opaque_struct_type("struct.MunFunctionSignature"); function_signature_type.set_body( &[ - str_type.into(), // name type_info_ptr_type.ptr_type(AddressSpace::Const).into(), // arg_types type_info_ptr_type.into(), // return_type context.i16_type().into(), // num_arg_types - privacy_type.into(), // privacy ], false, ); - // Construct the `MunFunctionInfo` struct - let function_info_type = context.opaque_struct_type("struct.MunFunctionInfo"); - function_info_type.set_body( + // Construct the `MunFunctionSignature` type + let function_prototype_type = context.opaque_struct_type("struct.MunFunctionPrototype"); + function_prototype_type.set_body( &[ + str_type.into(), // name function_signature_type.into(), // signature + ], + false, + ); + + // Construct the `MunFunctionDefinition` struct + let function_definition_type = context.opaque_struct_type("struct.MunFunctionDefinition"); + function_definition_type.set_body( + &[ + function_prototype_type.into(), // prototype context .void_type() .fn_type(&[], false) @@ -88,11 +97,13 @@ pub(crate) fn gen_abi_types(context: &Context) -> AbiTypes { let module_info_type = context.opaque_struct_type("struct.MunModuleInfo"); module_info_type.set_body( &[ - str_type.into(), // path - function_info_type.ptr_type(AddressSpace::Const).into(), // functions - context.i32_type().into(), // num_functions + str_type.into(), // path + function_definition_type + .ptr_type(AddressSpace::Const) + .into(), // functions + context.i32_type().into(), // num_functions type_info_ptr_type.ptr_type(AddressSpace::Const).into(), // types - context.i32_type().into(), // num_types + context.i32_type().into(), // num_types ], false, ); @@ -131,7 +142,8 @@ pub(crate) fn gen_abi_types(context: &Context) -> AbiTypes { privacy_type, type_info_type, function_signature_type, - function_info_type, + function_prototype_type, + function_definition_type, struct_info_type, module_info_type, dispatch_table_type, diff --git a/crates/mun_runtime/src/assembly.rs b/crates/mun_runtime/src/assembly.rs index c3a438c90..7e3f135fa 100644 --- a/crates/mun_runtime/src/assembly.rs +++ b/crates/mun_runtime/src/assembly.rs @@ -62,7 +62,7 @@ impl Assembly { .symbols .functions() .iter() - .map(|f| f.signature.name()) + .map(|f| f.prototype.name()) .collect(); for (fn_ptr, fn_sig) in self.info.dispatch_table.iter() { @@ -97,24 +97,27 @@ impl Assembly { } } - for fn_info in self.info.symbols.functions().iter() { - let (fn_sig, _) = dependencies - .get(fn_info.signature.name()) + for fn_definition in self.info.symbols.functions().iter() { + let (fn_prototype, _) = dependencies + .get(fn_definition.prototype.name()) .expect("The dependency must exist after the previous check."); // TODO: This is a hack - if fn_info.signature.return_type() != fn_sig.return_type() - || fn_info.signature.arg_types().len() != fn_sig.arg_types().len() - || !fn_info + if fn_definition.prototype.signature.return_type() + != fn_prototype.signature.return_type() + || fn_definition.prototype.signature.arg_types().len() + != fn_prototype.signature.arg_types().len() + || !fn_definition + .prototype .signature .arg_types() .iter() - .zip(fn_sig.arg_types().iter()) + .zip(fn_prototype.signature.arg_types().iter()) .all(|(a, b)| PartialEq::eq(a, b)) { return Err(io::Error::new( io::ErrorKind::NotFound, - format!("Failed to link: function '{}' is missing. A function with the same name does exist, but the signatures do not match (expected: {}, found: {}).", fn_sig.name(), fn_sig, fn_info.signature), + format!("Failed to link: function '{}' is missing. A function with the same name does exist, but the signatures do not match (expected: {}, found: {}).", fn_prototype.name(), fn_prototype, fn_definition.prototype), )); } } @@ -129,14 +132,14 @@ impl Assembly { /// an `Assembly` - in the `load` function - making this function safe. pub fn link(&mut self, runtime_dispatch_table: &mut DispatchTable) { for function in self.info.symbols.functions() { - runtime_dispatch_table.insert_fn(function.signature.name(), function.clone()); + runtime_dispatch_table.insert_fn(function.prototype.name(), function.clone()); } - for (dispatch_ptr, fn_signature) in self.info.dispatch_table.iter_mut() { + for (dispatch_ptr, fn_prototype) in self.info.dispatch_table.iter_mut() { if dispatch_ptr.is_null() { let fn_ptr = runtime_dispatch_table - .get_fn(fn_signature.name()) - .unwrap_or_else(|| panic!("Function '{}' is expected to exist.", fn_signature)) + .get_fn(fn_prototype.name()) + .unwrap_or_else(|| panic!("Function '{}' is expected to exist.", fn_prototype)) .fn_ptr; *dispatch_ptr = fn_ptr; } @@ -183,7 +186,7 @@ impl Assembly { // Remove the old assembly's functions for function in self.info.symbols.functions() { - runtime_dispatch_table.remove_fn(function.signature.name()); + runtime_dispatch_table.remove_fn(function.prototype.name()); } new_assembly.link(runtime_dispatch_table); diff --git a/crates/mun_runtime/src/lib.rs b/crates/mun_runtime/src/lib.rs index 5b8e98420..bb7fedafa 100644 --- a/crates/mun_runtime/src/lib.rs +++ b/crates/mun_runtime/src/lib.rs @@ -40,7 +40,7 @@ pub use crate::{ reflection::{ArgumentReflection, ReturnTypeReflection}, struct_ref::StructRef, }; -pub use abi::IntoFunctionInfo; +pub use abi::IntoFunctionDefinition; /// Options for the construction of a [`Runtime`]. pub struct RuntimeOptions { @@ -49,7 +49,7 @@ pub struct RuntimeOptions { /// Delay during which filesystem events are collected, deduplicated, and after which emitted. pub delay: Duration, /// Custom user injected functions - pub user_functions: Vec<(abi::FunctionInfo, abi::FunctionInfoStorage)>, + pub user_functions: Vec<(abi::FunctionDefinition, abi::FunctionDefinitionStorage)>, } /// A builder for the [`Runtime`]. @@ -76,10 +76,12 @@ impl RuntimeBuilder { } /// Adds a custom user function to the dispatch table. - pub fn insert_fn, F: abi::IntoFunctionInfo>(mut self, name: S, func: F) -> Self { - self.options - .user_functions - .push(func.into(name, abi::Privacy::Public)); + pub fn insert_fn, F: abi::IntoFunctionDefinition>( + mut self, + name: S, + func: F, + ) -> Self { + self.options.user_functions.push(func.into(name)); self } @@ -96,13 +98,13 @@ type DependencyMap = FxHashMap>; /// A runtime dispatch table that maps full paths to function and struct information. #[derive(Default)] pub struct DispatchTable { - functions: FxHashMap, - fn_dependencies: FxHashMap>, + functions: FxHashMap, + fn_dependencies: FxHashMap>, } impl DispatchTable { - /// Retrieves the [`abi::abi::FunctionInfo`] corresponding to `fn_path`, if it exists. - pub fn get_fn(&self, fn_path: &str) -> Option<&abi::FunctionInfo> { + /// Retrieves the [`abi::FunctionDefinition`] corresponding to `fn_path`, if it exists. + pub fn get_fn(&self, fn_path: &str) -> Option<&abi::FunctionDefinition> { self.functions.get(fn_path) } @@ -113,13 +115,13 @@ impl DispatchTable { pub fn insert_fn( &mut self, fn_path: S, - fn_info: abi::FunctionInfo, - ) -> Option { + fn_info: abi::FunctionDefinition, + ) -> Option { self.functions.insert(fn_path.to_string(), fn_info) } /// Removes and returns the `fn_info` corresponding to `fn_path`, if it exists. - pub fn remove_fn>(&mut self, fn_path: S) -> Option { + pub fn remove_fn>(&mut self, fn_path: S) -> Option { self.functions.remove(fn_path.as_ref()) } @@ -128,7 +130,7 @@ impl DispatchTable { &mut self, assembly_path: S, fn_path: T, - fn_signature: abi::FunctionSignature, + fn_prototype: abi::FunctionPrototype, ) { let dependencies = self .fn_dependencies @@ -137,7 +139,7 @@ impl DispatchTable { let (_, counter) = dependencies .entry(fn_path.to_string()) - .or_insert((fn_signature, 0)); + .or_insert((fn_prototype, 0)); *counter += 1; } @@ -165,7 +167,7 @@ pub struct Runtime { watcher: RecommendedWatcher, watcher_rx: Receiver, gc: Arc, - _user_functions: Vec, + _user_functions: Vec, } /// Retrieve the allocator using the provided handle. @@ -206,15 +208,14 @@ impl Runtime { let mut dispatch_table = DispatchTable::default(); // Add internal functions - options.user_functions.push(IntoFunctionInfo::into( + options.user_functions.push(IntoFunctionDefinition::into( new as extern "C" fn(*const abi::TypeInfo, *mut ffi::c_void) -> *const *mut ffi::c_void, "new", - abi::Privacy::Public, )); let mut storages = Vec::with_capacity(options.user_functions.len()); for (info, storage) in options.user_functions.into_iter() { - dispatch_table.insert_fn(info.signature.name().to_string(), info); + dispatch_table.insert_fn(info.prototype.name().to_string(), info); storages.push(storage) } @@ -256,8 +257,8 @@ impl Runtime { Ok(()) } - /// Retrieves the function information corresponding to `function_name`, if available. - pub fn get_function_info(&self, function_name: &str) -> Option<&abi::FunctionInfo> { + /// Retrieves the function definition corresponding to `function_name`, if available. + pub fn get_function_definition(&self, function_name: &str) -> Option<&abi::FunctionDefinition> { self.dispatch_table.get_fn(function_name) } diff --git a/crates/mun_runtime/src/macros.rs b/crates/mun_runtime/src/macros.rs index 68ae84ca7..10a94b265 100644 --- a/crates/mun_runtime/src/macros.rs +++ b/crates/mun_runtime/src/macros.rs @@ -97,13 +97,13 @@ macro_rules! invoke_fn_impl { ) -> core::result::Result> { let runtime_ref = runtime.borrow(); match runtime_ref - .get_function_info(function_name) + .get_function_definition(function_name) .ok_or_else(|| format!("Failed to obtain function '{}'", function_name)) .and_then(|function_info| { // Validate function signature let num_args = $crate::count_args!($($T),*); - let arg_types = function_info.signature.arg_types(); + let arg_types = function_info.prototype.signature.arg_types(); if arg_types.len() != num_args { return Err(format!( "Invalid number of arguments. Expected: {}. Found: {}.", @@ -127,7 +127,7 @@ macro_rules! invoke_fn_impl { idx += 1; )* - if let Some(return_type) = function_info.signature.return_type() { + if let Some(return_type) = function_info.prototype.signature.return_type() { crate::reflection::equals_return_type::(return_type) } else if <() as ReturnTypeReflection>::type_guid() != Output::type_guid() { Err((<() as ReturnTypeReflection>::type_name(), Output::type_name())) diff --git a/crates/mun_runtime/tests/marshalling.rs b/crates/mun_runtime/tests/marshalling.rs index 6251e2b6c..c04b7e1d1 100644 --- a/crates/mun_runtime/tests/marshalling.rs +++ b/crates/mun_runtime/tests/marshalling.rs @@ -232,15 +232,15 @@ fn compiler_valid_utf8() { ); let borrowed = driver.runtime_mut().borrow(); - let foo_func = borrowed.get_function_info("foo").unwrap(); + let foo_func = borrowed.get_function_definition("foo").unwrap(); assert_eq!( - unsafe { CStr::from_ptr(foo_func.signature.name) } + unsafe { CStr::from_ptr(foo_func.prototype.name) } .to_str() .is_ok(), true ); - for arg_type in foo_func.signature.arg_types() { + for arg_type in foo_func.prototype.signature.arg_types() { assert_eq!( unsafe { CStr::from_ptr(arg_type.name) }.to_str().is_ok(), true @@ -259,7 +259,7 @@ fn compiler_valid_utf8() { } } assert_eq!( - unsafe { CStr::from_ptr((*foo_func.signature.return_type).name) } + unsafe { CStr::from_ptr((*foo_func.prototype.signature.return_type).name) } .to_str() .is_ok(), true diff --git a/crates/mun_runtime/tests/memory.rs b/crates/mun_runtime/tests/memory.rs index 74580a38a..82c94e645 100644 --- a/crates/mun_runtime/tests/memory.rs +++ b/crates/mun_runtime/tests/memory.rs @@ -521,12 +521,12 @@ fn delete_used_struct() { assert!(driver .runtime_mut() .borrow() - .get_function_info("foo_new") + .get_function_definition("foo_new") .is_none()); assert!(driver .runtime_mut() .borrow() - .get_function_info("bar_new") + .get_function_definition("bar_new") .is_some()); assert_eq!(foo.get::("a").unwrap(), a); assert_eq!(foo.get::("b").unwrap(), b); diff --git a/crates/mun_runtime/tests/util.rs b/crates/mun_runtime/tests/util.rs index 1e1acaed0..b19b760d1 100644 --- a/crates/mun_runtime/tests/util.rs +++ b/crates/mun_runtime/tests/util.rs @@ -1,7 +1,7 @@ #![allow(dead_code, unused_macros)] use mun_compiler::{Config, DisplayColor, Driver, FileId, PathOrInline, RelativePathBuf}; -use mun_runtime::{IntoFunctionInfo, Runtime, RuntimeBuilder}; +use mun_runtime::{IntoFunctionDefinition, Runtime, RuntimeBuilder}; use std::io::Cursor; use std::{cell::RefCell, path::PathBuf, rc::Rc, thread::sleep, time::Duration}; @@ -108,7 +108,7 @@ impl TestDriver { } /// Adds a custom user function to the dispatch table. - pub fn insert_fn, F: IntoFunctionInfo>(mut self, name: S, func: F) -> Self { + pub fn insert_fn, F: IntoFunctionDefinition>(mut self, name: S, func: F) -> Self { self.runtime = match self.runtime { RuntimeOrBuilder::Builder(builder) => { RuntimeOrBuilder::Builder(builder.insert_fn(name, func)) diff --git a/crates/mun_runtime_capi/ffi b/crates/mun_runtime_capi/ffi index da92a600a..6534434b7 160000 --- a/crates/mun_runtime_capi/ffi +++ b/crates/mun_runtime_capi/ffi @@ -1 +1 @@ -Subproject commit da92a600a0ad7b8c4531f2eb427bc56cd238c481 +Subproject commit 6534434b7dfdbfac1fc766736094a7419e6fd890 diff --git a/crates/mun_runtime_capi/src/lib.rs b/crates/mun_runtime_capi/src/lib.rs index 0ff05a054..9ef5d4f4f 100644 --- a/crates/mun_runtime_capi/src/lib.rs +++ b/crates/mun_runtime_capi/src/lib.rs @@ -44,8 +44,6 @@ pub struct RuntimeHandle(*mut c_void); /// /// The runtime must be manually destructed using [`mun_runtime_destroy`]. /// -/// TODO: expose interval at which the runtime's file watcher operates. -/// /// # Safety /// /// This function receives raw pointers as parameters. If any of the arguments is a null pointer, @@ -79,13 +77,13 @@ pub unsafe extern "C" fn mun_runtime_create( } }; - let options = RuntimeOptions { + let runtime_options = RuntimeOptions { library_path: library_path.into(), delay: Duration::from_millis(10), user_functions: Default::default(), }; - let runtime = match Runtime::new(options) { + let runtime = match Runtime::new(runtime_options) { Ok(runtime) => runtime, Err(e) => return HUB.errors.register(e), }; @@ -102,8 +100,9 @@ pub extern "C" fn mun_runtime_destroy(handle: RuntimeHandle) { } } -/// Retrieves the [`FunctionInfo`] for `fn_name` from the runtime corresponding to `handle`. If -/// successful, `has_fn_info` and `fn_info` are set, otherwise a non-zero error handle is returned. +/// Retrieves the [`FunctionDefinition`] for `fn_name` from the runtime corresponding to `handle`. +/// If successful, `has_fn_info` and `fn_info` are set, otherwise a non-zero error handle is +/// returned. /// /// If a non-zero error handle is returned, it must be manually destructed using /// [`mun_error_destroy`]. @@ -113,11 +112,11 @@ pub extern "C" fn mun_runtime_destroy(handle: RuntimeHandle) { /// This function receives raw pointers as parameters. If any of the arguments is a null pointer, /// an error will be returned. Passing pointers to invalid data, will lead to undefined behavior. #[no_mangle] -pub unsafe extern "C" fn mun_runtime_get_function_info( +pub unsafe extern "C" fn mun_runtime_get_function_definition( handle: RuntimeHandle, fn_name: *const c_char, has_fn_info: *mut bool, - fn_info: *mut abi::FunctionInfo, + fn_definition: *mut abi::FunctionDefinition, ) -> ErrorHandle { let runtime = match (handle.0 as *mut Runtime).as_ref() { Some(runtime) => runtime, @@ -152,7 +151,7 @@ pub unsafe extern "C" fn mun_runtime_get_function_info( } }; - let fn_info = match fn_info.as_mut() { + let fn_definition = match fn_definition.as_mut() { Some(info) => info, None => { return HUB @@ -161,10 +160,10 @@ pub unsafe extern "C" fn mun_runtime_get_function_info( } }; - match runtime.get_function_info(fn_name) { + match runtime.get_function_definition(fn_name) { Some(info) => { *has_fn_info = true; - *fn_info = info.clone(); + *fn_definition = info.clone(); } None => *has_fn_info = false, } diff --git a/crates/mun_runtime_capi/src/tests.rs b/crates/mun_runtime_capi/src/tests.rs index 57e69fdde..a09b4cbe2 100644 --- a/crates/mun_runtime_capi/src/tests.rs +++ b/crates/mun_runtime_capi/src/tests.rs @@ -84,7 +84,7 @@ macro_rules! test_invalid_runtime { } test_invalid_runtime!( - runtime_get_function_info(ptr::null(), ptr::null_mut(), ptr::null_mut()), + runtime_get_function_definition(ptr::null(), ptr::null_mut(), ptr::null_mut()), runtime_update(ptr::null_mut()), gc_alloc(UnsafeTypeInfo::new(NonNull::dangling()), ptr::null_mut()), gc_ptr_type(mem::zeroed::(), ptr::null_mut()), @@ -149,7 +149,7 @@ fn test_runtime_get_function_info_invalid_fn_name() { ); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, ptr::null(), ptr::null_mut(), @@ -176,7 +176,7 @@ fn test_runtime_get_function_info_invalid_fn_name_encoding() { let invalid_encoding = ['�', '\0']; let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, invalid_encoding.as_ptr() as *const _, ptr::null_mut(), @@ -203,7 +203,7 @@ fn test_runtime_get_function_info_invalid_has_fn_info() { let fn_name = CString::new("main").expect("Invalid function name"); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), ptr::null_mut(), @@ -231,7 +231,7 @@ fn test_runtime_get_function_info_invalid_fn_info() { let fn_name = CString::new("main").expect("Invalid function name"); let mut has_fn_info = false; let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), &mut has_fn_info as *mut _, @@ -258,18 +258,18 @@ fn test_runtime_get_function_info() { let fn_name = CString::new("main").expect("Invalid function name"); let mut has_fn_info = false; - let mut fn_info = MaybeUninit::uninit(); + let mut fn_definition = MaybeUninit::uninit(); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), &mut has_fn_info as *mut _, - fn_info.as_mut_ptr(), + fn_definition.as_mut_ptr(), ) }; assert_eq!(handle.token(), 0); assert!(has_fn_info); - let _fn_info = unsafe { fn_info.assume_init() }; + let _fn_definition = unsafe { fn_definition.assume_init() }; } #[test] @@ -315,20 +315,20 @@ fn test_gc_alloc_invalid_obj() { ); let fn_name = CString::new("main").expect("Invalid function name"); let mut has_fn_info = false; - let mut fn_info = MaybeUninit::uninit(); + let mut fn_definition = MaybeUninit::uninit(); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), &mut has_fn_info as *mut _, - fn_info.as_mut_ptr(), + fn_definition.as_mut_ptr(), ) }; assert_eq!(handle.token(), 0); - let fn_info = unsafe { fn_info.assume_init() }; + let fn_definition = unsafe { fn_definition.assume_init() }; // TODO: Simplify this once we have `mun_runtime_find_type_info` - let return_type = fn_info.signature.return_type().unwrap(); + let return_type = fn_definition.prototype.signature.return_type().unwrap(); let return_type = UnsafeTypeInfo::new(NonNull::new(return_type as *const abi::TypeInfo as *mut _).unwrap()); @@ -353,20 +353,20 @@ fn test_gc_alloc() { ); let fn_name = CString::new("main").expect("Invalid function name"); let mut has_fn_info = false; - let mut fn_info = MaybeUninit::uninit(); + let mut fn_definition = MaybeUninit::uninit(); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), &mut has_fn_info as *mut _, - fn_info.as_mut_ptr(), + fn_definition.as_mut_ptr(), ) }; assert_eq!(handle.token(), 0); - let fn_info = unsafe { fn_info.assume_init() }; + let fn_definition = unsafe { fn_definition.assume_init() }; // TODO: Simplify this once we have `mun_runtime_find_type_info` - let return_type = fn_info.signature.return_type().unwrap(); + let return_type = fn_definition.prototype.signature.return_type().unwrap(); let return_type = UnsafeTypeInfo::new(NonNull::new(return_type as *const abi::TypeInfo as *mut _).unwrap()); @@ -417,20 +417,20 @@ fn test_gc_ptr_type() { ); let fn_name = CString::new("main").expect("Invalid function name"); let mut has_fn_info = false; - let mut fn_info = MaybeUninit::uninit(); + let mut fn_definition = MaybeUninit::uninit(); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), &mut has_fn_info as *mut _, - fn_info.as_mut_ptr(), + fn_definition.as_mut_ptr(), ) }; assert_eq!(handle.token(), 0); - let fn_info = unsafe { fn_info.assume_init() }; + let fn_definition = unsafe { fn_definition.assume_init() }; // TODO: Simplify this once we have `mun_runtime_find_type_info` - let return_type = fn_info.signature.return_type().unwrap(); + let return_type = fn_definition.prototype.signature.return_type().unwrap(); let return_type = UnsafeTypeInfo::new(NonNull::new(return_type as *const abi::TypeInfo as *mut _).unwrap()); @@ -464,20 +464,20 @@ fn test_gc_rooting() { ); let fn_name = CString::new("main").expect("Invalid function name"); let mut has_fn_info = false; - let mut fn_info = MaybeUninit::uninit(); + let mut fn_definition = MaybeUninit::uninit(); let handle = unsafe { - mun_runtime_get_function_info( + mun_runtime_get_function_definition( driver.runtime, fn_name.as_ptr(), &mut has_fn_info as *mut _, - fn_info.as_mut_ptr(), + fn_definition.as_mut_ptr(), ) }; assert_eq!(handle.token(), 0); - let fn_info = unsafe { fn_info.assume_init() }; + let fn_definition = unsafe { fn_definition.assume_init() }; // TODO: Simplify this once we have `mun_runtime_find_type_info` - let return_type = fn_info.signature.return_type().unwrap(); + let return_type = fn_definition.prototype.signature.return_type().unwrap(); let return_type = UnsafeTypeInfo::new(NonNull::new(return_type as *const abi::TypeInfo as *mut _).unwrap()); @@ -489,6 +489,7 @@ fn test_gc_rooting() { assert_ne!(unsafe { obj.deref::() }, ptr::null()); let handle = unsafe { mun_gc_root(driver.runtime, obj) }; + assert_eq!(handle.token(), 0); let mut reclaimed = false; diff --git a/crates/tools/src/abi.rs b/crates/tools/src/abi.rs index 3f1939f35..0d2244f82 100644 --- a/crates/tools/src/abi.rs +++ b/crates/tools/src/abi.rs @@ -58,7 +58,7 @@ pub fn generate(mode: Mode) -> Result<()> { .derive_copy(false) .derive_debug(false) .raw_line("#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]") - .raw_line("use crate::{Privacy, StructMemoryKind, TypeGroup};") + .raw_line("use crate::{StructMemoryKind, TypeGroup};") .generate() .map_err(|_| format_err!("Unable to generate bindings from 'mun_abi.h'"))?;