Stream: wasmtime

Topic: c-api


view this post on Zulip Jonathan Halliday (Sep 08 2021 at 12:37):

Is this the right place for questions relating to the wasm c-api ? It looks like it's intended to be implementation neutral, but actually lives in the wasmtime repo...

view this post on Zulip Till Schneidereit (Sep 08 2021 at 12:48):

This is the right place to ask about the Wasmtime implementation of the standards-track C API, and about the other C API we provide :smile:

For more context, our implementation of the standards-track C API lives in this repository, while the spec, headers, etc live in the WebAssembly github org. That said, Wasmtime also has another C API for the reasons outlined here: https://github.com/bytecodealliance/rfcs/blob/main/accepted/new-api.md#the-new-wasmtime-c-api

Wasm C API prototype. Contribute to WebAssembly/wasm-c-api development by creating an account on GitHub.
RFC process for Bytecode Alliance projects. Contribute to bytecodealliance/rfcs development by creating an account on GitHub.

view this post on Zulip Jonathan Halliday (Sep 08 2021 at 12:54):

Right, thanks. So my problem is with resolving exported functions. e.g.

  own wasm_extern_vec_t exports;
  wasm_instance_exports(instance, &exports);
  const wasm_func_t* run_func = wasm_extern_as_func(exports.data[2]);

To make that work, the sizeof(wasm_extern_t) must be defined, so that the array stride/offset can be calculated. However, that datatype does not appear to be part of the wasm.h header? That seems to rule out dynamically linking (or calling from another language) code that needs to work with such memory layouts?

view this post on Zulip bjorn3 (Sep 08 2021 at 13:06):

wasm_extern_vec_t is declared by WASM_DECLARE_VEC(extern, *): https://github.com/WebAssembly/wasm-c-api/blob/c9d31284651b975f05ac27cee0bab1377560b87e/include/wasm.h#L488

Note that the element type is wasm_extern_t* (a pointer) and not wasm_extern_t as the second argument to the WASM_DECLARE_VEC macro is *. (ptr_or_none at https://github.com/WebAssembly/wasm-c-api/blob/c9d31284651b975f05ac27cee0bab1377560b87e/include/wasm.h#L79)

view this post on Zulip Jonathan Halliday (Sep 08 2021 at 13:18):

Ahh, ok, so I'm missing a level of indirection somewhere. At least I know what to look for now. Thanks!

view this post on Zulip Jonathan Halliday (Sep 17 2021 at 13:19):

When running some of the c-api examples, I get errors like 'wasm_global_same is not implemented'. Is this expected?

view this post on Zulip Alex Crichton (Sep 17 2021 at 13:53):

@Jonathan Halliday I think that may be a bug in our implementation not having that implemented, so feel free to open an issue! We try to at the very least provide all of the symbols from the wasm.h C API, although we don't necessarily fully implement all of them (they'll panic if they're not implemented)

view this post on Zulip Jonathan Halliday (Sep 17 2021 at 13:54):

So there is no text coverage to ensure the examples work on each release? hmm, ok.

view this post on Zulip Jonathan Halliday (Sep 17 2021 at 13:57):

There is also a quirk with functions that are provided in the header, as they don't have an implementation in the library. Work outs ok when compiling with c, but if you're using some other language to call the lib using c conventions, you just get an unsatified link problem.

view this post on Zulip Alex Crichton (Sep 17 2021 at 13:58):

We generally offload testing of the C API to the bindings we have in other languages which have their own tests. We also do not control the wasm.h header or its source, so we try to have everything implemented but sometimes there's oversights.

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 09:29):

https://github.com/bytecodealliance/wasmtime/blob/main/crates/c-api/src/vec.rs#L75 What's the third arg doing here?

Standalone JIT-style runtime for WebAssembly, using Cranelift - wasmtime/vec.rs at main · bytecodealliance/wasmtime

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:13):

The third argument there is the capacity of the vector if that's what you're interested in? The Vec::from_raw_parts Rust docs can help explain more I think

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 14:30):

Ahh, it's copying rather than wrapping. fair enough, thanks.

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 14:32):

There are weird things that happen with the c api where writing directly to the data area of a vec is allowed, but can cause problems down the line because the vec rather than the buffer is used in some cases. I assume that's just an unfortunate side-effect of the implementation choices?

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:33):

Hm I'm not sure what you mean, can you elaborate on what bad may happen?

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 14:35):

looks like if I obtain a vec and modify its contents i.e. the array elements of the data in c, the rust code won't necessarily operate on the modified values, as it's not recopying from the buffer, it's just trusting its vec contents, which is now stale?

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:38):

I think yeah? In general memory management is pretty tricky with these *_vec_t types, although we've tried to make it clear in Wasmtime's documentation what the ownership requirements are

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:39):

This is one reason that the wasmtime.h APIs generally don't use *_vec_t

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 14:40):

It's not clear to me that the c api spec prohibits what I'm doing, which would seem to indicate the implementation is buggy then?

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:45):

Could you gist what you're doing? I think it depends on precisely what you're doing and what APIs you're claling

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 14:49):

I'm calling _new_uninitialized, then dereferencing the .data part and setting a value in it, then calling _delete, which blows up with SEGV. Same thing works fine if I supply the data value as a c array for _new, because that path copies it into the vec, whilst writing the array directly doesn't. In actual c those would be equivalent, but because rust is (sometimes) doing a memory copy behind the scenes to build the vec, it's not.

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:50):

Can you gist the code that you're doing?

view this post on Zulip Alex Crichton (Oct 05 2021 at 14:50):

sorry but Rust doesn't copy anything with Vec::from_raw_parts so I don't follow

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 15:22):

I thought slice.to_vec was a copy operation?

view this post on Zulip Alex Crichton (Oct 05 2021 at 15:35):

Yes to_vec copies the contents, Vec::from_raw_parts does not. Sorry I don't know precisely what you're talking about, so some reference could would be helpful to dig into

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 15:38):

ok, so when I construct a new vec_t by passing in a c array of ptrs, it copies the array, which I can then dispose of. But what disposes of the copy it made? Calling delete will release the struct holding a pointer to that copy+its size, but as far as I can tell not the copy itself?

view this post on Zulip Alex Crichton (Oct 05 2021 at 15:42):

using the delete method for a *_vec_t disposes of the contents of the vector, not the struct holding the contents of the vector

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 15:44):

take just sets self.data to a null pointer, its doesn't appear to release the memory that self.data points to first, so it's leaking?

view this post on Zulip Alex Crichton (Oct 05 2021 at 15:55):

take returns a Vec<T> to the Rust caller, and that's an owned value which is released when dropped

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 15:58):

ahh, so delete calls take, then as delete returns control from rust back to c, the rust runtime will free the Vec?

view this post on Zulip Alex Crichton (Oct 05 2021 at 15:59):

right yeah

view this post on Zulip Jonathan Halliday (Oct 05 2021 at 16:00):

Ahh, interesting language feature, thanks!

view this post on Zulip Jonathan Halliday (Oct 08 2021 at 13:43):

So wasm-c-api/example/hello.c seems fine, until I try to wrap it in a loop, whereupon it runs twice and then falls over... https://pastebin.com/wjM2CuBU Any bright ideas?

Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.

view this post on Zulip Alex Crichton (Oct 08 2021 at 16:09):

Can you share the C code?

view this post on Zulip Jonathan Halliday (Oct 13 2021 at 15:34):

It's not all c, I'm driving the c api using java's new panama ffi interface. Fun and games until the SEGVs start.

view this post on Zulip Jonathan Halliday (Oct 13 2021 at 15:36):

Does wasm_functype_new take ownership of the params and results vecs ? I've got a double-free bug that I think is due to rust's gc disposing of them...

view this post on Zulip Alex Crichton (Oct 13 2021 at 15:44):

They take ownership, yes

view this post on Zulip Jonathan Halliday (Oct 13 2021 at 15:50):

ok. Must have missed that bit in the api docs. Thanks!

view this post on Zulip Alex Crichton (Oct 13 2021 at 15:54):

nah I think the api docs may not be super great in this regard, I tried to document things but I probably left out places by accident

view this post on Zulip Jonathan Halliday (Oct 20 2021 at 12:12):

Is https://github.com/WebAssembly/wasm-c-api/blob/c9d31284651b975f05ac27cee0bab1377560b87e/example/trap.c working as intended? It appears to take a trap from the implementation's internal checks rather than the fail_callback

Wasm C API prototype. Contribute to WebAssembly/wasm-c-api development by creating an account on GitHub.

Last updated: Dec 23 2024 at 14:03 UTC