1(module
2  (import "wasi_snapshot_preview1" "fd_read"
3    (func $read (param i32 i32 i32 i32) (result i32)))
4
5  (memory (export "memory") 1)
6
7  (func (export "count") (result i32)
8    (call $count-up-to (i32.const -1))
9  )
10
11  (func $count-up-to (export "count-up-to") (param $up-to i32) (result i32)
12    (local $size i32)
13
14    (i32.eqz (local.get $up-to))
15    if
16      local.get 0
17      return
18    end
19    loop $the-loop
20      ;; setup a basic ciovec pointing into memory
21      (i32.store
22        (i32.const 100)
23        (i32.const 200))
24      (i32.store
25        (i32.const 104)
26        (i32.const 1000))
27
28
29      (call $read
30        (i32.const 0)       ;; stdin fileno
31        (i32.const 100)     ;; ciovec base
32        (i32.const 1)       ;; ciovec len
33        (i32.const 8)       ;; ret val ptr
34      )
35      ;; reading stdin must succeed (e.g. return 0)
36      if unreachable end
37
38      ;; update with how many bytes were read
39      (local.set $size
40        (i32.add
41          (local.get $size)
42          (i32.load (i32.const 8))))
43
44
45      ;; if no data was read, exit the loop
46      ;; if the size read exceeds what we're supposed to read, also exit the
47      ;; loop
48      (i32.load (i32.const 8))
49      if
50        (i32.lt_u (local.get $size) (local.get $up-to))
51        if
52          br $the-loop
53        end
54      end
55    end
56
57    local.get $size
58  )
59)
60