Stream: general

Topic: Recommended approach for handles/string literals


view this post on Zulip Josh Groves (Jul 22 2023 at 02:05):

Hi! I have some string literals that will only ever be accessed on the host (e.g., in other host functions called from the guest), so I was wondering the recommended approach for handling this.

I know it's possible to basically intern all of the strings and pass a handle (e.g, as u32) back from the guest, but I was wondering whether it might work nicely to use ExternRefs for this - basically every string would become an ExternRef that is all handled by the host. I think this would mean I'd have to make the function dynamic (i.e., because I don't know how many strings are needed statically), so something like Func::new(&mut store, type_with_all_strings_as_params, |_, params, results| { /*...*/ }).

Am I thinking about this right? Both approaches seem to work fine in practice, though ExternRef feels slightly more convenient since I don't have to worry about managing the string interning. I don't have a good intuition of how much overhead the runtime type checking for dynamic ExternRef params compares vs. the overhead of the interned string lookups, so I was wondering if somebody might have an idea? Thank you!

view this post on Zulip Hood Chatham (Jul 25 2023 at 19:48):

I think that the performance difference between interning and externref shouldn't be huge because internally they are the same. The externrefs will be more convenient indeed since the runtime handles all the details for you and can automatically free the strings when you are done using them. One big difference that you should keep in mind is that a u32 can be stored directly into wasm linear memory behind a normal pointer. This can also be dealt with by storing the externref into a wasm table of externrefs and passing around the indices into the table. The benefits of this compared to interning the strings yourself are:

  1. You don't have to do anything when you aren't storing the externref into linear memory
  2. You can manage the wasm table of externrefs from inside of wasm with table instructions:
    https://webassembly.github.io/spec/core/text/instructions.html#table-instructions

As a caveat, I'm mostly used to using the JS api for wasm with C code, there may be additional benefits/costs of the two methods are if you use wasi and Rust instead.

view this post on Zulip Josh Groves (Jul 27 2023 at 12:16):

Awesome, thank you for the context and suggestions! I've started with interning for now and also using that to write to intermediary strings (e.g., result of doing string concatenation would create a new interned string on the host side and the guest just gets a u32 for the resulting string) but interested in trying out externref more soon. The table idea is really interesting


Last updated: Dec 23 2024 at 12:05 UTC