Skip to content

Commit 65e5924

Browse files
authored
various wit-dylib API tweaks (#2362)
* various `wit-dylib` API tweaks I've recently ported `componentize-py` to use `wit-dylib` instead of its own Wasm code generator and found it useful to tweak the `wit-dylib` APIs a bit. The main idea here is to give `componentize-py` (and any similar build tool) access to the metadata generated by `wit-dylib` _before_ the guest runs, as well as match the types in that metadata up with the `wit_parser::TypeId`s from the input world. That allows the build tool to generate high-level binding code ahead of time and later match it up with the metadata at runtime. Specifically, this commit does the following: - Add a `wit_dylib::create_with_metadata` function which returns both the generated module and the `Metadata` object produced for it. - Add `id: TypeId` fields to all the "WIT type types" so that they can be matched up with the corresponding `wit-parser` types - Add `index` methods to the `wit-dylib-ffi` wrapper types, allowing the interpreter to determine where the instance appears in its respective array - Split the metadata `Function` type into separate `ImportFunction` and `ExportFunction` types, each with its own array in the `Wit` structure. Imported and exported functions are used very differently by interpreters; separating them makes them easier to deal with. Signed-off-by: Joel Dice <[email protected]> * update tests to match `wit-dylib` changes Signed-off-by: Joel Dice <[email protected]> * address review feedback Signed-off-by: Joel Dice <[email protected]> * add `index` methods to remaining `wit-dylib-ffi` types Signed-off-by: Joel Dice <[email protected]> --------- Signed-off-by: Joel Dice <[email protected]>
1 parent 5300663 commit 65e5924

38 files changed

+396
-148
lines changed

crates/wit-dylib/ffi/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,20 @@ A sample Rust crate used to implement `wit_dylib.h` with a Rust trait with the
44
possibility of an implementation being entirely safe Rust. Currently used in
55
tests of the `wit-dylib` crate, but written in such a way that this could be
66
used externally.
7+
8+
## Regenerating `ffi.rs`
9+
10+
If you've made changes to `wit_dylib.h` (or if someone else did, but forgot to
11+
update `ffi.rs`), you can use `rust-bindgen` to regenerate `ffi.rs`.
12+
13+
First, install a recent version of `rust-bindgen` if you don't already have it:
14+
15+
```
16+
cargo install bindgen-cli
17+
```
18+
19+
Then, from the parent of this directory, run:
20+
21+
```
22+
bindgen wit_dylib.h --allowlist-file wit_dylib.h --no-layout-tests --ignore-functions > ./ffi/src/ffi.rs
23+
```

crates/wit-dylib/ffi/src/ffi.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* automatically generated by rust-bindgen 0.69.4 */
1+
/* automatically generated by rust-bindgen 0.72.1 */
22

33
pub const WIT_TYPE_U8: u32 = 0;
44
pub const WIT_TYPE_U16: u32 = 1;
@@ -46,20 +46,30 @@ pub type wit_export_task_return_fn_t =
4646
::std::option::Option<unsafe extern "C" fn(cx: *mut ::std::os::raw::c_void)>;
4747
#[repr(C)]
4848
#[derive(Debug, Copy, Clone)]
49-
pub struct wit_func {
49+
pub struct wit_import_func {
5050
pub interface: *const ::std::os::raw::c_char,
5151
pub name: *const ::std::os::raw::c_char,
5252
pub impl_: wit_import_fn_t,
5353
pub async_impl: wit_import_async_fn_t,
5454
pub async_lift_impl: wit_import_async_lift_fn_t,
55-
pub task_return: wit_export_task_return_fn_t,
5655
pub nparams: usize,
5756
pub params: *const wit_type_t,
5857
pub result: wit_type_t,
5958
pub async_abi_area_size: usize,
6059
pub async_abi_area_align: usize,
6160
}
62-
pub type wit_func_t = wit_func;
61+
pub type wit_import_func_t = wit_import_func;
62+
#[repr(C)]
63+
#[derive(Debug, Copy, Clone)]
64+
pub struct wit_export_func {
65+
pub interface: *const ::std::os::raw::c_char,
66+
pub name: *const ::std::os::raw::c_char,
67+
pub task_return: wit_export_task_return_fn_t,
68+
pub nparams: usize,
69+
pub params: *const wit_type_t,
70+
pub result: wit_type_t,
71+
}
72+
pub type wit_export_func_t = wit_export_func;
6373
pub type wit_resource_drop_t = ::std::option::Option<unsafe extern "C" fn(arg1: u32)>;
6474
pub type wit_resource_new_t = ::std::option::Option<unsafe extern "C" fn(arg1: usize) -> u32>;
6575
pub type wit_resource_rep_t = ::std::option::Option<unsafe extern "C" fn(arg1: u32) -> usize>;
@@ -194,8 +204,10 @@ pub type wit_alias_t = wit_alias;
194204
#[derive(Debug, Copy, Clone)]
195205
pub struct wit {
196206
pub version: u32,
197-
pub num_funcs: usize,
198-
pub funcs: *const wit_func_t,
207+
pub num_import_funcs: usize,
208+
pub import_funcs: *const wit_import_func_t,
209+
pub num_export_funcs: usize,
210+
pub export_funcs: *const wit_export_func_t,
199211
pub num_resources: usize,
200212
pub resources: *const wit_resource_t,
201213
pub num_records: usize,

crates/wit-dylib/ffi/src/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,17 +368,17 @@ pub trait Interpreter: 'static {
368368
let _ = wit;
369369
}
370370

371-
fn export_start<'a>(wit: Wit, func: Function) -> Box<Self::CallCx<'a>>;
371+
fn export_start<'a>(wit: Wit, func: ExportFunction) -> Box<Self::CallCx<'a>>;
372372

373-
fn export_call(wit: Wit, func: Function, cx: &mut Self::CallCx<'_>);
373+
fn export_call(wit: Wit, func: ExportFunction, cx: &mut Self::CallCx<'_>);
374374

375375
fn export_call_async(
376376
wit: Wit,
377-
func: Function,
377+
func: ExportFunction,
378378
cx: Box<Self::CallCx<'static>>,
379379
) -> impl std::future::Future<Output = ()>;
380380

381-
fn export_finish(cx: Box<Self::CallCx<'_>>, func: Function) {
381+
fn export_finish(cx: Box<Self::CallCx<'_>>, func: ExportFunction) {
382382
let _ = func;
383383
let _ = cx;
384384
}
@@ -503,7 +503,7 @@ pub trait RawInterpreter: Interpreter {
503503
debug_println!("export_start({which})");
504504
unsafe {
505505
let wit = Wit::from_raw(WIT_T);
506-
let func = wit.func(which);
506+
let func = wit.export_func(which);
507507
Box::into_raw(Self::export_start(wit, func)).cast()
508508
}
509509
}
@@ -512,7 +512,7 @@ pub trait RawInterpreter: Interpreter {
512512
debug_println!("export_call({cx:?}, {which})");
513513
unsafe {
514514
let wit = Wit::from_raw(WIT_T);
515-
let func = wit.func(which);
515+
let func = wit.export_func(which);
516516
Self::export_call(wit, func, Self::cx_mut(cx))
517517
}
518518
}
@@ -522,7 +522,7 @@ pub trait RawInterpreter: Interpreter {
522522
#[cfg(feature = "async")]
523523
unsafe {
524524
let wit = Wit::from_raw(WIT_T);
525-
let func = wit.func(which);
525+
let func = wit.export_func(which);
526526
wit_bindgen::rt::async_support::start_task(Self::export_call_async(
527527
wit,
528528
func,
@@ -550,7 +550,7 @@ pub trait RawInterpreter: Interpreter {
550550
debug_println!("export_finish({cx:?}, {which})");
551551
unsafe {
552552
let wit = Wit::from_raw(WIT_T);
553-
let func = wit.func(which);
553+
let func = wit.export_func(which);
554554
Self::export_finish(Box::from_raw(cx.cast()), func)
555555
}
556556
}

0 commit comments

Comments
 (0)