> I'm surprised clang doesn't simply have a mode to do this already. Its weird we need this strange wasm dance
Compiling to WebAssembly doesn't make the code safe; it simply compiles it to a virtual machine with a memory model that isolates any bugs from the rest of the parent process (presuming a bug-free parent process).
Basically, all pointers in WebAssembly are indexes to a global array (or global arrays--one for data and another for functions). It's basically the same trick people use in Rust to get around restrictions on reference cycles. And like in Rust, the compiled code can still have the same dangling pointer and buffer overflow problems, but the memory thus referenced is restricted to the unstructured array, rather than to potentially any address in the parent process' address space.
The difference between Rust and WASM is that when you compile WASM to native code, at least when JIT'ing the code, you can completely elide the extra degree of memory reference indirection. (I don't think the extra indirection can be elided for AOT compilation of WASM code without a special runtime linking step.) The cost, however, is that you're left with this single global data array, so any bug in the WASM program can break any other part of the WASM program, whereas in Rust you effectively end up with many segments of unstructured memory (basically, one per component that uses the trick) that can't be cross-referenced if the program is buggy.