Stream: git-wasmtime

Topic: wasmtime / issue #10381 The definition wasmtime_func_t in...


view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:31):

TheWaWaR added the bug label to Issue #10381.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:31):

TheWaWaR opened issue #10381:

The wasmtime_func_t in wasmtime /extern.h is

typedef 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 type wasmtime_valunion_t in C.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:32):

TheWaWaR edited issue #10381:

The wasmtime_func_t in wasmtime /extern.h is

typedef 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 type wasmtime_valunion_t in C.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:35):

TheWaWaR commented on issue #10381:

And also the type wasmtime_anyref_t and wasmtime_externref_t in Rust code doesn't have #[repr(C)] in the definition marco ref_wrapper!.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:37):

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 a union so it shouldn't be 24 bytes, but if you found an issue in the wild then that's more worrisome.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:42):

TheWaWaR commented on issue #10381:

My problem is the callback function registered with wasmtime_linker_define_func, the params can't parse correctly with my zig code. Even the second param's kind field is parse incorrectly.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:42):

TheWaWaR edited a comment on issue #10381:

My problem is the callback function registered with wasmtime_linker_define_func, the params can't read correctly with my zig code. Even the second param's kind field is incorrect.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:45):

TheWaWaR edited a comment on issue #10381:

My problem is the callback function registered with wasmtime_linker_define_func, the params can't read correctly with my zig code. Even the second param's kind 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,
};

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:46):

TheWaWaR edited a comment on issue #10381:

My problem is the callback function registered with wasmtime_linker_define_func, the params can't read correctly with my zig code. Even the second param's kind 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,
};

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:47):

TheWaWaR edited a comment on issue #10381:

My problem is the callback function registered with wasmtime_linker_define_func, the params/results can't read correctly with my zig code. Even the second param's kind 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,
};

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:53):

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.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:54):

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 of u128 isn't the same as wasmtime_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.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:54):

TheWaWaR edited a comment on issue #10381:

I have tried print the value in c_callback_to_rust_fn:

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:55):

TheWaWaR edited a comment on issue #10381:

I have tried print the value in c_callback_to_rust_fn:

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 14:55):

TheWaWaR edited a comment on issue #10381:

I have tried print the value in c_callback_to_rust_fn:

so I guess it's a problem of data structure definition.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 16:25):

TheWaWaR closed issue #10381:

The wasmtime_func_t in wasmtime /extern.h is

typedef 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 type wasmtime_valunion_t in C.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 12 2025 at 16:25):

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