Stream: wasm

Topic: wasm Encoder


view this post on Zulip Reyrey (Dec 06 2023 at 18:45):

I have a question. I use the Wasm Encoder Create and I want to create a record type. But how can I create an instance of a type which holds the actual values? If I have a record with two integers, how can I save 35 for integer 1 and 129 for integer 2 but not only integers like strings as well as all the other types?

view this post on Zulip fitzgen (he/him) (Dec 11 2023 at 18:41):

@Reyrey you would push the values onto the stack in field order and then emit a struct.new instruction: https://docs.rs/wasm-encoder/latest/wasm_encoder/enum.Instruction.html#variant.StructNew

view this post on Zulip Reyrey (Dec 13 2023 at 11:23):

@fitzgen (he/him) first of all thank you for helping me I have only one question: do i have to put all Fields in the Strack using the memory section where they the values are pushed in field order and then put the u32 in struct.new

view this post on Zulip fitzgen (he/him) (Dec 13 2023 at 16:23):

not in any in-memory stack, on the operand stack. eg the i32.const 1 instruction pushes the value 1 onto the operand stack, i32.add pops two i32s from the stack and pushes one i32 onto the stack, etc. you just need to make sure the struct's fields' values are on the stack before executing the struct.new instruction

view this post on Zulip Reyrey (Dec 13 2023 at 21:22):

@fitzgen (he/him) i made a wat format that shows how i understand it let wat_code = "(module
(type $Person (struct
(field $id i32)
(field $age i32)
(field $team i32)
(field $tt f32)
))
(func (type 0)
i32.const 1
i32.const 56
i32.const 3
f32.const 4.5
struct.new $Person)
(export \"f\" (func 0)))"; then how would i do it for a record type that holds strings, char and s32 because a record would hold an s32

view this post on Zulip fitzgen (he/him) (Dec 13 2023 at 21:25):

wasm gc types can only hold wasm types like i32/i64/etc. and those types aren't signed or unsigned, it is operations on them that determine how the bits are interperted. there are no wasm string types.

records are a component-model thing, which is unrelated to wasm gc

view this post on Zulip Reyrey (Dec 13 2023 at 21:39):

ah i understand so for a record do i have to have imports or inst it possible to save values for a record type field or do i have to come up with a complet diffrent approach @fitzgen (he/him)

view this post on Zulip fitzgen (he/him) (Dec 13 2023 at 21:40):

in the component model, records are lowered to scalar wasm types according to the canonical ABI: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md

view this post on Zulip fitzgen (he/him) (Dec 13 2023 at 21:41):

they don't use gc at all (for now, maybe in a while they will optionally use wasm gc if that is what the wasm module wants)

view this post on Zulip Reyrey (Dec 13 2023 at 22:01):

ah so i have to ultilize the abi for reading component-level values into and out of linear memory. are there some ressources that could help me accomplish that

view this post on Zulip fitzgen (he/him) (Dec 13 2023 at 23:23):

you probably want to use wit-bindgen to generate the boilerplate: https://github.com/bytecodealliance/wit-bindgen/

A language binding generator for WebAssembly interface types - GitHub - bytecodealliance/wit-bindgen: A language binding generator for WebAssembly interface types

view this post on Zulip Reyrey (Dec 14 2023 at 00:16):

I can't because of the project I'm contributing to and I, want the macro I'm building to be runtime agnostic so we can have different runtimes that work with it the wit-bindgen project from my knowledge only works with wasmtime but thanks for guiding me through that all really appreciate it

view this post on Zulip Joel Dice (Dec 14 2023 at 00:50):

FWIW, wit-bindgen is not wasmtime-specific (it also works great with jco). It is intended for runtimes that support the component model, although technically you could run a guest that uses wit-bindgen-generated bindings in a host runtime that doesn't support the component model if you're willing to handle the ABI marshaling (on the host side) yourself.

view this post on Zulip Reyrey (Dec 14 2023 at 09:09):

I was under the impression that with-bindgen only supported Wasmtime, as I saw that the Wasmer project had to create their own fork of the with-bindgen project. However, I am now curious as to what runtimes with-bindgen currently supports. Are Wasmtime and JCO the only ones, or are there others, such as V8 or Wazero? And if they are not supported, then am I correct in understanding that I would need to handle the ABI marshaling myself?

view this post on Zulip Till Schneidereit (Dec 14 2023 at 12:43):

Wasmer didn't have to fork wit-bindgen: wit-bindgen is designed to support easy extension with different codegen backends, and adding one for Wasmer wasn't a problem from an engineering perspective.

As you can read in this comment by the project lead, they chose to fork because they were unhappy we didn't want to take on complexity to give them the ability to make the Wasmer support easily discoverable. As you might see, the entire arguments for integrating Wasmer bindings revolve around benefits for them, with just a vague "collaboration is better" statement that's not even backed by any concrete benefits we as maintainers of wit-bindgen might derive from this integration.

In the meantime, wasmtime bindings have been removed from the wit-bindgen repository, because keeping them there wasn't a good fit for our development practices. Meaning any runtime maintaining a bindings backend wouldn't even be somehow less supported than wasmtime.

This is all to say that I would encourage you to look into using wit-bindgen if all that's blocking you is this perceived issue with supporting other runtimes.

I'm opening this issue to follow up on the PR that we created a few months ago adding support for Wasmer bindings: #173, given that the project has already matured a bit. Right now the wit-bindgen ...

view this post on Zulip Joel Dice (Dec 14 2023 at 16:13):

jco runs on V8 by way of NodeJS. Wazero does not yet have CM support AFAIK, so you'd need to handle the ABI marshaling yourself there.

view this post on Zulip Reyrey (Dec 15 2023 at 12:03):

Till Schneidereit said:

Wasmer didn't have to fork wit-bindgen: wit-bindgen is designed to support easy extension with different codegen backends, and adding one for Wasmer wasn't a problem from an engineering perspective.

As you can read in this comment by the project lead, they chose to fork because they were unhappy we didn't want to take on complexity to give them the ability to make the Wasmer support easily discoverable. As you might see, the entire arguments for integrating Wasmer bindings revolve around benefits for them, with just a vague "collaboration is better" statement that's not even backed by any concrete benefits we as maintainers of wit-bindgen might derive from this integration.

In the meantime, wasmtime bindings have been removed from the wit-bindgen repository, because keeping them there wasn't a good fit for our development practices. Meaning any runtime maintaining a bindings backend wouldn't even be somehow less supported than wasmtime.

This is all to say that I would encourage you to look into using wit-bindgen if all that's blocking you is this perceived issue with supporting other runtimes.

This makes the WIT project even more powerful, as it allows for greater flexibility. I was previously under the impression that this feature was only available for wasmruntime. Knowing this, I am now considering using the WIT project for my contribution. Our project focuses on simplicity, aiming to create a plugin system using wasm that does not overwhelm the user with complexity. To achieve this, we want to use a procedural macro on a type that can generate a record type when the user compiles their own project to wasm. We can then read these from the host application. Do you think that the WIT project would be suitable for this use case?

view this post on Zulip Reyrey (Dec 15 2023 at 12:03):

Joel Dice said:

jco runs on V8 by way of NodeJS. Wazero does not yet have CM support AFAIK, so you'd need to handle the ABI marshaling yourself there.

To clarify, if various runtimes are already compatible, then the only prerequisite for a runtime is that it must be able to support the CM. In this case, we would only need to create the bindings part. If I have understood you correctly, otherwise we would be required to manage the ABI on our own.

view this post on Zulip Joel Dice (Dec 15 2023 at 14:56):

There's a lot more to the CM than just the ABI, so adding full CM support to a runtime is a fairly large project, but if you're only interested in the ABI you could either write a host bindings generator for the runtime of interest or write bindings by hand. In any case you might want to play around with the wasmtime::component::bindgen Rust macro, using e.g. cargo expand to see what it generates and get an idea of what's required to satisfy the ABI. And as Nick mentioned earlier, the "official" reference is available at https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md


Last updated: Dec 23 2024 at 12:05 UTC