Skip to content

Use link_name for dynamic library loading #3101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions bindgen/codegen/dyngen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ impl DynamicItems {
pub(crate) fn push_func(
&mut self,
ident: &Ident,
symbol: &str,
abi: ClangAbi,
is_variadic: bool,
is_required: bool,
Expand Down Expand Up @@ -181,11 +182,12 @@ impl DynamicItems {
}

// N.B: Unwrap the signature upon construction if it is required to be resolved.
let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
let symbol_cstr =
codegen::helpers::ast_ty::cstr_expr(symbol.to_string());
let library_get = if ctx.options().wrap_unsafe_ops {
quote!(unsafe { __library.get(#ident_str) })
quote!(unsafe { __library.get(#symbol_cstr) })
} else {
quote!(__library.get(#ident_str))
quote!(__library.get(#symbol_cstr))
};

self.constructor_inits.push(if is_required {
Expand All @@ -206,6 +208,7 @@ impl DynamicItems {
pub fn push_var(
&mut self,
ident: &Ident,
symbol: &str,
ty: &TokenStream,
is_required: bool,
wrap_unsafe_ops: bool,
Expand All @@ -231,12 +234,13 @@ impl DynamicItems {
}
});

let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
let symbol_cstr =
codegen::helpers::ast_ty::cstr_expr(symbol.to_string());

let library_get = if wrap_unsafe_ops {
quote!(unsafe { __library.get::<*mut #ty>(#ident_str) })
quote!(unsafe { __library.get::<*mut #ty>(#symbol_cstr) })
} else {
quote!(__library.get::<*mut #ty>(#ident_str))
quote!(__library.get::<*mut #ty>(#symbol_cstr))
};

let qmark = if is_required { quote!(?) } else { quote!() };
Expand Down
47 changes: 25 additions & 22 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,20 +779,20 @@ impl CodeGenerator for Var {
}
}
} else {
// If necessary, apply a `#[link_name]` attribute
if let Some(link_name) = self.link_name() {
attrs.push(attributes::link_name::<false>(link_name));
} else {
let symbol: &str = self.link_name().unwrap_or_else(|| {
let link_name =
self.mangled_name().unwrap_or_else(|| self.name());
if !utils::names_will_be_identical_after_mangling(
if utils::names_will_be_identical_after_mangling(
&canonical_name,
link_name,
None,
) {
canonical_name.as_str()
} else {
attrs.push(attributes::link_name::<false>(link_name));
link_name
}
}
});

let maybe_mut = if self.is_const() {
quote! {}
Expand All @@ -816,6 +816,7 @@ impl CodeGenerator for Var {
if ctx.options().dynamic_library_name.is_some() {
result.dynamic_items().push_var(
&canonical_ident,
symbol,
&self
.ty()
.to_rust_ty_or_opaque(ctx, &())
Expand Down Expand Up @@ -4639,21 +4640,19 @@ impl CodeGenerator for Function {
write!(&mut canonical_name, "{times_seen}").unwrap();
}

let mut has_link_name_attr = false;
if let Some(link_name) = self.link_name() {
attributes.push(attributes::link_name::<false>(link_name));
has_link_name_attr = true;
} else {
let link_name = mangled_name.unwrap_or(name);
if !is_dynamic_function &&
!utils::names_will_be_identical_after_mangling(
&canonical_name,
link_name,
Some(abi),
)
{
let link_name_attr = self.link_name().or_else(|| {
let mangled_name = mangled_name.unwrap_or(name);
(!utils::names_will_be_identical_after_mangling(
&canonical_name,
mangled_name,
Some(abi),
))
.then(|| mangled_name)
});

if let Some(link_name) = link_name_attr {
if !is_dynamic_function {
attributes.push(attributes::link_name::<false>(link_name));
has_link_name_attr = true;
}
}

Expand All @@ -4665,8 +4664,9 @@ impl CodeGenerator for Function {
quote! { #[link(wasm_import_module = #name)] }
});

let should_wrap =
is_internal && ctx.options().wrap_static_fns && !has_link_name_attr;
let should_wrap = is_internal &&
ctx.options().wrap_static_fns &&
link_name_attr.is_none();

if should_wrap {
let name = canonical_name.clone() + ctx.wrap_static_fns_suffix();
Expand Down Expand Up @@ -4732,11 +4732,14 @@ impl CodeGenerator for Function {

// If we're doing dynamic binding generation, add to the dynamic items.
if is_dynamic_function {
let ident_str = ident.to_string();
let symbol = link_name_attr.unwrap_or(&ident_str);
let args_identifiers =
utils::fnsig_argument_identifiers(ctx, signature);
let ret_ty = utils::fnsig_return_ty(ctx, signature);
result.dynamic_items().push_func(
&ident,
symbol,
abi,
signature.is_variadic(),
ctx.options().dynamic_link_require_all,
Expand Down