denoland / deno_bindgen

Write high-level Deno FFI libraries in Rust.
MIT License
274 stars 28 forks source link

Stateless macro #135

Closed littledivy closed 10 months ago

littledivy commented 10 months ago

We need to improve the situation with bindings.json.

It's a hacky approach for maintaing symbol metadata across non-deterministic proc macro runs and causes issues with rust-analyzer.

Unfortunately, there is no good solution to global state in proc macros. We need a more stateless way to metadata:

  1. Each binding generates an initialization function.

    
    #[no_mangle]
    pub unsafe extern "C" fn __init_de90_add(
    params: *mut u8,
    result: *mut u8,
    ) -> *const u8 {
    // ...
    params[0] = Type::U32 as u8;
    params[1] = Type::U32 as u8;
    *result = Type::U32 as u8;
    
    "add\0".as_ptr()
    }

[no_mangle]

extern "C" fn add(a: u32, b: u32) -> u32 { a + b }



2. The CLI will look for symbols starting with the magic string `__init_de90` and call it to gather metadata for all runtime callable symbols.

**Why not ctor?** 

I want to keep most of the work AOT and avoid any init-time cost.
littledivy commented 10 months ago

Ok, scratch that idea. Found this amazing crate that offers a distributed const-context slice that can be used from a proc macro. It can be used to store all the stuff about symbols we need without having to do state management.

https://github.com/dtolnay/linkme