logoalt Hacker News

tlivelytoday at 3:34 PM1 replyview on HN

Andy jests, but I would actually like to add nominal types to Wasm (along with type imports to make them usable). No proposal yet, but maybe later this year.

This blog post mentions that you can kind of emulate nominal types by putting all your types in one rec group, but then it brushes that off as inferior to using exceptions. (Which is hilarious! Good work, Andy.) What it doesn’t make clear is that people actually use this rec group trick in practice. There are two ways to do it: you can put literally all your types in one rec group, or you can emit minimal rec groups with additional “brand types” that serve no purpose but to ensure the groups have different structures. The former solution is better for code size when the entire application is one module, but the latter solution is better if there are multiple modules involved. You don’t want to repeat every type definition in every module, and using smaller rec groups lets you define only the types that are (transitively) used in each module.

The Binaryen optimizer has to ensure that it does not accidentally give distinct types the same structural identity because that would generally be observable by casts. Most of its type optimizations therefore put all the types in one rec group. However, it does have a type merging optimization that takes the casts into account[0]. That optimization is fun because it reuses the DFA minimization code from the original equirecursive type system we were experimenting with for Wasm GC. We also have a rec group minimization optimization[1] that creates minimal rec groups (by finding strongly connected components of the type definition graph), then ensures the types remain distinct first by using different permutations of the types within a rec group and then only as necessary by adding brand types.

[0]: https://github.com/WebAssembly/binaryen/blob/main/src/passes...

[1]: https://github.com/WebAssembly/binaryen/blob/main/src/passes...


Replies

flohofwoetoday at 4:42 PM

I'm using WASM via Emscripten almost since the beginning but have never encountered 'rec' or 'struct' (or generally types beyond integers and floats). Why would WASM even need to know how structs are composed internally, instead of 'dissolving' them at compile time into offsets? Was this stuff coming in via the GC feature?

show 2 replies