<p>Assume that I have a simple language with the types I32 and F32, but also composite types like Tuples. I want to add Discriminated Union types, but I find it difficult to generate the wasm code in a good way.</p>
<p>The discrimination tag is easy, but the union part is more challenging.</p>
<p>My first thought was to count max number of I32 of all variants, also max number of F32 of all variants, and then have a layout where I put all I32 first and then all F32. But I find it difficult to compile e.g. composite types in the variants to match this layout for the type.</p>
<p>What is a good way to compile Discriminated Union types to Webassembly?</p>

<webassembly><code-generation><union-types>
How to compile Discriminated Union types to Webassembly?
CC BY-SA 4.0
2024-12-30T11:50:13.157Z
I don't know enough about WASM specifically - does it not allow you to treat a 32-bit storage location as either `i32` or `f32` depending on the instruction used?
kaya3
CC BY-SA 4.0
2024-12-30T13:35:39.070Z
@kaya3 not for the function return type or parameter type and I want to have the value on the stack
Jonas
CC BY-SA 4.0
2024-12-30T16:22:08.767Z
[AssemblyScript](https://assemblyscript.org/) aspires to be a more high-level way of writing WASM compared to the WASM textual syntax, by slotting in somewhere between WASM and TypeScript on the abstraction spectrum. (It is essentially a syntactic and semantic subset of TypeScript and semantic superset of WASM.) Interestingly, [they explicitly call out that they don't support *union types*](https://assemblyscript.org/concepts.html#strictly-typed). Given how important use of unions in TypeScript is, and AssemblyScript's goal of being familiar to TypeScript programmers, this looks like a big …
Jörg W Mittag
CC BY-SA 4.0
2024-12-30T16:23:50.817Z
… feature to miss. I wonder whether they ran into similar issues and that's why they didn't implement it? There might be some information in their repository or discussion channels. They *do* use the word "yet", though, when they describe it: "There are no union types yet", so it sounds like they expect to get it working at some point.
Jörg W Mittag
<p>Wasm essentially is a thin abstraction over hardware. When compiling to hardware directly, calling conventions for unions either require to pass them through memory, or to allocate different registers to fields according to their types. The same applies to Wasm, where the use of function parameters/results in Wasm abstracts the use of registers, such that mostly the same techniques apply.</p>
<p>For example, a typical C ABI will often use either an int or float register for an int + float union passed by value. Mapping this to Wasm would consist of declaring the parameter/result as including both an i32 and an f32, but one of them is always unused (filled with a dummy value in this case).</p>
<p>The set of so assigned registers/results can be optimised by reordering fields, and by reinterpret-casting floats to ints for parameter/result passing, for example, such that they can share the same slot. But none of that is particularly special to Wasm.</p>
<p>(Wasm 3 can also represent unions as GC types, but I assume that's not what you're looking for.)</p>

CC BY-SA 4.0
2024-12-31T09:08:24.103Z
2024-12-31T09:08:24.103Z
Andreas Rossberg
CC BY-SA 4.0
2024-12-31T11:33:26.787Z
So if I understand correctly, the size of a union type would scale like the sum of the sizes of the variants, rather than the max?
kaya3
CC BY-SA 4.0
2024-12-31T15:22:30.750Z
@kaya3, no, the slot assignments would of course be overlayed/reused between variant cases, like registers of a physical CPU.
Andreas Rossberg
# How to compile Discriminated Union types to Webassembly?
Posted by: username_0 on 2024-12-30
Assume that I have a simple language with the types I32 and F32, but also composite types like Tuples. I want to add Discriminated Union types, but I find it difficult to generate the wasm code in a good way.

The discrimination tag is easy, but the union part is more challenging.

My first thought was to count max number of I32 of all variants, also max number of F32 of all variants, and then have a layout where I put all I32 first and then all F32. But I find it difficult to compile e.g. composite types in the variants to match this layout for the type.

What is a good way to compile Discriminated Union types to Webassembly?
**Tags:** webassembly code-generation union-types
> **Comments:**
> **username_1**: I don't know enough about WASM specifically - does it not allow you to treat a 32-bit storage location as either `i32` or `f32` depending on the instruction used?  
> **username_0**: @kaya3 not for the function return type or parameter type and I want to have the value on the stack  
> **username_2**: [AssemblyScript](https://assemblyscript.org/) aspires to be a more high-level way of writing WASM compared to the WASM textual syntax, by slotting in somewhere between WASM and TypeScript on the abstraction spectrum. (It is essentially a syntactic and semantic subset of TypeScript and semantic superset of WASM.) Interestingly, [they explicitly call out that they don't support *union types*](https://assemblyscript.org/concepts.html#strictly-typed). Given how important use of unions in TypeScript is, and AssemblyScript's goal of being familiar to TypeScript programmers, this looks like a big …  
> **username_2**: … feature to miss. I wonder whether they ran into similar issues and that's why they didn't implement it? There might be some information in their repository or discussion channels. They *do* use the word "yet", though, when they describe it: "There are no union types yet", so it sounds like they expect to get it working at some point.  
---
## 1 answers
### Answer by username_3 on 2024-12-31. Score: 2
Wasm essentially is a thin abstraction over hardware. When compiling to hardware directly, calling conventions for unions either require to pass them through memory, or to allocate different registers to fields according to their types. The same applies to Wasm, where the use of function parameters/results in Wasm abstracts the use of registers, such that mostly the same techniques apply.

For example, a typical C ABI will often use either an int or float register for an int + float union passed by value. Mapping this to Wasm would consist of declaring the parameter/result as including both an i32 and an f32, but one of them is always unused (filled with a dummy value in this case).

The set of so assigned registers/results can be optimised by reordering fields, and by reinterpret-casting floats to ints for parameter/result passing, for example, such that they can share the same slot. But none of that is particularly special to Wasm.

(Wasm 3 can also represent unions as GC types, but I assume that's not what you're looking for.)
> **Comments:**
> **username_1** (2024-12-31): So if I understand correctly, the size of a union type would scale like the sum of the sizes of the variants, rather than the max?  
> **username_3** (2024-12-31): @kaya3, no, the slot assignments would of course be overlayed/reused between variant cases, like registers of a physical CPU.  
---
