diff --git a/imports/wasi_snapshot_preview1/testdata/wasi_arg.wasm b/imports/wasi_snapshot_preview1/testdata/print_args.wasm similarity index 100% rename from imports/wasi_snapshot_preview1/testdata/wasi_arg.wasm rename to imports/wasi_snapshot_preview1/testdata/print_args.wasm diff --git a/imports/wasi_snapshot_preview1/testdata/wasi_arg.wat b/imports/wasi_snapshot_preview1/testdata/print_args.wat similarity index 92% rename from imports/wasi_snapshot_preview1/testdata/wasi_arg.wat rename to imports/wasi_snapshot_preview1/testdata/print_args.wat index f7fb72e9..e1197041 100644 --- a/imports/wasi_snapshot_preview1/testdata/wasi_arg.wat +++ b/imports/wasi_snapshot_preview1/testdata/print_args.wat @@ -1,5 +1,5 @@ -;; $wasi_arg is a WASI command which copies null-terminated args to stdout. -(module $wasi_arg +;; $print_args is a WASI command which copies null-terminated args to stdout. +(module $print_args ;; args_get reads command-line argument data. ;; ;; See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-args_getargv-pointerpointeru8-argv_buf-pointeru8---errno @@ -24,9 +24,9 @@ ;; See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memories%E2%91%A7 (memory (export "memory") 1) - ;; $iovs are offset/length pairs in memory fd_write copies to the file descriptor. - ;; $main will only write one offset/length pair, corresponding to null-terminated args. - (global $iovs i32 i32.const 1024) ;; 1024 is an arbitrary offset larger than the args. + ;; $iovs are offset/length pairs in memory fd_write copies to the file + ;; descriptor. $main will only write one offset/length pair. + (global $iovs i32 i32.const 1024) ;; 1024 is an arbitrary offset ;; WASI parameters are usually memory offsets, you can ignore values by writing them to an unread offset. (global $ignored i32 i32.const 32768) diff --git a/imports/wasi_snapshot_preview1/testdata/print_prestat_dirname.wasm b/imports/wasi_snapshot_preview1/testdata/print_prestat_dirname.wasm new file mode 100644 index 00000000..f1088798 Binary files /dev/null and b/imports/wasi_snapshot_preview1/testdata/print_prestat_dirname.wasm differ diff --git a/imports/wasi_snapshot_preview1/testdata/print_prestat_dirname.wat b/imports/wasi_snapshot_preview1/testdata/print_prestat_dirname.wat new file mode 100644 index 00000000..81f952d5 --- /dev/null +++ b/imports/wasi_snapshot_preview1/testdata/print_prestat_dirname.wat @@ -0,0 +1,42 @@ +;; $$print_prestat_dirname is a WASI command which copies the first preopen dirname to stdout. +(module $print_prestat_dirname + (import "wasi_snapshot_preview1" "fd_prestat_get" + (func $wasi.fd_prestat_get (param $fd i32) (param $result.prestat i32) (result (;errno;) i32))) + + (import "wasi_snapshot_preview1" "fd_prestat_dir_name" + (func $wasi.fd_prestat_dir_name (param $fd i32) (param $result.path i32) (param $result.path_len i32) (result (;errno;) i32))) + + (import "wasi_snapshot_preview1" "fd_write" + (func $wasi.fd_write (param $fd i32) (param $iovs i32) (param $iovs_len i32) (param $result.size i32) (result (;errno;) i32))) + + (memory (export "memory") 1 1) + + (func $main (export "_start") + ;; First, we need to know the size of the prestat dir name. + (call $wasi.fd_prestat_get + (i32.const 3) ;; preopen FD + (i32.const 0) ;; where to write prestat + ) + drop ;; ignore the errno returned + + ;; Next, write the dir name to offset 8 (past the prestat). + (call $wasi.fd_prestat_dir_name + (i32.const 3) ;; preopen FD + (i32.const 8) ;; where to write dir_name + (i32.load (i32.const 4)) ;; length is the last part of the prestat + ) + drop ;; ignore the errno returned + + ;; Now, convert the prestat to an iovec [offset, len] writing offset=8. + (i32.store (i32.const 0) (i32.const 8)) + + ;; Finally, write the dirname to stdout via its iovec [offset, len]. + (call $wasi.fd_write + (i32.const 1) ;; stdout + (i32.const 0) ;; where's the iovec + (i32.const 1) ;; only one iovec + (i32.const 0) ;; overwrite the iovec with the ignored result. + ) + drop ;; ignore the errno returned + ) +) diff --git a/imports/wasi_snapshot_preview1/usage_test.go b/imports/wasi_snapshot_preview1/usage_test.go index d267879a..88e25e87 100644 --- a/imports/wasi_snapshot_preview1/usage_test.go +++ b/imports/wasi_snapshot_preview1/usage_test.go @@ -8,13 +8,14 @@ import ( "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" + "github.com/tetratelabs/wazero/internal/fstest" "github.com/tetratelabs/wazero/internal/testing/require" ) -// wasiArg was compiled from testdata/wasi_arg.wat +// pringArgsWasm was compiled from testdata/wasi_arg.wat // -//go:embed testdata/wasi_arg.wasm -var wasiArg []byte +//go:embed testdata/print_args.wasm +var pringArgsWasm []byte func TestInstantiateModule(t *testing.T) { ctx := context.Background() @@ -28,7 +29,7 @@ func TestInstantiateModule(t *testing.T) { sys := wazero.NewModuleConfig().WithStdout(&stdout) wasi_snapshot_preview1.MustInstantiate(ctx, r) - compiled, err := r.CompileModule(ctx, wasiArg) + compiled, err := r.CompileModule(ctx, pringArgsWasm) require.NoError(t, err) // Re-use the same module many times. @@ -46,3 +47,27 @@ func TestInstantiateModule(t *testing.T) { require.NoError(t, mod.Close(ctx)) } } + +// printPrestatDirname was compiled from testdata/print_prestat_dirname.wat +// +//go:embed testdata/print_prestat_dirname.wasm +var printPrestatDirname []byte + +// TestInstantiateModule_Prestat +func TestInstantiateModule_Prestat(t *testing.T) { + ctx := context.Background() + + r := wazero.NewRuntime(ctx) + defer r.Close(ctx) + + var stdout bytes.Buffer + + wasi_snapshot_preview1.MustInstantiate(ctx, r) + + _, err := r.InstantiateWithConfig(ctx, printPrestatDirname, wazero.NewModuleConfig(). + WithStdout(&stdout). + WithFSConfig(wazero.NewFSConfig().WithFSMount(fstest.FS, "/wazero"))) + require.NoError(t, err) + + require.Equal(t, "/wazero", stdout.String()) +} diff --git a/internal/wasip1/wasi.go b/internal/wasip1/wasi.go index 4328b49a..299feea2 100644 --- a/internal/wasip1/wasi.go +++ b/internal/wasip1/wasi.go @@ -1,5 +1,4 @@ -// Package wasi_snapshot_preview1 is a helper to remove package cycles re-using -// constants. +// Package wasip1 is a helper to remove package cycles re-using constants. package wasip1 import (