TheWaWaR added the bug label to Issue #10381.
TheWaWaR opened issue #10381:
The
wasmtime_func_t
inwasmtime /extern.h
istypedef struct wasmtime_func { uint64_t store_id; size_t __private; } wasmtime_func_t;
But in rust code (crates/c-api/src/val.rs):
#[repr(C)] #[derive(Clone, Copy)] pub union wasmtime_func_t { store_id: u64, func: Func, } #[derive(Copy, Clone, Debug)] #[repr(transparent)] // here for the C API pub struct Func(Stored<FuncData>); #[repr(C)] // used by reference in the C API, also in `wasmtime_func_t`. pub struct Stored<T> { store_id: StoreId, index: usize, _marker: marker::PhantomData<fn() -> T>, }
The size of wasmtime_func_t in C is 16 bytes, but the size in rust is 24 bytes, which include 2
store_id
field.As a consequence, the type
wasmtime_val_union
in Rust can't align with the typewasmtime_valunion_t
in C.
TheWaWaR edited issue #10381:
The
wasmtime_func_t
inwasmtime /extern.h
istypedef struct wasmtime_func { uint64_t store_id; size_t __private; } wasmtime_func_t;
But in rust code (crates/c-api/src/val.rs):
#[repr(C)] #[derive(Clone, Copy)] pub union wasmtime_func_t { store_id: u64, func: Func, } #[derive(Copy, Clone, Debug)] #[repr(transparent)] // here for the C API pub struct Func(Stored<FuncData>); #[repr(C)] // used by reference in the C API, also in `wasmtime_func_t`. pub struct Stored<T> { store_id: StoreId, index: usize, _marker: marker::PhantomData<fn() -> T>, }
The size of wasmtime_func_t in C is 16 bytes, but the size in rust is 24 bytes, which include 2
store_id
fields.As a consequence, the type
wasmtime_val_union
in Rust can't align with the typewasmtime_valunion_t
in C.
TheWaWaR commented on issue #10381:
And also the type
wasmtime_anyref_t
andwasmtime_externref_t
in Rust code doesn't have#[repr(C)]
in the definition marcoref_wrapper!
.
alexcrichton commented on issue #10381:
Have you run into issues in the wild as a result of this? Or was this spotted during code review?
The Rust definition of
wasmtime_func_t
uses aunion
so it shouldn't be 24 bytes, but if you found an issue in the wild then that's more worrisome.
TheWaWaR commented on issue #10381:
My problem is the callback function registered with
wasmtime_linker_define_func
, theparams
can't parse correctly with my zig code. Even the second param'skind
field is parse incorrectly.
TheWaWaR edited a comment on issue #10381:
My problem is the callback function registered with
wasmtime_linker_define_func
, theparams
can't read correctly with my zig code. Even the second param'skind
field is incorrect.
TheWaWaR edited a comment on issue #10381:
My problem is the callback function registered with
wasmtime_linker_define_func
, theparams
can't read correctly with my zig code. Even the second param'skind
field is incorrect.pub fn getKeyboardState( env: *anyopaque, caller: *anyopaque, args: [*]const Value, nargs: usize, results: [*]Value, nresults: usize, ) callconv(.C) ?*anyopaque {} pub const Value = extern struct { kind: ValueKind, of: ValueUnion, } // wasmtime/val.h: wasmtime_valunion_t pub const ValueUnion = extern union { i32: i32, i64: i64, f32: f32, f64: f64, anyref: u128, externref: u128, funcref: u128, v128: [16]u8, }; // wasmtime/val.h: wasmtime_valkind_t pub const ValueKind = enum(u8) { i32 = 0, i64 = 1, f32 = 2, f64 = 3, v128 = 4, funcref = 5, externref = 6, anyref = 7, };
TheWaWaR edited a comment on issue #10381:
My problem is the callback function registered with
wasmtime_linker_define_func
, theparams
can't read correctly with my zig code. Even the second param'skind
field is incorrect. (other arguments in the callback function is ok.)pub fn getKeyboardState( env: *anyopaque, caller: *anyopaque, args: [*]const Value, nargs: usize, results: [*]Value, nresults: usize, ) callconv(.C) ?*anyopaque {} pub const Value = extern struct { kind: ValueKind, of: ValueUnion, } // wasmtime/val.h: wasmtime_valunion_t pub const ValueUnion = extern union { i32: i32, i64: i64, f32: f32, f64: f64, anyref: u128, externref: u128, funcref: u128, v128: [16]u8, }; // wasmtime/val.h: wasmtime_valkind_t pub const ValueKind = enum(u8) { i32 = 0, i64 = 1, f32 = 2, f64 = 3, v128 = 4, funcref = 5, externref = 6, anyref = 7, };
TheWaWaR edited a comment on issue #10381:
My problem is the callback function registered with
wasmtime_linker_define_func
, theparams
/results
can't read correctly with my zig code. Even the second param'skind
field is incorrect. (other arguments in the callback function is ok.)pub fn getKeyboardState( env: *anyopaque, caller: *anyopaque, args: [*]const Value, nargs: usize, results: [*]Value, nresults: usize, ) callconv(.C) ?*anyopaque {} pub const Value = extern struct { kind: ValueKind, of: ValueUnion, } // wasmtime/val.h: wasmtime_valunion_t pub const ValueUnion = extern union { i32: i32, i64: i64, f32: f32, f64: f64, anyref: u128, externref: u128, funcref: u128, v128: [16]u8, }; // wasmtime/val.h: wasmtime_valkind_t pub const ValueKind = enum(u8) { i32 = 0, i64 = 1, f32 = 2, f64 = 3, v128 = 4, funcref = 5, externref = 6, anyref = 7, };
TheWaWaR commented on issue #10381:
I have tried print the value in
c_callback_to_rust_fn
,params.as_ptr().addr()
matched the value in my zig code, so I guess it's a problem of data structure definition.
alexcrichton commented on issue #10381:
Sorry but I'm not familiar enough with Zig to know what I'm looking at there. Can you reduce your problem to being expressed in terms of the C API? One thing I see is that the definition of
ValueUnion
probably isn't correct sice the alignment ofu128
isn't the same aswasmtime_func_t
.Otherwise if you're using Zig there aren't official bindings to Wasmtime available in Zig so you're going to be kind of on your own for support. If you would like support here you'll most likely need to frame your problem in terms of C as opposed to Zig as otherwise you're unlikely to be able to get much help.
TheWaWaR edited a comment on issue #10381:
I have tried print the value in
c_callback_to_rust_fn
:
- The type/value in
vals
before passing into callback function is correct.params.as_ptr().addr()
matched the value in my zig code
so I guess it's a problem of data structure definition.
TheWaWaR edited a comment on issue #10381:
I have tried print the value in
c_callback_to_rust_fn
:
- The type/value in
vals
before passing into callback function is correct.params.as_ptr().addr()
matched the value in my zig code
*
so I guess it's a problem of data structure definition.
TheWaWaR edited a comment on issue #10381:
I have tried print the value in
c_callback_to_rust_fn
:
- The type/value in
vals
before passing into callback function is correct.params.as_ptr().addr()
matched the value in my zig codeso I guess it's a problem of data structure definition.
TheWaWaR closed issue #10381:
The
wasmtime_func_t
inwasmtime /extern.h
istypedef struct wasmtime_func { uint64_t store_id; size_t __private; } wasmtime_func_t;
But in rust code (crates/c-api/src/val.rs):
#[repr(C)] #[derive(Clone, Copy)] pub union wasmtime_func_t { store_id: u64, func: Func, } #[derive(Copy, Clone, Debug)] #[repr(transparent)] // here for the C API pub struct Func(Stored<FuncData>); #[repr(C)] // used by reference in the C API, also in `wasmtime_func_t`. pub struct Stored<T> { store_id: StoreId, index: usize, _marker: marker::PhantomData<fn() -> T>, }
The size of wasmtime_func_t in C is 16 bytes, but the size in rust is 24 bytes, which include 2
store_id
fields.As a consequence, the type
wasmtime_val_union
in Rust can't align with the typewasmtime_valunion_t
in C.
TheWaWaR commented on issue #10381:
I tested it in C, it's ok. You are right, I think the problem is the alignment of
u128
.
Last updated: Apr 18 2025 at 05:03 UTC