WAST/WAT Example Code in Text Spec?
re : http://webassembly.github.io/spec/core/text/index.html
It would be nice if there was a short example usage of some of the opcodes available.
I was tinkering with wat2wasm and some standalone WASM-JITs... but mostly just getting this code to work...
(module $factorial (start 1)
(type (;0;) (func (param i32) (result i32)))
(func (param i32) (result i32)
local.get 0
i32.const 0
i32.eq
if (result i32) ;; label = @1
i32.const 1
else
local.get 0
local.get 0
i32.const 1
i32.sub
call 0
i32.mul
end)
(export "fac" (func 0))
(type (;1;) (func ))
(func
i32.const 100
call 0
return
)
)
I was getting errors like this...
fac.wat:22:4: error: type mismatch in function, expected [] but got [i32]
call 0
^^^^
Which I think is somewhat misleading, it looks like an error about the arguments passed, but it's really about the return value... (Removing the i32.const 100... )
fac.wat:22:4: error: type mismatch in call, expected [i32] but got []
call 0
^^^^
fac.wat:22:4: error: type mismatch in function, expected [] but got [i32]
call 0
^^^^
So I finally reasoned that it must be that there's a return value I needed to drop. I tried to use 'drop'
drop( call 0 ) ?
drop( i32.const 100 call 0 )?
but I really couldn't figure out how to get it to just consume the return value of the function. But I found later that 'return' does stack cleanup too (is slighly more than the return I'm used to in x86 assembly); which is what is shown in the completed example...
So, It would be nice to have examples of how to use 'drop'...
like isn't drop( i32.const 100 ) just a nop? Since it puses a constant and removes it? that was the sort of examples I found in the Issue about lots of ignored return values, before the addition of 'drop'
Here's an old blog post that I wrote about some of this: WebAssembly type-checking. You might find it helpful.
But I found later that 'return' does stack cleanup too
Yes, return does this, as well as br and br_table too.
You can use drop afterward like this:
(func
i32.const 100
call 0
drop)
Or you can use the "folded" form, which is often more natural to read:
(func
(drop
(call 0
(i32.const 100)))
)
So, It would be nice to have examples of how to use 'drop'... like isn't drop( i32.const 100 ) just a nop?
Yes, but it would have to be written i32.const 100 drop or (drop (i32.const 100)). The text format is perhaps too flexible, since drop (i32.const 100) is interpreted the same as drop i32.const 100 and (drop) (i32.const 100).
The (parent (child1) (child2)) format is syntatic sugar for child1 child2 parent; it moves the child nodes before the parent node without reordering the children. So even all of these examples are the same:
(i32.add (i32.const 1) (i32.const 2))
(i32.const 1) (i32.add (i32.const 2))
(i32.const 1) (i32.const 2) (i32.add)
i32.const 1 i32.const 2 i32.add
;; even this!
(i32.const 2 (i32.const 1)) (i32.add)
Not sure if you've seen it, but sometimes I find it useful to experiment with this in the wat2wasm web demo.