Skip to content
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

[Feature Request] Allow the addition of custom Rust annotations to generated function definitions #2739

Open
mstrydom opened this issue Jan 27, 2024 · 4 comments

Comments

@mstrydom
Copy link
Contributor

mstrydom commented Jan 27, 2024

We would like to wrap all our calls into the FFI boundary with a standard piece of code. In particular. we would like to use cee_scape to solve some long_jmp behaviour from the code that we are calling into. A nice way to be able to do this is to have an annotation on the generated FFI code from rust-bindgen. We can then use this proc macro to generate the wrappers that we want.

This seemed like something that other users of rust-bindgen could use, as it provides a lot of flexibility with, what I hope is, very little investment from rust-bindgen.

This issue is to see if the contributors of rust-bindgen would be interested in adding such a feature and what they would require to be added.

My view is that we allow add a setting that adds a custom annotation to the extern block, lets say extern_annotation("my_crate::my_annotation")

rust-bindgen would then generate all functions as:

[my_crate::my_annotation]
extern "C" {
    pub fn my_c_function(
        ctype: *const ::std::os::raw::c_char,
    ) -> ::std::os::raw::c_int;
}

After this point, a user of rust-bindgen can put what they want/need inside the annotation implementation. Something like:

pub fn my_annotation(_args: TokenStream, input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemForeignMod);

    quote! {
        fn <macro code to get wrapping function name> {
            #input

            unsafe { my_c_function(ctype) }
        }
    }
    .into()
}

I assume we would want to add include and exclude configuration in case there someone does not want to put the annotation on all functions. Or one could argue that they can implement exclusions in their macro, but its probably cleaner to add in rust-bindgen

If there is an existing way of doing this in rust-bindgen already that I just missed, please let me know.

I am more than happy to take a stab at producing a pull request for this, although I would appreciate some help in finding the right code.

Any thoughts/help would be appreciated.

@mstrydom mstrydom changed the title [Feature Request] Allow the addition of custom Rust annotations to generated functions [Feature Request] Allow the addition of custom Rust annotations to generated function definitions Jan 27, 2024
@mstrydom
Copy link
Contributor Author

I did just see this code: https://github.com/rust-lang/rust-bindgen/blob/main/bindgen/codegen/postprocessing/merge_extern_blocks.rs#L6 . Which looks like some merging of extern blocks happen. I am checking the version I have been using and I see I am on 0.63, so some of the local behaviour I assumed might have changed in later versions.

@emilio
Copy link
Contributor

emilio commented Jan 31, 2024

We have already a wasm_import_module_name option that adds such an attribute where you want, afaict. Extending / generalizing that seems better. Given we merge the blocks I think it'd be simpler if we didn't add extra exclusion logic or what not.

@pvdrz
Copy link
Contributor

pvdrz commented Mar 7, 2024

this could also be seen as a generalization of the custom derive callback. Maybe it would make sense to introduce a callback to annotate any rust items with custom attributes and implement the existing callbacks on top of it instead.

@pvdrz
Copy link
Contributor

pvdrz commented Apr 3, 2024

We have already a wasm_import_module_name option that adds such an attribute where you want, afaict. Extending / generalizing that seems better. Given we merge the blocks I think it'd be simpler if we didn't add extra exclusion logic or what not.

I think younger me implemented the extern blocks merge so it only happens if the extern blocks are identical, we would only need to extend this notion of identical to include attributes as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants