Open orsinium opened 5 months ago
For reference, here is how the same function looks in Rust:
https://github.com/firefly-zero/firefly-rust/blob/main/src/misc.rs#L4-L10
Yes apologies, this is one of the main decisions to be made for the alpha — how to model strings: #7. Currently in Orb it’s a i32
pointer to a nul-terminated string. But those have security issues by making it too easy to create buffer overflow or underflow.
So I’d like to always have the string length included whenever you reference a string. But WebAssembly doesn’t let you pass around tuples, so the packed i32+i32 into a i64 is my best idea currently.
The Range
and Slice
naming is another decision to be made. Orb doesn’t have an ownership model, the memory is just there and you can create pointer references to parts. So I want that to be clear in the name, but I also want it to feel natural similar to how you work with strings in other languages. Are you working with a pointer range or a slice of the memory? i.e. Is the thing you are working with the pointer or the memory itself? I’m leaning towards Slice and that’s why that crept into the site before the code actually has been updated.
I’ll make progress on this soon and make a PR to the https://github.com/firefly-zero/firefly-elixir project. It looks really great and readable!
Feel free to share your opinions on the above as I’m curious what you find works well with say Zig and Rust.
Wasm supports tuples. You can return multiple values from a function (which is supported by all runtimes), and you can pass represent as multiple arguments in wasm what is one argument in your code.
I'm writing a programming language that compiles into wasm. Well, not right now, I switched to Firefly for now, but I before that I made good progress on it. Ask me questions if you get stuck.
For representing values in memory and passing them around and things like that I suggest following the ABI described in the component model.
Sure, would appreciate any knowledge you can bring!
Multiple return values are awesome but the limitation is you can’t store tuples in locals. Orb currently exposes the underlying primitives as-is, so to support more complex locals I’d either have to create a C-like stack abstraction, or wait for the component model.
Orb targets currently shipping WebAssembly runtimes, so it’s going to be pretty conservative even when the component model matures.
You still can make more locals for tuples, and nobody will complain. If in Elixir code variable a
stores a 2-element tuple, just make a.0
and a.1
locals in wasm.
The component describes many things. One of which is standard ABI, and you should follow that ABI when storing values in the linear memory. You don't need any special support from the runtime side to do that.
According to the docs, strings get transformed into Orb.Memory.Range (the docs say
Slice
instead ofRange
but I think it's a typo). However, it's not what happens. When I define a function:And then call this function:
The function receives a string, not a Range:
I guess it gets transformed only when passing into a host-defined function? The problem I'm trying to solve is that while the Range type packs both the string offset and string len into a single i64 value, I need to pass into the host two separate i32 values for offset and length (as shown in the snippet above).