mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +00:00
feat(c-api) No longer expand with cbindgen: drop dependency to Rust nightly.
So. Let's explain a dirty hack. `cbindgen` reads the code and collects symbols. What symbols do we need? None of the one declared in `wasm.h`, but for non-standard API, we need to collect all of them. The problem is that `wasm_named_extern_t` is the only non-standard type where extra symbols are generated by a macro (`wasm_declare_boxed_vec!`). If we want those macro-generated symbols to be collected by `cbindgen`, we need to _expand_ the crate (i.e. running something like `rustc -- -Zunstable-options --pretty=expanded`). Expanding code is unstable and available only on nightly compiler. We _don't want_ to use a nightly compiler only for that. So how can we help `cbindgen` to _see_ those symbols? First solution: We write the C code directly in a file, which is then included in the generated header file with the `cbindgen` API. Problem, it's super easy to get it outdated, and it makes the build process more complex. Second solution: We write those symbols in a custom module, that is just here for `cbindgen`, never used by our Rust code (otherwise it's duplicated code), with no particular implementation. And that's why we have the following `cbindgen_hack` module. But this module must not be compiled by `rustc`. How to force `rustc` to ignore a module? With conditional compilation. Because `cbindgen` does not support conditional compilation, it will always _ignore_ the `#[cfg]` attribute, and will always read the content of the module. Sorry.
This commit is contained in:
@@ -403,7 +403,7 @@ int main() {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn [<wasm_ $name _vec_copy>](
|
||||
out_ptr: &mut [<wasm_ $name _vec_t>],
|
||||
in_ptr: & [<wasm _$name _vec_t>])
|
||||
in_ptr: & [<wasm_ $name _vec_t>])
|
||||
{
|
||||
*out_ptr = in_ptr.clone();
|
||||
}
|
||||
|
||||
@@ -361,6 +361,88 @@ pub struct wasm_named_extern_t {
|
||||
|
||||
wasm_declare_boxed_vec!(named_extern);
|
||||
|
||||
/// So. Let's explain a dirty hack. `cbindgen` reads the code and
|
||||
/// collects symbols. What symbols do we need? None of the one
|
||||
/// declared in `wasm.h`, but for non-standard API, we need to collect
|
||||
/// all of them. The problem is that `wasm_named_extern_t` is the only
|
||||
/// non-standard type where extra symbols are generated by a macro
|
||||
/// (`wasm_declare_boxed_vec!`). If we want those macro-generated
|
||||
/// symbols to be collected by `cbindgen`, we need to _expand_ the
|
||||
/// crate (i.e. running something like `rustc -- -Zunstable-options
|
||||
/// --pretty=expanded`). Expanding code is unstable and available only
|
||||
/// on nightly compiler. We _don't want_ to use a nightly compiler
|
||||
/// only for that. So how can we help `cbindgen` to _see_ those
|
||||
/// symbols?
|
||||
///
|
||||
/// First solution: We write the C code directly in a file, which is
|
||||
/// then included in the generated header file with the `cbindgen`
|
||||
/// API. Problem, it's super easy to get it outdated, and it makes the
|
||||
/// build process more complex.
|
||||
///
|
||||
/// Second solution: We write those symbols in a custom module, that
|
||||
/// is just here for `cbindgen`, never used by our Rust code
|
||||
/// (otherwise it's duplicated code), with no particular
|
||||
/// implementation.
|
||||
///
|
||||
/// And that's why we have the following `cbindgen_hack`
|
||||
/// module.
|
||||
///
|
||||
/// But this module must not be compiled by `rustc`. How to force
|
||||
/// `rustc` to ignore a module? With conditional compilation. Because
|
||||
/// `cbindgen` does not support conditional compilation, it will
|
||||
/// always _ignore_ the `#[cfg]` attribute, and will always read the
|
||||
/// content of the module.
|
||||
///
|
||||
/// Sorry.
|
||||
#[doc(hidden)]
|
||||
#[cfg(__cbindgen_hack__ = "yes")]
|
||||
mod __cbindgen_hack__ {
|
||||
use super::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct wasm_named_extern_vec_t {
|
||||
pub size: usize,
|
||||
pub data: *mut *mut wasm_named_extern_t,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_new(
|
||||
out: *mut wasm_named_extern_vec_t,
|
||||
length: usize,
|
||||
init: *const *mut wasm_named_extern_t,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_new_uninitialized(
|
||||
out: *mut wasm_named_extern_vec_t,
|
||||
length: usize,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_copy(
|
||||
out_ptr: &mut wasm_named_extern_vec_t,
|
||||
in_ptr: &wasm_named_extern_vec_t,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_delete(
|
||||
ptr: Option<&mut wasm_named_extern_vec_t>,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_new_empty(out: *mut wasm_named_extern_vec_t) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-standard function to get the module name of a
|
||||
/// `wasm_named_extern_t`.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user