I'm compiling a language of pure total functions to WebAssembly. The most complicated construction available is primitive recursion. I have experimented a little, and it seems like the only viable approach is to build a trampolining abstract machine which marches over some sort of bytecode, transforming recursion to iteration. Is there a better strategy?
Well, you can of course simply use recursion in Wasm, but it will not be tail-recursive. It isn't entirely clear from your question whether that's a requirement.
An extension with explicit tail calls has been proposed for Wasm. This proposal is currently at "phase 3" of Wasm's proposal process and has been implemented in V8 and (ongoing) Safari, which means that it will hopefully be standardised very soon.
Until then, yes, you'll have to use some kind of trampoline if you depend on tail call semantics.