|
| 1 | +;; Repeatedly read the contents of `test.bin`. |
| 2 | +(module |
| 3 | + (import "wasi_snapshot_preview1" "path_open" |
| 4 | + (func $__wasi_path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32))) |
| 5 | + (import "wasi_snapshot_preview1" "fd_read" |
| 6 | + (func $__wasi_fd_read (param i32 i32 i32 i32) (result i32))) |
| 7 | + (import "wasi_snapshot_preview1" "fd_close" |
| 8 | + (func $__wasi_fd_close (param i32) (result i32))) |
| 9 | + (func (export "run") (param $iters i64) (result i64) |
| 10 | + (local $i i64) |
| 11 | + (local.set $i (i64.const 0)) |
| 12 | + |
| 13 | + ;; Set up the iovec list; the memory usage for this module should be: |
| 14 | + ;; - offset 0 => file name |
| 15 | + ;; - offset 16 => the opened file descriptor |
| 16 | + ;; - offset 24 => the number of read bytes |
| 17 | + ;; - offset 32 => the iovec list |
| 18 | + ;; - offset 48 => the first (and only) iovec buffer |
| 19 | + (i32.store (i32.const 32) (i32.const 48)) |
| 20 | + (i32.store (i32.const 36) (i32.const 4096)) |
| 21 | + |
| 22 | + (loop $cont |
| 23 | + ;; Open the file `test.bin` under the same directory as this WAT |
| 24 | + ;; file; this assumes some prior set up of the preopens in |
| 25 | + ;; `wasi.rs`. See https://github.com/WebAssembly/WASI/blob/d8da230b/phases/snapshot/witx/wasi_snapshot_preview1.witx#L346. |
| 26 | + (call $__wasi_path_open |
| 27 | + ;; The fd of the preopen under which to search for the file; |
| 28 | + ;; the first three are the `std*` ones. |
| 29 | + (i32.const 3) |
| 30 | + ;; The lookup flags (i.e., whether to follow symlinks). |
| 31 | + (i32.const 0) |
| 32 | + ;; The path to the file under the initial fd. |
| 33 | + (i32.const 0) |
| 34 | + (i32.const 8) |
| 35 | + ;; The open flags; in this case we will only attempt to read but |
| 36 | + ;; this may attempt to create the file if it does not exist, see |
| 37 | + ;; https://github.com/WebAssembly/WASI/blob/d8da230b/phases/snapshot/witxtypenames.witx#L444). |
| 38 | + (i32.const 0) |
| 39 | + ;; The base rights and the inheriting rights: here we only set |
| 40 | + ;; the bits for the FD_READ and FD_READDIR capabilities. |
| 41 | + (i64.const 0x2002) |
| 42 | + (i64.const 0x2002) |
| 43 | + ;; The file descriptor flags (e.g., whether to append, sync, |
| 44 | + ;; etc.); see https://github.com/WebAssembly/WASI/blob/d8da230b/phases/snapshot/witx/typenames.witx#L385 |
| 45 | + (i32.const 0) |
| 46 | + ;; The address at which to store the opened fd (if the call |
| 47 | + ;; succeeds) |
| 48 | + (i32.const 16)) |
| 49 | + (if (then unreachable)) |
| 50 | + |
| 51 | + ;; Read the file into the sole iovec buffer. |
| 52 | + (call $__wasi_fd_read |
| 53 | + ;; The now-open fd stored at offset 16. |
| 54 | + (i32.load (i32.const 16)) |
| 55 | + ;; The address and size of the list of iovecs; here we only use |
| 56 | + ;; a list of a single iovec set up outside the loop. |
| 57 | + (i32.const 32) |
| 58 | + (i32.const 1) |
| 59 | + ;; The address at which to store the number of bytes read. |
| 60 | + (i32.const 24)) |
| 61 | + (if (then unreachable)) |
| 62 | + ;; Check that we indeed read 4096 bytes. |
| 63 | + (if (i32.ne (i32.load (i32.const 24)) (i32.const 4096)) |
| 64 | + (then unreachable)) |
| 65 | + |
| 66 | + ;; Close the open file handle we stored at offset 16. |
| 67 | + (call $__wasi_fd_close (i32.load (i32.const 16))) |
| 68 | + (if (then unreachable)) |
| 69 | + |
| 70 | + ;; Continue looping until $i reaches $iters. |
| 71 | + (local.set $i (i64.add (local.get $i) (i64.const 1))) |
| 72 | + (br_if $cont (i64.lt_u (local.get $i) (local.get $iters))) |
| 73 | + ) |
| 74 | + (local.get $i) |
| 75 | + ) |
| 76 | + (data (i32.const 0) "test.bin") |
| 77 | + (memory (export "memory") 1) |
| 78 | +) |
0 commit comments