add some function name mangling to xs exports

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2020-10-16 11:08:50 +02:00
parent 2290f60a05
commit 9525acd643
7 changed files with 36 additions and 7 deletions

View File

@ -50,6 +50,20 @@ impl TryFrom<AttributeArgs> for ModuleAttrs {
}
}
impl ModuleAttrs {
pub fn mangle_package_name(&self) -> String {
let mut out = String::with_capacity(self.package_name.len());
for ch in self.package_name.chars() {
if ch.is_ascii_alphabetic() || ch.is_ascii_digit() {
out.push(ch);
} else {
out.push('_');
}
}
out
}
}
pub struct FunctionAttrs {
pub xs_name: Option<Ident>,
}

View File

@ -12,7 +12,11 @@ pub struct XSub {
pub tokens: TokenStream,
}
pub fn handle_function(attr: FunctionAttrs, func: syn::ItemFn) -> Result<XSub, Error> {
pub fn handle_function(
attr: FunctionAttrs,
func: syn::ItemFn,
mangled_package_name: Option<&str>,
) -> Result<XSub, Error> {
//let vis = core::mem::replace(&mut func.vis, syn::Visibility::Inherited);
//if let syn::Visibility::Public(_) = vis {
// // ok
@ -32,7 +36,10 @@ pub fn handle_function(attr: FunctionAttrs, func: syn::ItemFn) -> Result<XSub, E
let name = &sig.ident;
let xs_name = attr
.xs_name
.unwrap_or_else(|| Ident::new(&format!("xs_{}", name), name.span()));
.unwrap_or_else(|| match mangled_package_name {
None => Ident::new(&format!("xs_{}", name), name.span()),
Some(prefix) => Ident::new(&format!("xs_{}_{}", prefix, name), name.span()),
});
let impl_xs_name = Ident::new(&format!("impl_xs_{}", name), name.span());
let mut extract_arguments = TokenStream::new();

View File

@ -158,7 +158,7 @@ fn export_impl(attr: AttributeArgs, item: TokenStream) -> Result<TokenStream, Er
let func: syn::ItemFn = syn::parse2(item)?;
let attr = attribs::FunctionAttrs::try_from(attr)?;
let func = function::handle_function(attr, func)?;
let func = function::handle_function(attr, func, None)?;
Ok(func.tokens)
}

View File

@ -15,6 +15,7 @@ use crate::package::Package;
pub fn handle_module(attr: AttributeArgs, mut module: syn::ItemMod) -> Result<TokenStream, Error> {
let mut package = Package::with_attrs(attr)?;
let mangled_package_name = package.mangle_package_name();
if let Some((_brace, ref mut items)) = module.content {
for item in items.iter_mut() {
@ -42,7 +43,11 @@ pub fn handle_module(attr: AttributeArgs, mut module: syn::ItemMod) -> Result<To
// if we removed an #[export] macro this is an exported function:
if let Some(attribs) = attribs {
let func = crate::function::handle_function(attribs, func)?;
let func = crate::function::handle_function(
attribs,
func,
Some(&mangled_package_name),
)?;
*item = syn::Item::Verbatim(func.tokens);
package.export_named(

View File

@ -126,6 +126,10 @@ impl Package {
Ok(())
}
pub fn mangle_package_name(&self) -> String {
self.attrs.mangle_package_name()
}
}
mod kw {

View File

@ -1,4 +1,3 @@
#[cfg(feature = "rust142")]
/// The fhe following requires rust 1.42 to work, as custom attributes on inline modules has only
/// been stabilized then.
mod pkg142;

View File

@ -1,9 +1,9 @@
#[perlmod::package(name = "RSPM::Foo", lib = "perlmod_test")]
#[perlmod::package(name = "RSPM::Foo142", lib = "perlmod_test")]
mod export {
use anyhow::{bail, Error};
#[export]
fn foo(a: u32, b: u32) -> Result<u32, Error> {
fn foo142(a: u32, b: u32) -> Result<u32, Error> {
if a == 42 {
bail!("dying on magic number");
}