The core issue is that WebAssembly VMs use the host’s native stack for return addresses and local variables, without providing wasm code any way to inspect or manipulate that data. Thus, there’s no way to scan the stack for GC roots, as would be possible in a ‘real’ assembly language. Programs do typically maintain a second, separate, stack, located within wasm-accessible memory, for things like local variables that have their address taken. In theory, you could make the compiler store all locals there across function calls; I think that might be what Go does. But that’s a performance waste. In any case, a manual approach won’t solve the use case of accessing JS/DOM objects from WebAssembly; that requires interoperating with the existing JS garbage collector.