> my observations are that people with experience in the field tend to prefer register machines
That's actually the opposite of my observation, they seem to prefer stack machines.
> my observations are that people with experience in the field tend to prefer register machines
That's actually the opposite of my observation, they seem to prefer stack machines.
(f32.add
(f32.add
(f32.mul
(f32.load
(local.get 0))
(f32.load
(local.get 1)))
(f32.mul
(f32.load offset=4
(local.get 0))
(f32.load offset=4
(local.get 1))))
(f32.mul
(f32.load offset=8
(local.get 0))
(f32.load offset=8
(local.get 1))))
The outer f32.add could translate into a byte code instruction that finds its two operands on a stack, or to one which gets them from registers.The code only says that there is a f32.add call which has two operands that are the result of a f32.add and f32.mul and so on.
The implementations will agree in their treatment of locals: that there are two locals 0 and 1, which support loading at offsets and such.
Both stack and register machines can support locals.
Just read the standard, it's quite clear from the semantics that it's a stack machine: https://webassembly.github.io/spec/core/exec/runtime.html#st... https://webassembly.github.io/spec/core/exec/instructions.ht...
To me, the distinction here is that the stack machine in WASM is restricted to the point that it corresponds 1:1 with an expression tree—not even a graph, just a tree. This means that every function in Web Assembly can be thought of as a collections of statements and expressions, and the stack machine abstraction is nothing more than a serialization format for the expressions.
Maybe dial it back a bit with the challenge to point at literature. The literature has not really caught up with the existence of WASM yet.
A defining feature of a register machine is that the actual instruction encoding has direct references to source and destination registers in it. Wasm doesn't have those, it has explicit get_local instructions instead.
That said, if you turn off LLVM's WebAssemblyRegStackify pass, all LLVM IR's values will end up in locals, with little to no stack usage. Still no register machine, but a bit more of a grey area :)
It wasn't me who claimed that WASM is "obviously" a register machine, despite the inventors saying otherwise. They even explicitly state that they decided against a register machine. I guess it's then reasonable for me to ask on what definition of stack vs register you are basing this opinion on. Let me be clear: I was not asking here for literature about WASM specifically but a definition of register/stack machines that supports your claim.
WASM's instruction encoding is very much based on a stack machine. Even with the initial limitations you mentioned I don't think it qualifies as "obviously a register machine". As already mentioned in multiple comments those restrictions were already lifted with the multi value proposal.
I understand that there is a grey area, but simply claiming "obviously a register machine" doesn't seem right to me. Implementation-wise WASM is a stack machine even if it needs/needed locals to be turing-complete.