WebAssembly / gc

Branch of the spec repo scoped to discussion of GC integration in WebAssembly
https://webassembly.github.io/gc/
Other
992 stars 71 forks source link

Dynamically initializing a non mutable array #515

Open ericvergnaud opened 8 months ago

ericvergnaud commented 8 months ago

Hi,

I'm probably missing the obvious but I can't seem to find a way to dynamically populate a non mutable array:

There are many scenarios where a non-mutable array needs to be dynamically populated rather than sourced from static data. Some examples:

What am I missing ?

rossberg commented 8 months ago

There are several instructions: array.new_fixed (initialises from stack operands), array.new_data (initialises from data segment), array.new_elem (initialises from element segment). Clearly, we cannot allow array.set or array.copy on immutable arrays.

We did not add array.new_array, array.new_memory, or array.new_table for the MVP, although it might make sense to have those. One rationale was that none of them will be enough to cover all cases anyway, e.g., consider the initialisation of cyclic structures like in the compilation of function closures. Personally, I believe we will need some notion like readonly to have a sufficiently general solution. Another alternative recently proposed is ref.freeze, although it's unclear how that could be implemented efficiently.

That said, keep in mind that the only reason why we have immutable arrays in the first place is richer Wasm-level subtyping. In cases where you don't need subtyping on the array field type – such as in the representation of strings – there is no particular reason to use immutable arrays. In particular, immutability is pointless when the field type isn't a reference.

ericvergnaud commented 8 months ago

Thanks for confirming. Yes ref.freeze would be a great solution for the above use use cases since it avoids a copy altogether, and readonly is a generic solution to the exact problem I'm facing. I agree that using mutable arrays is a temporarily acceptable solution, but not sure I agree with sub typing being the 'only reason'. Another strong reason I can think of for having immutable arrays is if I compile to WebAssembly a language that supports const concepts, I'd want that attribute to be reflected in the generated Wasm, such that it is guaranteed at runtime, not just at compile time. In the String example, I expect that if the characters are stored in a readonly array, then no code will be able to change one of those characters.

rossberg commented 8 months ago

I'd want that attribute to be reflected in the generated Wasm.

I'm afraid that is a misunderstanding of Wasm's intended role. Wasm is a low-level language abstracting hardware, a virtual CPU, and as such not meant to reflect source-level concepts. In particular, the GC extension is not intended to give producers any more protection than they get with linear memory, the only inherent protection is for the engine itself. Any source-level protection mechanisms must be ensured at a higher level, as with a physical CPU.

ericvergnaud commented 8 months ago

Thanks for the clarification 👍