Language based security like WASM can prevent untrusted code from receiving timing channels, but only by executing it absolutely deterministically and denying it anything that can be used as a clock, which definitely includes shared memory multithreading. So you would not be able to run anything originally multithreaded, except perhaps by heroic measures like a continuation passing lowering of fibers. If the code has any way to measure the passage of time, there is presently no known way to prevent it from using Spectre to read the whole memory of the process it is in.
On the other hand process sandboxing can rely on defenses provided by the operating system and hardware. These are not IMO as absolute as deterministic execution, but they are better than nothing if it's not practical to run the untrusted code deterministically.
Thus you see for example Chrome shifting its security model in the direction of assuming that anything mapped in the same OS process as untrusted JS or WASM has no confidentiality. I personally think it would be better, given the historically very limited access of JS to synchronous timing channels, to go for perfect determinism in that context. But definitely there are use cases where that isn't practical, so there is a place for process sandboxing. It also makes for a second line of defense - you can run your wasm vm inside your process sandbox, and an integrity failure of either one is not fatal!
That's not to say, of course, that WASM VMs don't employ various security measures. V8, at least, uses (mostly) the same optimization pipeline for WASM that it does for JS, so all the years of security that have gone into JS are gained by WASM for free.
With WASM, you wouldn't need to run the sandboxed code in a separate execution context. And you shouldn't need any OS-specific code to isolate the sandboxed executable. The whole thing would be conceptually simpler; although you'd need to pull in a WASM runtime. The actual code would run a bit slower in order for the WASM VM to do bounds checks and so on. But I think function calls across the WASM boundary would be way faster than the sandboxed IPC bridge that blog post suggests. Also a WASM version would let you build your sandboxed bundle once and run it anywhere, which is neat.
So I get the sense that a WASM version of this would be simpler and more portable but have a different performance profile. Are there other considerations here? It'd be a cool experiment to play with.