Skip to content

Commit

Permalink
Use link_name for dynamic library loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Molot2032 committed Jan 30, 2025
1 parent 59a43e1 commit 6364365
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 42 deletions.

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
66 changes: 39 additions & 27 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,17 +779,25 @@ 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 link_name =
self.mangled_name().unwrap_or_else(|| self.name());
if !utils::names_will_be_identical_after_mangling(
&canonical_name,
link_name,
None,
) {
// None means the canonical name will end up working out the same, so no need to add the attribute.
let link_name_attribute: Option<&str> =
self.link_name().or_else(|| {
let link_name =
self.mangled_name().unwrap_or_else(|| self.name());
if utils::names_will_be_identical_after_mangling(
&canonical_name,
link_name,
None,
) {
None
} else {
Some(link_name)
}
});

// Apply the `#[link_name]` attribute if necessary, but not if we're not generating dynamic library bindings as they're linked at runtime.
if let Some(link_name) = link_name_attribute {
if ctx.options().dynamic_library_name.is_none() {
attrs.push(attributes::link_name::<false>(link_name));
}
}
Expand All @@ -814,8 +822,10 @@ impl CodeGenerator for Var {
);

if ctx.options().dynamic_library_name.is_some() {
let symbol = link_name_attribute.unwrap_or(&canonical_name);
result.dynamic_items().push_var(
canonical_ident,
symbol,
self.ty()
.to_rust_ty_or_opaque(ctx, &())
.into_token_stream(),
Expand Down Expand Up @@ -4641,21 +4651,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 @@ -4667,8 +4675,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 @@ -4734,11 +4743,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

0 comments on commit 6364365

Please sign in to comment.