Repository: tetratelabs/wazero
Pull request #971 (2022-12-29 01:30:00)

wasi: unexports errno and re-uses constants for logging
We originally exported WASI errno as we originally supported invoking host functions directly (e.g. without a guest). This was an invalid call pattern, and we removed that. However, we left the errnos exported even though the caller of a guest won't ever see them. This prevented us from re-using them cleanly in features such as logging.

This moves all constants including function names and flag enums internal so that there is less duplication between logging and implementation of wasi functions. This also helps in reference searches, as we can analyze uses of a particular function name.

The only constant left exported is the module name, as there's a use case for that (overriding implementations via FunctionBuilder).


Patch:
diff --git a/experimental/logging/log_listener.go b/experimental/logging/log_listener.go
index 2d458a47..304bfc8e 100644
--- a/experimental/logging/log_listener.go
+++ b/experimental/logging/log_listener.go
@@ -7,10 +7,10 @@ import (
 
 	"github.com/tetratelabs/wazero/api"
 	"github.com/tetratelabs/wazero/experimental"
-	wasilogging "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/logging"
 	gologging "github.com/tetratelabs/wazero/internal/gojs/logging"
 	"github.com/tetratelabs/wazero/internal/logging"
 	"github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	wasilogging "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1/logging"
 )
 
 type Writer interface {
@@ -78,7 +78,7 @@ func (f *loggingListenerFactory) NewListener(fnd api.FunctionDefinition) experim
 	var pSampler logging.ParamSampler
 	var rLoggers []logging.ResultLogger
 	switch fnd.ModuleName() {
-	case wasi_snapshot_preview1.ModuleName:
+	case wasi_snapshot_preview1.InternalModuleName:
 		if f.fsOnly && !wasilogging.IsFilesystemFunction(fnd) {
 			return nil
 		}
diff --git a/imports/wasi_snapshot_preview1/args.go b/imports/wasi_snapshot_preview1/args.go
index 3fc77511..67869025 100644
--- a/imports/wasi_snapshot_preview1/args.go
+++ b/imports/wasi_snapshot_preview1/args.go
@@ -4,15 +4,11 @@ import (
 	"context"
 
 	"github.com/tetratelabs/wazero/api"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-const (
-	argsGetName      = "args_get"
-	argsSizesGetName = "args_sizes_get"
-)
-
-// argsGet is the WASI function named argsGetName that reads command-line
+// argsGet is the WASI function named ArgsGetName that reads command-line
 // argument data.
 //
 // # Parameters
@@ -44,7 +40,7 @@ const (
 // See argsSizesGet
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_get
 // See https://en.wikipedia.org/wiki/Null-terminated_string
-var argsGet = newHostFunc(argsGetName, argsGetFn, []api.ValueType{i32, i32}, "argv", "argv_buf")
+var argsGet = newHostFunc(ArgsGetName, argsGetFn, []api.ValueType{i32, i32}, "argv", "argv_buf")
 
 func argsGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
@@ -52,7 +48,7 @@ func argsGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Args(), argv, argvBuf, sysCtx.ArgsSize())
 }
 
-// argsSizesGet is the WASI function named argsSizesGetName that reads
+// argsSizesGet is the WASI function named ArgsSizesGetName that reads
 // command-line argument sizes.
 //
 // # Parameters
@@ -81,7 +77,7 @@ func argsGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 // See argsGet
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_sizes_get
 // See https://en.wikipedia.org/wiki/Null-terminated_string
-var argsSizesGet = newHostFunc(argsSizesGetName, argsSizesGetFn, []api.ValueType{i32, i32}, "result.argc", "result.argv_len")
+var argsSizesGet = newHostFunc(ArgsSizesGetName, argsSizesGetFn, []api.ValueType{i32, i32}, "result.argc", "result.argv_len")
 
 func argsSizesGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
diff --git a/imports/wasi_snapshot_preview1/clock.go b/imports/wasi_snapshot_preview1/clock.go
index 7e1e4ec0..299324ee 100644
--- a/imports/wasi_snapshot_preview1/clock.go
+++ b/imports/wasi_snapshot_preview1/clock.go
@@ -5,25 +5,11 @@ import (
 	"time"
 
 	"github.com/tetratelabs/wazero/api"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-const (
-	clockResGetName  = "clock_res_get"
-	clockTimeGetName = "clock_time_get"
-)
-
-// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clockid-enumu32
-const (
-	// clockIDRealtime is the name ID named "realtime" like sys.Walltime
-	clockIDRealtime = iota
-	// clockIDMonotonic is the name ID named "monotonic" like sys.Nanotime
-	clockIDMonotonic
-	// Note: clockIDProcessCputime and clockIDThreadCputime were removed by
-	// WASI maintainers: https://github.com/WebAssembly/wasi-libc/pull/294
-)
-
-// clockResGet is the WASI function named clockResGetName that returns the
+// clockResGet is the WASI function named ClockResGetName that returns the
 // resolution of time values returned by clockTimeGet.
 //
 // # Parameters
@@ -51,7 +37,7 @@ const (
 // Note: This is similar to `clock_getres` in POSIX.
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_res_getid-clockid---errno-timestamp
 // See https://linux.die.net/man/3/clock_getres
-var clockResGet = newHostFunc(clockResGetName, clockResGetFn, []api.ValueType{i32, i32}, "id", "result.resolution")
+var clockResGet = newHostFunc(ClockResGetName, clockResGetFn, []api.ValueType{i32, i32}, "id", "result.resolution")
 
 func clockResGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
@@ -59,9 +45,9 @@ func clockResGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 
 	var resolution uint64 // ns
 	switch id {
-	case clockIDRealtime:
+	case ClockIDRealtime:
 		resolution = uint64(sysCtx.WalltimeResolution())
-	case clockIDMonotonic:
+	case ClockIDMonotonic:
 		resolution = uint64(sysCtx.NanotimeResolution())
 	default:
 		return ErrnoInval
@@ -73,7 +59,7 @@ func clockResGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return ErrnoSuccess
 }
 
-// clockTimeGet is the WASI function named clockTimeGetName that returns
+// clockTimeGet is the WASI function named ClockTimeGetName that returns
 // the time value of a name (time.Now).
 //
 // # Parameters
@@ -104,7 +90,7 @@ func clockResGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 // Note: This is similar to `clock_gettime` in POSIX.
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_time_getid-clockid-precision-timestamp---errno-timestamp
 // See https://linux.die.net/man/3/clock_gettime
-var clockTimeGet = newHostFunc(clockTimeGetName, clockTimeGetFn, []api.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp")
+var clockTimeGet = newHostFunc(ClockTimeGetName, clockTimeGetFn, []api.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp")
 
 func clockTimeGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
@@ -115,10 +101,10 @@ func clockTimeGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 
 	var val int64
 	switch id {
-	case clockIDRealtime:
+	case ClockIDRealtime:
 		sec, nsec := sysCtx.Walltime()
 		val = (sec * time.Second.Nanoseconds()) + int64(nsec)
-	case clockIDMonotonic:
+	case ClockIDMonotonic:
 		val = sysCtx.Nanotime()
 	default:
 		return ErrnoInval
diff --git a/imports/wasi_snapshot_preview1/environ.go b/imports/wasi_snapshot_preview1/environ.go
index 01348d5e..fabf4992 100644
--- a/imports/wasi_snapshot_preview1/environ.go
+++ b/imports/wasi_snapshot_preview1/environ.go
@@ -4,15 +4,11 @@ import (
 	"context"
 
 	"github.com/tetratelabs/wazero/api"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-const (
-	environGetName      = "environ_get"
-	environSizesGetName = "environ_sizes_get"
-)
-
-// environGet is the WASI function named environGetName that reads
+// environGet is the WASI function named EnvironGetName that reads
 // environment variables.
 //
 // # Parameters
@@ -44,7 +40,7 @@ const (
 // See environSizesGet
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_get
 // See https://en.wikipedia.org/wiki/Null-terminated_string
-var environGet = newHostFunc(environGetName, environGetFn, []api.ValueType{i32, i32}, "environ", "environ_buf")
+var environGet = newHostFunc(EnvironGetName, environGetFn, []api.ValueType{i32, i32}, "environ", "environ_buf")
 
 func environGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
@@ -53,7 +49,7 @@ func environGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Environ(), environ, environBuf, sysCtx.EnvironSize())
 }
 
-// environSizesGet is the WASI function named environSizesGetName that
+// environSizesGet is the WASI function named EnvironSizesGetName that
 // reads environment variable sizes.
 //
 // # Parameters
@@ -84,7 +80,7 @@ func environGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 // See environGet
 // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_sizes_get
 // and https://en.wikipedia.org/wiki/Null-terminated_string
-var environSizesGet = newHostFunc(environSizesGetName, environSizesGetFn, []api.ValueType{i32, i32}, "result.environc", "result.environv_len")
+var environSizesGet = newHostFunc(EnvironSizesGetName, environSizesGetFn, []api.ValueType{i32, i32}, "result.environc", "result.environv_len")
 
 func environSizesGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go
index 54fa473c..41f13923 100644
--- a/imports/wasi_snapshot_preview1/fs.go
+++ b/imports/wasi_snapshot_preview1/fs.go
@@ -8,70 +8,34 @@ import (
 	"math"
 	"os"
 	"path"
-	"syscall"
 
 	"github.com/tetratelabs/wazero/api"
-	internalsys "github.com/tetratelabs/wazero/internal/sys"
-	"github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	"github.com/tetratelabs/wazero/internal/sys"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-const (
-	fdAdviseName           = "fd_advise"
-	fdAllocateName         = "fd_allocate"
-	fdCloseName            = "fd_close"
-	fdDatasyncName         = "fd_datasync"
-	fdFdstatGetName        = "fd_fdstat_get"
-	fdFdstatSetFlagsName   = "fd_fdstat_set_flags"
-	fdFdstatSetRightsName  = "fd_fdstat_set_rights"
-	fdFilestatGetName      = "fd_filestat_get"
-	fdFilestatSetSizeName  = "fd_filestat_set_size"
-	fdFilestatSetTimesName = "fd_filestat_set_times"
-	fdPreadName            = "fd_pread"
-	fdPrestatGetName       = "fd_prestat_get"
-	fdPrestatDirNameName   = "fd_prestat_dir_name"
-	fdPwriteName           = "fd_pwrite"
-	fdReadName             = "fd_read"
-	fdReaddirName          = "fd_readdir"
-	fdRenumberName         = "fd_renumber"
-	fdSeekName             = "fd_seek"
-	fdSyncName             = "fd_sync"
-	fdTellName             = "fd_tell"
-	fdWriteName            = "fd_write"
-
-	pathCreateDirectoryName  = "path_create_directory"
-	pathFilestatGetName      = "path_filestat_get"
-	pathFilestatSetTimesName = "path_filestat_set_times"
-	pathLinkName             = "path_link"
-	pathOpenName             = "path_open"
-	pathReadlinkName         = "path_readlink"
-	pathRemoveDirectoryName  = "path_remove_directory"
-	pathRenameName           = "path_rename"
-	pathSymlinkName          = "path_symlink"
-	pathUnlinkFileName       = "path_unlink_file"
-)
-
-// fdAdvise is the WASI function named fdAdviseName which provides file
+// fdAdvise is the WASI function named FdAdviseName which provides file
 // advisory information on a file descriptor.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_advisefd-fd-offset-filesize-len-filesize-advice-advice---errno
 var fdAdvise = stubFunction(
-	fdAdviseName,
+	FdAdviseName,
 	[]wasm.ValueType{i32, i64, i64, i32},
 	"fd", "offset", "len", "advice",
 )
 
-// fdAllocate is the WASI function named fdAllocateName which forces the
+// fdAllocate is the WASI function named FdAllocateName which forces the
 // allocation of space in a file.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_allocatefd-fd-offset-filesize-len-filesize---errno
 var fdAllocate = stubFunction(
-	fdAllocateName,
+	FdAllocateName,
 	[]wasm.ValueType{i32, i64, i64},
 	"fd", "offset", "len",
 )
 
-// fdClose is the WASI function named fdCloseName which closes a file
+// fdClose is the WASI function named FdCloseName which closes a file
 // descriptor.
 //
 // # Parameters
@@ -86,7 +50,7 @@ var fdAllocate = stubFunction(
 // Note: This is similar to `close` in POSIX.
 // See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_close
 // and https://linux.die.net/man/3/close
-var fdClose = newHostFunc(fdCloseName, fdCloseFn, []api.ValueType{i32}, "fd")
+var fdClose = newHostFunc(FdCloseName, fdCloseFn, []api.ValueType{i32}, "fd")
 
 func fdCloseFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	fsc := mod.(*wasm.CallContext).Sys.FS()
@@ -98,13 +62,13 @@ func fdCloseFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return ErrnoSuccess
 }
 
-// fdDatasync is the WASI function named fdDatasyncName which synchronizes
+// fdDatasync is the WASI function named FdDatasyncName which synchronizes
 // the data of a file to disk.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_datasyncfd-fd---errno
-var fdDatasync = stubFunction(fdDatasyncName, []api.ValueType{i32}, "fd")
+var fdDatasync = stubFunction(FdDatasyncName, []api.ValueType{i32}, "fd")
 
-// fdFdstatGet is the WASI function named fdFdstatGetName which returns the
+// fdFdstatGet is the WASI function named FdFdstatGetName which returns the
 // attributes of a file descriptor.
 //
 // # Parameters
@@ -141,7 +105,7 @@ var fdDatasync = stubFunction(fdDatasyncName, []api.ValueType{i32}, "fd")
 // well as additional fields.
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fdstat
 // and https://linux.die.net/man/3/fsync
-var fdFdstatGet = newHostFunc(fdFdstatGetName, fdFdstatGetFn, []api.ValueType{i32, i32}, "fd", "result.stat")
+var fdFdstatGet = newHostFunc(FdFdstatGetName, fdFdstatGetFn, []api.ValueType{i32, i32}, "fd", "result.stat")
 
 // fdFdstatGetFn cannot currently use proxyResultParams because fdstat is larger
 // than api.ValueTypeI64 (i64 == 8 bytes, but fdstat is 24).
@@ -158,7 +122,7 @@ func fdFdstatGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 
 	stat, err := fsc.StatFile(fd)
 	if err != nil {
-		return toErrno(err)
+		return ToErrno(err)
 	}
 
 	filetype := getWasiFiletype(stat.Mode())
@@ -167,7 +131,7 @@ func fdFdstatGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	// Determine if it is writeable
 	if w := fsc.FdWriter(fd); w != nil {
 		// TODO: maybe cache flags to open instead
-		fdflags = wasi_snapshot_preview1.FD_APPEND
+		fdflags = FD_APPEND
 	}
 
 	writeFdstat(buf, filetype, fdflags)
@@ -176,7 +140,7 @@ func fdFdstatGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 }
 
 var blockFdstat = []byte{
-	wasi_snapshot_preview1.FILETYPE_BLOCK_DEVICE, 0, // filetype
+	FILETYPE_BLOCK_DEVICE, 0, // filetype
 	0, 0, 0, 0, 0, 0, // fdflags
 	0, 0, 0, 0, 0, 0, 0, 0, // fs_rights_base
 	0, 0, 0, 0, 0, 0, 0, 0, // fs_rights_inheriting
@@ -189,22 +153,22 @@ func writeFdstat(buf []byte, filetype uint8, fdflags uint16) {
 	buf[2] = byte(fdflags)
 }
 
-// fdFdstatSetFlags is the WASI function named fdFdstatSetFlagsName which
+// fdFdstatSetFlags is the WASI function named FdFdstatSetFlagsName which
 // adjusts the flags associated with a file descriptor.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_fdstat_set_flagsfd-fd-flags-fdflags---errnoand is stubbed for GrainLang per #271
-var fdFdstatSetFlags = stubFunction(fdFdstatSetFlagsName, []wasm.ValueType{i32, i32}, "fd", "flags")
+var fdFdstatSetFlags = stubFunction(FdFdstatSetFlagsName, []wasm.ValueType{i32, i32}, "fd", "flags")
 
 // fdFdstatSetRights will not be implemented as rights were removed from WASI.
 //
 // See https://github.com/bytecodealliance/wasmtime/pull/4666
 var fdFdstatSetRights = stubFunction(
-	fdFdstatSetRightsName,
+	FdFdstatSetRightsName,
 	[]wasm.ValueType{i32, i64, i64},
 	"fd", "fs_rights_base", "fs_rights_inheriting",
 )
 
-// fdFilestatGet is the WASI function named fdFilestatGetName which returns
+// fdFilestatGet is the WASI function named FdFilestatGetName which returns
 // the stat attributes of an open file.
 //
 // # Parameters
@@ -251,7 +215,7 @@ var fdFdstatSetRights = stubFunction(
 // Note: This is similar to `fstat` in POSIX.
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_filestat_getfd-fd---errno-filestat
 // and https://linux.die.net/man/3/fstat
-var fdFilestatGet = newHostFunc(fdFilestatGetName, fdFilestatGetFn, []api.ValueType{i32, i32}, "fd", "result.filestat")
+var fdFilestatGet = newHostFunc(FdFilestatGetName, fdFilestatGetFn, []api.ValueType{i32, i32}, "fd", "result.filestat")
 
 // fdFilestatGetFn cannot currently use proxyResultParams because filestat is
 // larger than api.ValueTypeI64 (i64 == 8 bytes, but filestat is 64).
@@ -270,7 +234,7 @@ func fdFilestatGetFunc(mod api.Module, fd, resultBuf uint32) Errno {
 
 	stat, err := fsc.StatFile(fd)
 	if err != nil {
-		return toErrno(err)
+		return ToErrno(err)
 	}
 
 	writeFilestat(buf, stat)
@@ -279,17 +243,17 @@ func fdFilestatGetFunc(mod api.Module, fd, resultBuf uint32) Errno {
 }
 
 func getWasiFiletype(fileMode fs.FileMode) uint8 {
-	wasiFileType := wasi_snapshot_preview1.FILETYPE_UNKNOWN
+	wasiFileType := FILETYPE_UNKNOWN
 	if fileMode&fs.ModeDevice != 0 {
-		wasiFileType = wasi_snapshot_preview1.FILETYPE_BLOCK_DEVICE
+		wasiFileType = FILETYPE_BLOCK_DEVICE
 	} else if fileMode&fs.ModeCharDevice != 0 {
-		wasiFileType = wasi_snapshot_preview1.FILETYPE_CHARACTER_DEVICE
+		wasiFileType = FILETYPE_CHARACTER_DEVICE
 	} else if fileMode&fs.ModeDir != 0 {
-		wasiFileType = wasi_snapshot_preview1.FILETYPE_DIRECTORY
+		wasiFileType = FILETYPE_DIRECTORY
 	} else if fileMode&fs.ModeType == 0 {
-		wasiFileType = wasi_snapshot_preview1.FILETYPE_REGULAR_FILE
+		wasiFileType = FILETYPE_REGULAR_FILE
 	} else if fileMode&fs.ModeSymlink != 0 {
-		wasiFileType = wasi_snapshot_preview1.FILETYPE_SYMBOLIC_LINK
+		wasiFileType = FILETYPE_SYMBOLIC_LINK
 	}
 	return wasiFileType
 }
@@ -297,7 +261,7 @@ func getWasiFiletype(fileMode fs.FileMode) uint8 {
 var blockFilestat = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0, // device
 	0, 0, 0, 0, 0, 0, 0, 0, // inode
-	wasi_snapshot_preview1.FILETYPE_BLOCK_DEVICE, 0, 0, 0, 0, 0, 0, 0, // filetype
+	FILETYPE_BLOCK_DEVICE, 0, 0, 0, 0, 0, 0, 0, // filetype
 	1, 0, 0, 0, 0, 0, 0, 0, // nlink
 	0, 0, 0, 0, 0, 0, 0, 0, // filesize
 	0, 0, 0, 0, 0, 0, 0, 0, // atim
@@ -319,30 +283,30 @@ func writeFilestat(buf []byte, stat fs.FileInfo) {
 	le.PutUint64(buf[56:], uint64(mtim)) // ctim
 }
 
-// fdFilestatSetSize is the WASI function named fdFilestatSetSizeName which
+// fdFilestatSetSize is the WASI function named FdFilestatSetSizeName which
 // adjusts the size of an open file.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_filestat_set_sizefd-fd-size-filesize---errno
-var fdFilestatSetSize = stubFunction(fdFilestatSetSizeName, []wasm.ValueType{i32, i64}, "fd", "size")
+var fdFilestatSetSize = stubFunction(FdFilestatSetSizeName, []wasm.ValueType{i32, i64}, "fd", "size")
 
 // fdFilestatSetTimes is the WASI function named functionFdFilestatSetTimes
 // which adjusts the times of an open file.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_filestat_set_timesfd-fd-atim-timestamp-mtim-timestamp-fst_flags-fstflags---errno
 var fdFilestatSetTimes = stubFunction(
-	fdFilestatSetTimesName,
+	FdFilestatSetTimesName,
 	[]wasm.ValueType{i32, i64, i64, i32},
 	"fd", "atim", "mtim", "fst_flags",
 )
 
-// fdPread is the WASI function named fdPreadName which reads from a file
+// fdPread is the WASI function named FdPreadName which reads from a file
 // descriptor, without using and updating the file descriptor's offset.
 //
 // Except for handling offset, this implementation is identical to fdRead.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_preadfd-fd-iovs-iovec_array-offset-filesize---errno-size
 var fdPread = newHostFunc(
-	fdPreadName, fdPreadFn,
+	FdPreadName, fdPreadFn,
 	[]api.ValueType{i32, i32, i32, i64, i32},
 	"fd", "iovs", "iovs_len", "offset", "result.nread",
 )
@@ -351,7 +315,7 @@ func fdPreadFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return fdReadOrPread(mod, params, true)
 }
 
-// fdPrestatGet is the WASI function named fdPrestatGetName which returns
+// fdPrestatGet is the WASI function named FdPrestatGetName which returns
 // the prestat data of a file descriptor.
 //
 // # Parameters
@@ -382,14 +346,14 @@ func fdPreadFn(_ context.Context, mod api.Module, params []uint64) Errno {
 //
 // See fdPrestatDirName and
 // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#prestat
-var fdPrestatGet = newHostFunc(fdPrestatGetName, fdPrestatGetFn, []api.ValueType{i32, i32}, "fd", "result.prestat")
+var fdPrestatGet = newHostFunc(FdPrestatGetName, fdPrestatGetFn, []api.ValueType{i32, i32}, "fd", "result.prestat")
 
 func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	fsc := mod.(*wasm.CallContext).Sys.FS()
 	fd, resultPrestat := uint32(params[0]), uint32(params[1])
 
 	// Currently, we only pre-open the root file descriptor.
-	if fd != internalsys.FdRoot {
+	if fd != sys.FdRoot {
 		return ErrnoBadf
 	}
 
@@ -407,7 +371,7 @@ func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return ErrnoSuccess
 }
 
-// fdPrestatDirName is the WASI function named fdPrestatDirNameName which
+// fdPrestatDirName is the WASI function named FdPrestatDirNameName which
 // returns the path of the pre-opened directory of a file descriptor.
 //
 // # Parameters
@@ -438,7 +402,7 @@ func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 // See fdPrestatGet
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_prestat_dir_name
 var fdPrestatDirName = newHostFunc(
-	fdPrestatDirNameName, fdPrestatDirNameFn,
+	FdPrestatDirNameName, fdPrestatDirNameFn,
 	[]api.ValueType{i32, i32, i32},
 	"fd", "result.path", "result.path_len",
 )
@@ -448,7 +412,7 @@ func fdPrestatDirNameFn(_ context.Context, mod api.Module, params []uint64) Errn
 	fd, path, pathLen := uint32(params[0]), uint32(params[1]), uint32(params[2])
 
 	// Currently, we only pre-open the root file descriptor.
-	if fd != internalsys.FdRoot {
+	if fd != sys.FdRoot {
 		return ErrnoBadf
 	}
 
@@ -468,17 +432,17 @@ func fdPrestatDirNameFn(_ context.Context, mod api.Module, params []uint64) Errn
 	return ErrnoSuccess
 }
 
-// fdPwrite is the WASI function named fdPwriteName which writes to a file
+// fdPwrite is the WASI function named FdPwriteName which writes to a file
 // descriptor, without using and updating the file descriptor's offset.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_pwritefd-fd-iovs-ciovec_array-offset-filesize---errno-size
 var fdPwrite = stubFunction(
-	fdPwriteName,
+	FdPwriteName,
 	[]wasm.ValueType{i32, i32, i32, i64, i32},
 	"fd", "iovs", "iovs_len", "offset", "result.nwritten",
 )
 
-// fdRead is the WASI function named fdReadName which reads from a file
+// fdRead is the WASI function named FdReadName which reads from a file
 // descriptor.
 //
 // # Parameters
@@ -528,7 +492,7 @@ var fdPwrite = stubFunction(
 // See fdWrite
 // and https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_read
 var fdRead = newHostFunc(
-	fdReadName, fdReadFn,
+	FdReadName, fdReadFn,
 	[]api.ValueType{i32, i32, i32, i32},
 	"fd", "iovs", "iovs_len", "result.nread",
 )
@@ -619,12 +583,12 @@ func fdRead_shouldContinueRead(n, l uint32, err error) (bool, Errno) {
 	return n == l && n != 0, ErrnoSuccess
 }
 
-// fdReaddir is the WASI function named fdReaddirName which reads directory
+// fdReaddir is the WASI function named FdReaddirName which reads directory
 // entries from a directory.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_readdirfd-fd-buf-pointeru8-buf_len-size-cookie-dircookie---errno-size
 var fdReaddir = newHostFunc(
-	fdReaddirName, fdReaddirFn,
+	FdReaddirName, fdReaddirFn,
 	[]wasm.ValueType{i32, i32, i32, i64, i32},
 	"fd", "buf", "buf_len", "cookie", "result.bufused",
 )
@@ -644,7 +608,7 @@ func fdReaddirFn(_ context.Context, mod api.Module, params []uint64) Errno {
 
 	// The bufLen must be enough to write a dirent. Otherwise, the caller can't
 	// read what the next cookie is.
-	if bufLen < direntSize {
+	if bufLen < DirentSize {
 		return ErrnoInval
 	}
 
@@ -660,10 +624,10 @@ func fdReaddirFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	}
 
 	// First, determine the maximum directory entries that can be encoded as
-	// dirents. The total size is direntSize(24) + nameSize, for each file.
+	// dirents. The total size is DirentSize(24) + nameSize, for each file.
 	// Since a zero-length file name is invalid, the minimum size entry is
-	// 25 (direntSize + 1 character).
-	maxDirEntries := int(bufLen/direntSize + 1)
+	// 25 (DirentSize + 1 character).
+	maxDirEntries := int(bufLen/DirentSize + 1)
 
 	// While unlikely maxDirEntries will fit into bufLen, add one more just in
 	// case, as we need to know if we hit the end of the directory or not to
@@ -719,10 +683,10 @@ func fdReaddirFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return ErrnoSuccess
 }
 
-const largestDirent = int64(math.MaxUint32 - direntSize)
+const largestDirent = int64(math.MaxUint32 - DirentSize)
 
 // lastDirEntries is broken out from fdReaddirFn for testability.
-func lastDirEntries(dir *internalsys.ReadDir, cookie int64) (entries []fs.DirEntry, errno Errno) {
+func lastDirEntries(dir *sys.ReadDir, cookie int64) (entries []fs.DirEntry, errno Errno) {
 	if cookie < 0 {
 		errno = ErrnoInval // invalid as we will never send a negative cookie.
 		return
@@ -757,10 +721,6 @@ func lastDirEntries(dir *internalsys.ReadDir, cookie int64) (entries []fs.DirEnt
 	return
 }
 
-// direntSize is the size of the dirent struct, which should be followed by the
-// length of a file name.
-const direntSize = uint32(24)
-
 // maxDirents returns the maximum count and total entries that can fit in
 // maxLen bytes.
 //
@@ -773,7 +733,7 @@ const direntSize = uint32(24)
 func maxDirents(entries []fs.DirEntry, bufLen uint32) (bufused, direntCount uint32, writeTruncatedEntry bool) {
 	lenRemaining := bufLen
 	for _, e := range entries {
-		if lenRemaining < direntSize {
+		if lenRemaining < DirentSize {
 			// We don't have enough space in bufLen for another struct,
 			// entry. A caller who wants more will retry.
 
@@ -787,9 +747,9 @@ func maxDirents(entries []fs.DirEntry, bufLen uint32) (bufused, direntCount uint
 		nameLen := int64(len(e.Name()))
 		var entryLen uint32
 
-		// Check to see if direntSize + nameLen overflows, or if it would be
+		// Check to see if DirentSize + nameLen overflows, or if it would be
 		// larger than possible to encode.
-		if el := int64(direntSize) + nameLen; el < 0 || el > largestDirent {
+		if el := int64(DirentSize) + nameLen; el < 0 || el > largestDirent {
 			// panic, as testing is difficult. ex we would have to extract a
 			// function to get size of a string or allocate a 2^32 size one!
 			panic("invalid filename: too large")
@@ -801,8 +761,8 @@ func maxDirents(entries []fs.DirEntry, bufLen uint32) (bufused, direntCount uint
 			// We haven't room to write the entry, and docs say to write the
 			// header. This helps especially when there is an entry with a very
 			// long filename. Ex if bufLen is 4096 and the filename is 4096,
-			// we need to write direntSize(24) + 4096 bytes to write the entry.
-			// In this case, we only write up to direntSize(24) to allow the
+			// we need to write DirentSize(24) + 4096 bytes to write the entry.
+			// In this case, we only write up to DirentSize(24) to allow the
 			// caller to resize.
 
 			// bufused == bufLen means more entries exist, which is the case
@@ -839,7 +799,7 @@ func writeDirents(
 		nameLen := uint32(len(e.Name()))
 
 		writeDirent(dirents[pos:], d_next, nameLen, e.IsDir())
-		pos += direntSize
+		pos += DirentSize
 
 		copy(dirents[pos:], e.Name())
 		pos += nameLen
@@ -851,7 +811,7 @@ func writeDirents(
 	}
 
 	// Write a dirent without its name
-	dirent := make([]byte, direntSize)
+	dirent := make([]byte, DirentSize)
 	e := entries[i]
 	writeDirent(dirent, d_next, uint32(len(e.Name())), e.IsDir())
 
@@ -859,21 +819,21 @@ func writeDirents(
 	copy(dirents[pos:], dirent)
 }
 
-// writeDirent writes direntSize bytes
+// writeDirent writes DirentSize bytes
 func writeDirent(buf []byte, dNext uint64, dNamlen uint32, dType bool) {
 	le.PutUint64(buf, dNext)        // d_next
 	le.PutUint64(buf[8:], 0)        // no d_ino
 	le.PutUint32(buf[16:], dNamlen) // d_namlen
 
-	filetype := wasi_snapshot_preview1.FILETYPE_REGULAR_FILE
+	filetype := FILETYPE_REGULAR_FILE
 	if dType {
-		filetype = wasi_snapshot_preview1.FILETYPE_DIRECTORY
+		filetype = FILETYPE_DIRECTORY
 	}
 	le.PutUint32(buf[20:], uint32(filetype)) //  d_type
 }
 
 // openedDir returns the directory and ErrnoSuccess if the fd points to a readable directory.
-func openedDir(fsc *internalsys.FSContext, fd uint32) (fs.ReadDirFile, *internalsys.ReadDir, Errno) {
+func openedDir(fsc *sys.FSContext, fd uint32) (fs.ReadDirFile, *sys.ReadDir, Errno) {
 	if f, ok := fsc.OpenedFile(fd); !ok {
 		return nil, nil, ErrnoBadf
 	} else if d, ok := f.File.(fs.ReadDirFile); !ok {
@@ -886,19 +846,19 @@ func openedDir(fsc *internalsys.FSContext, fd uint32) (fs.ReadDirFile, *internal
 		return nil, nil, ErrnoBadf
 	} else {
 		if f.ReadDir == nil {
-			f.ReadDir = &internalsys.ReadDir{}
+			f.ReadDir = &sys.ReadDir{}
 		}
 		return d, f.ReadDir, ErrnoSuccess
 	}
 }
 
-// fdRenumber is the WASI function named fdRenumberName which atomically
+// fdRenumber is the WASI function named FdRenumberName which atomically
 // replaces a file descriptor by renumbering another file descriptor.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_renumberfd-fd-to-fd---errno
-var fdRenumber = stubFunction(fdRenumberName, []wasm.ValueType{i32, i32}, "fd", "to")
+var fdRenumber = stubFunction(FdRenumberName, []wasm.ValueType{i32, i32}, "fd", "to")
 
-// fdSeek is the WASI function named fdSeekName which moves the offset of a
+// fdSeek is the WASI function named FdSeekName which moves the offset of a
 // file descriptor.
 //
 // # Parameters
@@ -936,7 +896,7 @@ var fdRenumber = stubFunction(fdRenumberName, []wasm.ValueType{i32, i32}, "fd",
 // See io.Seeker
 // and https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_seek
 var fdSeek = newHostFunc(
-	fdSeekName, fdSeekFn,
+	FdSeekName, fdSeekFn,
 	[]api.ValueType{i32, i64, i32, i32},
 	"fd", "offset", "whence", "result.newoffset",
 )
@@ -948,7 +908,7 @@ func fdSeekFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	whence := uint32(params[2])
 	resultNewoffset := uint32(params[3])
 
-	if fd == internalsys.FdRoot {
+	if fd == sys.FdRoot {
 		return ErrnoBadf // cannot seek a directory
 	}
 
@@ -976,19 +936,19 @@ func fdSeekFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	return ErrnoSuccess
 }
 
-// fdSync is the WASI function named fdSyncName which synchronizes the data
+// fdSync is the WASI function named FdSyncName which synchronizes the data
 // and metadata of a file to disk.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_syncfd-fd---errno
-var fdSync = stubFunction(fdSyncName, []api.ValueType{i32}, "fd")
+var fdSync = stubFunction(FdSyncName, []api.ValueType{i32}, "fd")
 
-// fdTell is the WASI function named fdTellName which returns the current
+// fdTell is the WASI function named FdTellName which returns the current
 // offset of a file descriptor.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_tellfd-fd---errno-filesize
-var fdTell = stubFunction(fdTellName, []wasm.ValueType{i32, i32}, "fd", "result.offset")
+var fdTell = stubFunction(FdTellName, []wasm.ValueType{i32, i32}, "fd", "result.offset")
 
-// fdWrite is the WASI function named fdWriteName which writes to a file
+// fdWrite is the WASI function named FdWriteName which writes to a file
 // descriptor.
 //
 // # Parameters
@@ -1047,7 +1007,7 @@ var fdTell = stubFunction(fdTellName, []wasm.ValueType{i32, i32}, "fd", "result.
 // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#ciovec
 // and https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_write
 var fdWrite = newHostFunc(
-	fdWriteName, fdWriteFn,
+	FdWriteName, fdWriteFn,
 	[]api.ValueType{i32, i32, i32, i32},
 	"fd", "iovs", "iovs_len", "result.nwritten",
 )
@@ -1100,17 +1060,17 @@ func fdWriteFn(ctx context.Context, mod api.Module, params []uint64) Errno {
 	return ErrnoSuccess
 }
 
-// pathCreateDirectory is the WASI function named pathCreateDirectoryName
+// pathCreateDirectory is the WASI function named PathCreateDirectoryName
 // which creates a directory.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-path_create_directoryfd-fd-path-string---errno
 var pathCreateDirectory = stubFunction(
-	pathCreateDirectoryName,
+	PathCreateDirectoryName,
 	[]wasm.ValueType{i32, i32, i32},
 	"fd", "path", "path_len",
 )
 
-// pathFilestatGet is the WASI function named pathFilestatGetName which
+// pathFilestatGet is the WASI function named PathFilestatGetName which
 // returns the stat attributes of a file or directory.
 //
 // # Parameters
@@ -1139,7 +1099,7 @@ var pathCreateDirectory = stubFunction(
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-path_filestat_getfd-fd-flags-lookupflags-path-string---errno-filestat
 // and https://linux.die.net/man/2/fstatat
 var pathFilestatGet = newHostFunc(
-	pathFilestatGetName, pathFilestatGetFn,
+	PathFilestatGetName, pathFilestatGetFn,
 	[]api.ValueType{i32, i32, i32, i32, i32},
 	"fd", "flags", "path", "path_len", "result.filestat",
 )
@@ -1192,27 +1152,27 @@ func pathFilestatGetFn(_ context.Context, mod api.Module, params []uint64) Errno
 	return ErrnoSuccess
 }
 
-// pathFilestatSetTimes is the WASI function named pathFilestatSetTimesName
+// pathFilestatSetTimes is the WASI function named PathFilestatSetTimesName
 // which adjusts the timestamps of a file or directory.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-path_filestat_set_timesfd-fd-flags-lookupflags-path-string-atim-timestamp-mtim-timestamp-fst_flags-fstflags---errno
 var pathFilestatSetTimes = stubFunction(
-	pathFilestatSetTimesName,
+	PathFilestatSetTimesName,
 	[]wasm.ValueType{i32, i32, i32, i32, i64, i64, i32},
 	"fd", "flags", "path", "path_len", "atim", "mtim", "fst_flags",
 )
 
-// pathLink is the WASI function named pathLinkName which adjusts the
+// pathLink is the WASI function named PathLinkName which adjusts the
 // timestamps of a file or directory.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#path_link
 var pathLink = stubFunction(
-	pathLinkName,
+	PathLinkName,
 	[]wasm.ValueType{i32, i32, i32, i32, i32, i32, i32},
 	"old_fd", "old_flags", "old_path", "old_path_len", "new_fd", "new_path", "new_path_len",
 )
 
-// pathOpen is the WASI function named pathOpenName which opens a file or
+// pathOpen is the WASI function named PathOpenName which opens a file or
 // directory. This returns ErrnoBadf if the fd is invalid.
 //
 // # Parameters
@@ -1266,7 +1226,7 @@ var pathLink = stubFunction(
 //
 // See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#path_open
 var pathOpen = newHostFunc(
-	pathOpenName, pathOpenFn,
+	PathOpenName, pathOpenFn,
 	[]api.ValueType{i32, i32, i32, i32, i32, i64, i64, i32, i32},
 	"fd", "dirflags", "path", "path_len", "oflags", "fs_rights_base", "fs_rights_inheriting", "fdflags", "result.opened_fd",
 )
@@ -1319,14 +1279,14 @@ func pathOpenFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	pathName := string(b)
 	var newFD uint32
 	var err error
-	if isDir && oflags&wasi_snapshot_preview1.O_CREAT != 0 {
+	if isDir && oflags&O_CREAT != 0 {
 		newFD, err = fsc.Mkdir(pathName, 0o700)
 	} else {
 		newFD, err = fsc.OpenFile(pathName, fileOpenFlags, 0o600)
 	}
 
 	if err != nil {
-		return toErrno(err)
+		return ToErrno(err)
 	}
 
 	// Check any flags that require the file to evaluate.
@@ -1344,9 +1304,9 @@ func pathOpenFn(_ context.Context, mod api.Module, params []uint64) Errno {
 }
 
 func openFlags(oflags, fdflags uint16) (openFlags int, isDir bool) {
-	isDir = oflags&wasi_snapshot_preview1.O_DIRECTORY != 0
+	isDir = oflags&O_DIRECTORY != 0
 	openFlags = os.O_RDONLY
-	if oflags&wasi_snapshot_preview1.O_CREAT != 0 {
+	if oflags&O_CREAT != 0 {
 		if !isDir { // assume read write
 			openFlags = os.O_RDWR
 		}
@@ -1355,19 +1315,19 @@ func openFlags(oflags, fdflags uint16) (openFlags int, isDir bool) {
 	if isDir {
 		return
 	}
-	if oflags&wasi_snapshot_preview1.O_EXCL != 0 {
+	if oflags&O_EXCL != 0 {
 		openFlags |= os.O_EXCL
 	}
-	if oflags&wasi_snapshot_preview1.O_TRUNC != 0 {
+	if oflags&O_TRUNC != 0 {
 		openFlags |= os.O_TRUNC
 	}
-	if fdflags&wasi_snapshot_preview1.FD_APPEND != 0 {
+	if fdflags&FD_APPEND != 0 {
 		openFlags |= os.O_APPEND
 	}
 	return
 }
 
-func failIfNotDirectory(fsc *internalsys.FSContext, fd uint32) Errno {
+func failIfNotDirectory(fsc *sys.FSContext, fd uint32) Errno {
 	// Lookup the previous file
 	if f, ok := fsc.OpenedFile(fd); !ok {
 		return ErrnoBadf
@@ -1378,86 +1338,61 @@ func failIfNotDirectory(fsc *internalsys.FSContext, fd uint32) Errno {
 	return ErrnoSuccess
 }
 
-// pathReadlink is the WASI function named pathReadlinkName that reads the
+// pathReadlink is the WASI function named PathReadlinkName that reads the
 // contents of a symbolic link.
 //
 // See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-path_readlinkfd-fd-path-string-buf-pointeru8-buf_len-size---errno-size
 var pathReadlink = stubFunction(
-	pathReadlinkName,
+	PathReadlinkName,
 	[]wasm.ValueType{i32, i32, i32, i32, i32, i32},
 	"fd", "path", "path_len", "buf", "buf_len", "result.bufused",
 )
 
-// pathRemoveDirectory is the WASI function named pathRemoveDirectoryName
+// pathRemoveDirectory is the WASI function named PathRemoveDirectoryName
 // which removes a directory.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-path_remove_directoryfd-fd-path-string---errno
 var pathRemoveDirectory = stubFunction(
-	pathRemoveDirectoryName,
+	PathRemoveDirectoryName,
 	[]wasm.ValueType{i32, i32, i32},
 	"fd", "path", "path_len",
 )
 
-// pathRename is the WASI function named pathRenameName which renames a
+// pathRename is the WASI function named PathRenameName which renames a
 // file or directory.
 var pathRename = stubFunction(
-	pathRenameName,
+	PathRenameName,
 	[]wasm.ValueType{i32, i32, i32, i32, i32, i32},
 	"fd", "old_path", "old_path_len", "new_fd", "new_path", "new_path_len",
 )
 
-// pathSymlink is the WASI function named pathSymlinkName which creates a
+// pathSymlink is the WASI function named PathSymlinkName which creates a
 // symbolic link.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#path_symlink
 var pathSymlink = stubFunction(
-	pathSymlinkName,
+	PathSymlinkName,
 	[]wasm.ValueType{i32, i32, i32, i32, i32},
 	"old_path", "old_path_len", "fd", "new_path", "new_path_len",
 )
 
-// pathUnlinkFile is the WASI function named pathUnlinkFileName which
+// pathUnlinkFile is the WASI function named PathUnlinkFileName which
 // unlinks a file.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-path_unlink_filefd-fd-path-string---errno
 var pathUnlinkFile = stubFunction(
-	pathUnlinkFileName,
+	PathUnlinkFileName,
 	[]wasm.ValueType{i32, i32, i32},
 	"fd", "path", "path_len",
 )
 
 // statFile attempts to stat the file at the given path. Errors coerce to WASI
 // Errno.
-func statFile(fsc *internalsys.FSContext, name string) (stat fs.FileInfo, errno Errno) {
+func statFile(fsc *sys.FSContext, name string) (stat fs.FileInfo, errno Errno) {
 	var err error
 	stat, err = fsc.StatPath(name)
 	if err != nil {
-		errno = toErrno(err)
+		errno = ToErrno(err)
 	}
 	return
 }
-
-// toErrno coerces the error to a WASI Errno.
-//
-// Note: Coercion isn't centralized in sys.FSContext because ABI use different
-// error codes. For example, wasi-filesystem and GOOS=js don't map to these
-// Errno.
-func toErrno(err error) Errno {
-	// handle all the cases of FS.Open or internal to FSContext.OpenFile
-	switch {
-	case errors.Is(err, syscall.ENOSYS):
-		return ErrnoNosys
-	case errors.Is(err, fs.ErrInvalid):
-		return ErrnoInval
-	case errors.Is(err, fs.ErrNotExist):
-		// fs.FS is allowed to return this instead of ErrInvalid on an invalid path
-		return ErrnoNoent
-	case errors.Is(err, fs.ErrExist):
-		return ErrnoExist
-	case errors.Is(err, syscall.EBADF):
-		// fsc.OpenFile currently returns this on out of file descriptors
-		return ErrnoBadf
-	default:
-		return ErrnoIo
-	}
-}
diff --git a/imports/wasi_snapshot_preview1/poll.go b/imports/wasi_snapshot_preview1/poll.go
index edb74670..367c517d 100644
--- a/imports/wasi_snapshot_preview1/poll.go
+++ b/imports/wasi_snapshot_preview1/poll.go
@@ -4,22 +4,11 @@ import (
 	"context"
 
 	"github.com/tetratelabs/wazero/api"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-const pollOneoffName = "poll_oneoff"
-
-// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-eventtype-enumu8
-const (
-	// eventTypeClock is the timeout event named "name".
-	eventTypeClock = iota
-	// eventTypeFdRead is the data available event named "fd_read".
-	eventTypeFdRead
-	// eventTypeFdWrite is the capacity available event named "fd_write".
-	eventTypeFdWrite
-)
-
-// pollOneoff is the WASI function named pollOneoffName that concurrently
+// pollOneoff is the WASI function named PollOneoffName that concurrently
 // polls for the occurrence of a set of events.
 //
 // # Parameters
@@ -46,7 +35,7 @@ const (
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#poll_oneoff
 // See https://linux.die.net/man/3/poll
 var pollOneoff = newHostFunc(
-	pollOneoffName, pollOneoffFn,
+	PollOneoffName, pollOneoffFn,
 	[]api.ValueType{i32, i32, i32, i32},
 	"in", "out", "nsubscriptions", "result.nevents",
 )
@@ -87,10 +76,10 @@ func pollOneoffFn(ctx context.Context, mod api.Module, params []uint64) Errno {
 		eventType := inBuf[inOffset+8] // +8 past userdata
 		var errno Errno                // errno for this specific event
 		switch eventType {
-		case eventTypeClock: // handle later
+		case EventTypeClock: // handle later
 			// +8 past userdata +8 name alignment
 			errno = processClockEvent(ctx, mod, inBuf[inOffset+8+8:])
-		case eventTypeFdRead, eventTypeFdWrite:
+		case EventTypeFdRead, EventTypeFdWrite:
 			// +8 past userdata +4 FD alignment
 			errno = processFDEvent(mod, eventType, inBuf[inOffset+8+4:])
 		default:
@@ -110,7 +99,7 @@ func pollOneoffFn(ctx context.Context, mod api.Module, params []uint64) Errno {
 
 // processClockEvent supports only relative name events, as that's what's used
 // to implement sleep in various compilers including Rust, Zig and TinyGo.
-func processClockEvent(ctx context.Context, mod api.Module, inBuf []byte) Errno {
+func processClockEvent(_ context.Context, mod api.Module, inBuf []byte) Errno {
 	_ /* ID */ = le.Uint32(inBuf[0:8])          // See below
 	timeout := le.Uint64(inBuf[8:16])           // nanos if relative
 	_ /* precision */ = le.Uint64(inBuf[16:24]) // Unused
@@ -143,9 +132,9 @@ func processFDEvent(mod api.Module, eventType byte, inBuf []byte) Errno {
 	// Choose the best error, which falls back to unsupported, until we support
 	// files.
 	errno := ErrnoNotsup
-	if eventType == eventTypeFdRead && fsc.FdReader(fd) == nil {
+	if eventType == EventTypeFdRead && fsc.FdReader(fd) == nil {
 		errno = ErrnoBadf
-	} else if eventType == eventTypeFdWrite && fsc.FdWriter(fd) == nil {
+	} else if eventType == EventTypeFdWrite && fsc.FdWriter(fd) == nil {
 		errno = ErrnoBadf
 	}
 
diff --git a/imports/wasi_snapshot_preview1/proc.go b/imports/wasi_snapshot_preview1/proc.go
index d67b0248..f8c31697 100644
--- a/imports/wasi_snapshot_preview1/proc.go
+++ b/imports/wasi_snapshot_preview1/proc.go
@@ -4,16 +4,12 @@ import (
 	"context"
 
 	"github.com/tetratelabs/wazero/api"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 	"github.com/tetratelabs/wazero/sys"
 )
 
-const (
-	procExitName  = "proc_exit"
-	procRaiseName = "proc_raise"
-)
-
-// procExit is the WASI function named procExitName that terminates the
+// procExit is the WASI function named ProcExitName that terminates the
 // execution of the module with an exit code. The only successful exit code is
 // zero.
 //
@@ -23,8 +19,8 @@ const (
 //
 // See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#proc_exit
 var procExit = &wasm.HostFunc{
-	ExportNames: []string{procExitName},
-	Name:        procExitName,
+	ExportNames: []string{ProcExitName},
+	Name:        ProcExitName,
 	ParamTypes:  []api.ValueType{i32},
 	ParamNames:  []string{"rval"},
 	Code: &wasm.Code{
@@ -48,4 +44,4 @@ func procExitFn(ctx context.Context, mod api.Module, params []uint64) {
 // procRaise is stubbed and will never be supported, as it was removed.
 //
 // See https://github.com/WebAssembly/WASI/pull/136
-var procRaise = stubFunction(procRaiseName, []api.ValueType{i32}, "sig")
+var procRaise = stubFunction(ProcRaiseName, []api.ValueType{i32}, "sig")
diff --git a/imports/wasi_snapshot_preview1/random.go b/imports/wasi_snapshot_preview1/random.go
index b5ea4930..0e841afd 100644
--- a/imports/wasi_snapshot_preview1/random.go
+++ b/imports/wasi_snapshot_preview1/random.go
@@ -5,12 +5,11 @@ import (
 	"io"
 
 	"github.com/tetratelabs/wazero/api"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-const randomGetName = "random_get"
-
-// randomGet is the WASI function named randomGetName which writes random
+// randomGet is the WASI function named RandomGetName which writes random
 // data to a buffer.
 //
 // # Parameters
@@ -34,7 +33,7 @@ const randomGetName = "random_get"
 //	    buf --^
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-bufLen-size---errno
-var randomGet = newHostFunc(randomGetName, randomGetFn, []api.ValueType{i32, i32}, "buf", "buf_len")
+var randomGet = newHostFunc(RandomGetName, randomGetFn, []api.ValueType{i32, i32}, "buf", "buf_len")
 
 func randomGetFn(_ context.Context, mod api.Module, params []uint64) Errno {
 	sysCtx := mod.(*wasm.CallContext).Sys
diff --git a/imports/wasi_snapshot_preview1/sched.go b/imports/wasi_snapshot_preview1/sched.go
index 54c03641..cc97a4a1 100644
--- a/imports/wasi_snapshot_preview1/sched.go
+++ b/imports/wasi_snapshot_preview1/sched.go
@@ -1,9 +1,11 @@
 package wasi_snapshot_preview1
 
-const schedYieldName = "sched_yield"
+import (
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+)
 
-// schedYield is the WASI function named schedYieldName which temporarily
+// schedYield is the WASI function named SchedYieldName which temporarily
 // yields execution of the calling thread.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sched_yield---errno
-var schedYield = stubFunction(schedYieldName, nil)
+var schedYield = stubFunction(SchedYieldName, nil)
diff --git a/imports/wasi_snapshot_preview1/sock.go b/imports/wasi_snapshot_preview1/sock.go
index 0d3c1caa..5291e2d1 100644
--- a/imports/wasi_snapshot_preview1/sock.go
+++ b/imports/wasi_snapshot_preview1/sock.go
@@ -1,47 +1,43 @@
 package wasi_snapshot_preview1
 
-import "github.com/tetratelabs/wazero/internal/wasm"
-
-const (
-	sockAcceptName   = "sock_accept"
-	sockRecvName     = "sock_recv"
-	sockSendName     = "sock_send"
-	sockShutdownName = "sock_shutdown"
+import (
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
-// sockAccept is the WASI function named sockAcceptName which accepts a new
+// sockAccept is the WASI function named SockAcceptName which accepts a new
 // incoming connection.
 //
 // See: https://github.com/WebAssembly/WASI/blob/0ba0c5e2e37625ca5a6d3e4255a998dfaa3efc52/phases/snapshot/docs.md#sock_accept
 // and https://github.com/WebAssembly/WASI/pull/458
 var sockAccept = stubFunction(
-	sockAcceptName,
+	SockAcceptName,
 	[]wasm.ValueType{i32, i32, i32},
 	"fd", "flags", "result.fd",
 )
 
-// sockRecv is the WASI function named sockRecvName which receives a
+// sockRecv is the WASI function named SockRecvName which receives a
 // message from a socket.
 //
 // See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sock_recvfd-fd-ri_data-iovec_array-ri_flags-riflags---errno-size-roflags
 var sockRecv = stubFunction(
-	sockRecvName,
+	SockRecvName,
 	[]wasm.ValueType{i32, i32, i32, i32, i32, i32},
 	"fd", "ri_data", "ri_data_count", "ri_flags", "result.ro_datalen", "result.ro_flags",
 )
 
-// sockSend is the WASI function named sockSendName which sends a message
+// sockSend is the WASI function named SockSendName which sends a message
 // on a socket.
 //
 // See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sock_sendfd-fd-si_data-ciovec_array-si_flags-siflags---errno-size
 var sockSend = stubFunction(
-	sockSendName,
+	SockSendName,
 	[]wasm.ValueType{i32, i32, i32, i32, i32},
 	"fd", "si_data", "si_data_count", "si_flags", "result.so_datalen",
 )
 
-// sockShutdown is the WASI function named sockShutdownName which shuts
+// sockShutdown is the WASI function named SockShutdownName which shuts
 // down socket send and receive channels.
 //
 // See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sock_shutdownfd-fd-how-sdflags---errno
-var sockShutdown = stubFunction(sockShutdownName, []wasm.ValueType{i32, i32}, "fd", "how")
+var sockShutdown = stubFunction(SockShutdownName, []wasm.ValueType{i32, i32}, "fd", "how")
diff --git a/imports/wasi_snapshot_preview1/wasi.go b/imports/wasi_snapshot_preview1/wasi.go
index fa21078e..8b7e3307 100644
--- a/imports/wasi_snapshot_preview1/wasi.go
+++ b/imports/wasi_snapshot_preview1/wasi.go
@@ -22,17 +22,16 @@ import (
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/api"
-	"github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
 // ModuleName is the module name WASI functions are exported into.
 //
 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md
-const (
-	ModuleName = wasi_snapshot_preview1.ModuleName
-	i32, i64   = wasm.ValueTypeI32, wasm.ValueTypeI64
-)
+const ModuleName = InternalModuleName
+
+const i32, i64 = wasm.ValueTypeI32, wasm.ValueTypeI64
 
 var le = binary.LittleEndian
 
diff --git a/internal/wasi_snapshot_preview1/args.go b/internal/wasi_snapshot_preview1/args.go
new file mode 100644
index 00000000..cd5cbc9b
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/args.go
@@ -0,0 +1,6 @@
+package wasi_snapshot_preview1
+
+const (
+	ArgsGetName      = "args_get"
+	ArgsSizesGetName = "args_sizes_get"
+)
diff --git a/internal/wasi_snapshot_preview1/clock.go b/internal/wasi_snapshot_preview1/clock.go
new file mode 100644
index 00000000..58694431
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/clock.go
@@ -0,0 +1,16 @@
+package wasi_snapshot_preview1
+
+const (
+	ClockResGetName  = "clock_res_get"
+	ClockTimeGetName = "clock_time_get"
+)
+
+// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clockid-enumu32
+const (
+	// ClockIDRealtime is the name ID named "realtime" like sys.Walltime
+	ClockIDRealtime = iota
+	// ClockIDMonotonic is the name ID named "monotonic" like sys.Nanotime
+	ClockIDMonotonic
+	// Note: clockIDProcessCputime and clockIDThreadCputime were removed by
+	// WASI maintainers: https://github.com/WebAssembly/wasi-libc/pull/294
+)
diff --git a/internal/wasi_snapshot_preview1/environ.go b/internal/wasi_snapshot_preview1/environ.go
new file mode 100644
index 00000000..56fab775
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/environ.go
@@ -0,0 +1,6 @@
+package wasi_snapshot_preview1
+
+const (
+	EnvironGetName      = "environ_get"
+	EnvironSizesGetName = "environ_sizes_get"
+)
diff --git a/imports/wasi_snapshot_preview1/errno.go b/internal/wasi_snapshot_preview1/errno.go
similarity index 68%
rename from imports/wasi_snapshot_preview1/errno.go
rename to internal/wasi_snapshot_preview1/errno.go
index 2e00e0aa..03dc3ea0 100644
--- a/imports/wasi_snapshot_preview1/errno.go
+++ b/internal/wasi_snapshot_preview1/errno.go
@@ -1,24 +1,22 @@
 package wasi_snapshot_preview1
 
 import (
-	internalwasi "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	"errors"
+	"fmt"
+	"io/fs"
+	"syscall"
 )
 
-// Errno are the error codes returned by WASI functions.
-//
-// # Notes
-//
-//   - This is not always an error, as ErrnoSuccess is a valid code.
-//   - Codes are defined even when not relevant to WASI for use in higher-level
-//     libraries or alignment with POSIX.
-//
-// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-errno-enumu16 and
-// https://linux.die.net/man/3/errno
-type Errno = uint32 // neither uint16 nor an alias for parity with wasm.ValueType
+// Errno is neither uint16 nor an alias for parity with wasm.ValueType.
+type Errno = uint32
 
-// ErrnoName returns the POSIX error code name, except ErrnoSuccess, which is not an error. e.g. Errno2big -> "E2BIG"
-func ErrnoName(errno Errno) string {
-	return internalwasi.ErrnoName(errno)
+// ErrnoName returns the POSIX error code name, except ErrnoSuccess, which is
+// not an error. e.g. Errno2big -> "E2BIG"
+func ErrnoName(errno uint32) string {
+	if int(errno) < len(errnoToString) {
+		return errnoToString[errno]
+	}
+	return fmt.Sprintf("errno(%d)", errno)
 }
 
 // Note: Below prefers POSIX symbol names over WASI ones, even if the docs are from WASI.
@@ -181,3 +179,108 @@ const (
 	// Note: ErrnoNotcapable was removed by WASI maintainers.
 	// See https://github.com/WebAssembly/wasi-libc/pull/294
 )
+
+var errnoToString = [...]string{
+	"ESUCCESS",
+	"E2BIG",
+	"EACCES",
+	"EADDRINUSE",
+	"EADDRNOTAVAIL",
+	"EAFNOSUPPORT",
+	"EAGAIN",
+	"EALREADY",
+	"EBADF",
+	"EBADMSG",
+	"EBUSY",
+	"ECANCELED",
+	"ECHILD",
+	"ECONNABORTED",
+	"ECONNREFUSED",
+	"ECONNRESET",
+	"EDEADLK",
+	"EDESTADDRREQ",
+	"EDOM",
+	"EDQUOT",
+	"EEXIST",
+	"EFAULT",
+	"EFBIG",
+	"EHOSTUNREACH",
+	"EIDRM",
+	"EILSEQ",
+	"EINPROGRESS",
+	"EINTR",
+	"EINVAL",
+	"EIO",
+	"EISCONN",
+	"EISDIR",
+	"ELOOP",
+	"EMFILE",
+	"EMLINK",
+	"EMSGSIZE",
+	"EMULTIHOP",
+	"ENAMETOOLONG",
+	"ENETDOWN",
+	"ENETRESET",
+	"ENETUNREACH",
+	"ENFILE",
+	"ENOBUFS",
+	"ENODEV",
+	"ENOENT",
+	"ENOEXEC",
+	"ENOLCK",
+	"ENOLINK",
+	"ENOMEM",
+	"ENOMSG",
+	"ENOPROTOOPT",
+	"ENOSPC",
+	"ENOSYS",
+	"ENOTCONN",
+	"ENOTDIR",
+	"ENOTEMPTY",
+	"ENOTRECOVERABLE",
+	"ENOTSOCK",
+	"ENOTSUP",
+	"ENOTTY",
+	"ENXIO",
+	"EOVERFLOW",
+	"EOWNERDEAD",
+	"EPERM",
+	"EPIPE",
+	"EPROTO",
+	"EPROTONOSUPPORT",
+	"EPROTOTYPE",
+	"ERANGE",
+	"EROFS",
+	"ESPIPE",
+	"ESRCH",
+	"ESTALE",
+	"ETIMEDOUT",
+	"ETXTBSY",
+	"EXDEV",
+	"ENOTCAPABLE",
+}
+
+// ToErrno coerces the error to a WASI Errno.
+//
+// Note: Coercion isn't centralized in sys.FSContext because ABI use different
+// error codes. For example, wasi-filesystem and GOOS=js don't map to these
+// Errno.
+func ToErrno(err error) Errno {
+	// handle all the cases of FS.Open or wasi_snapshot_preview1 to FSContext.OpenFile
+	switch {
+	case errors.Is(err, syscall.ENOSYS):
+		return ErrnoNosys
+	case errors.Is(err, fs.ErrInvalid):
+		return ErrnoInval
+	case errors.Is(err, fs.ErrNotExist):
+		// fs.FS is allowed to return this instead of ErrInvalid on an invalid path
+		return ErrnoNoent
+	case errors.Is(err, fs.ErrExist):
+		return ErrnoExist
+	case errors.Is(err, syscall.EBADF):
+		// fsc.OpenFile currently returns this on out of file descriptors
+		return ErrnoBadf
+	default:
+		return ErrnoIo
+	}
+}
diff --git a/internal/wasi_snapshot_preview1/fs.go b/internal/wasi_snapshot_preview1/fs.go
new file mode 100644
index 00000000..164c40be
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/fs.go
@@ -0,0 +1,135 @@
+package wasi_snapshot_preview1
+
+import (
+	"fmt"
+)
+
+const (
+	FdAdviseName           = "fd_advise"
+	FdAllocateName         = "fd_allocate"
+	FdCloseName            = "fd_close"
+	FdDatasyncName         = "fd_datasync"
+	FdFdstatGetName        = "fd_fdstat_get"
+	FdFdstatSetFlagsName   = "fd_fdstat_set_flags"
+	FdFdstatSetRightsName  = "fd_fdstat_set_rights"
+	FdFilestatGetName      = "fd_filestat_get"
+	FdFilestatSetSizeName  = "fd_filestat_set_size"
+	FdFilestatSetTimesName = "fd_filestat_set_times"
+	FdPreadName            = "fd_pread"
+	FdPrestatGetName       = "fd_prestat_get"
+	FdPrestatDirNameName   = "fd_prestat_dir_name"
+	FdPwriteName           = "fd_pwrite"
+	FdReadName             = "fd_read"
+	FdReaddirName          = "fd_readdir"
+	FdRenumberName         = "fd_renumber"
+	FdSeekName             = "fd_seek"
+	FdSyncName             = "fd_sync"
+	FdTellName             = "fd_tell"
+	FdWriteName            = "fd_write"
+
+	PathCreateDirectoryName  = "path_create_directory"
+	PathFilestatGetName      = "path_filestat_get"
+	PathFilestatSetTimesName = "path_filestat_set_times"
+	PathLinkName             = "path_link"
+	PathOpenName             = "path_open"
+	PathReadlinkName         = "path_readlink"
+	PathRemoveDirectoryName  = "path_remove_directory"
+	PathRenameName           = "path_rename"
+	PathSymlinkName          = "path_symlink"
+	PathUnlinkFileName       = "path_unlink_file"
+)
+
+// oflags are open flags used by path_open
+// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-oflags-flagsu16
+const (
+	// O_CREAT creates a file if it does not exist.
+	O_CREAT uint16 = 1 << iota //nolint
+	// O_DIRECTORY fails if not a directory.
+	O_DIRECTORY
+	// O_EXCL fails if file already exists.
+	O_EXCL //nolint
+	// O_TRUNC truncates the file to size 0.
+	O_TRUNC //nolint
+)
+
+func OflagsString(oflags int) string {
+	return flagsString(oflagNames[:], oflags)
+}
+
+var oflagNames = [...]string{
+	"CREAT",
+	"DIRECTORY",
+	"EXCL",
+	"TRUNC",
+}
+
+// file descriptor flags
+// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fdflags
+const (
+	FD_APPEND uint16 = 1 << iota //nolint
+	FD_DSYNC
+	FD_NONBLOCK
+	FD_RSYNC
+	FD_SYNC
+)
+
+func FdFlagsString(fdflags int) string {
+	return flagsString(fdflagNames[:], fdflags)
+}
+
+var fdflagNames = [...]string{
+	"APPEND",
+	"DSYNC",
+	"NONBLOCK",
+	"RSYNC",
+	"SYNC",
+}
+
+// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#lookupflags
+const (
+	// LOOKUP_SYMLINK_FOLLOW expands a path if it resolves into a symbolic
+	// link.
+	LOOKUP_SYMLINK_FOLLOW uint16 = 1 << iota //nolint
+)
+
+var lookupflagNames = [...]string{
+	"SYMLINK_FOLLOW",
+}
+
+func LookupflagsString(lookupflags int) string {
+	return flagsString(lookupflagNames[:], lookupflags)
+}
+
+// DirentSize is the size of the dirent struct, which should be followed by the
+// length of a file name.
+const DirentSize = uint32(24)
+
+const (
+	FILETYPE_UNKNOWN uint8 = iota
+	FILETYPE_BLOCK_DEVICE
+	FILETYPE_CHARACTER_DEVICE
+	FILETYPE_DIRECTORY
+	FILETYPE_REGULAR_FILE
+	FILETYPE_SOCKET_DGRAM
+	FILETYPE_SOCKET_STREAM
+	FILETYPE_SYMBOLIC_LINK
+)
+
+// FiletypeName returns string name of the file type.
+func FiletypeName(filetype uint8) string {
+	if int(filetype) < len(filetypeToString) {
+		return filetypeToString[filetype]
+	}
+	return fmt.Sprintf("filetype(%d)", filetype)
+}
+
+var filetypeToString = [...]string{
+	"UNKNOWN",
+	"BLOCK_DEVICE",
+	"CHARACTER_DEVICE",
+	"DIRECTORY",
+	"REGULAR_FILE",
+	"SOCKET_DGRAM",
+	"SOCKET_STREAM",
+	"SYMBOLIC_LINK",
+}
diff --git a/imports/wasi_snapshot_preview1/logging/logging.go b/internal/wasi_snapshot_preview1/logging/logging.go
similarity index 68%
rename from imports/wasi_snapshot_preview1/logging/logging.go
rename to internal/wasi_snapshot_preview1/logging/logging.go
index 88757969..c7c49b25 100644
--- a/imports/wasi_snapshot_preview1/logging/logging.go
+++ b/internal/wasi_snapshot_preview1/logging/logging.go
@@ -8,7 +8,7 @@ import (
 
 	"github.com/tetratelabs/wazero/api"
 	"github.com/tetratelabs/wazero/internal/logging"
-	"github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 var le = binary.LittleEndian
@@ -25,11 +25,11 @@ func IsFilesystemFunction(fnd api.FunctionDefinition) bool {
 
 func Config(fnd api.FunctionDefinition) (pLoggers []logging.ParamLogger, rLoggers []logging.ResultLogger) {
 	switch fnd.Name() {
-	case "fd_prestat_get":
+	case FdPrestatGetName:
 		pLoggers = []logging.ParamLogger{logging.NewParamLogger(0, "fd", logging.ValueTypeI32)}
 		rLoggers = []logging.ResultLogger{resultParamLogger("prestat", logPrestat(1).Log), logErrno}
 		return
-	case "proc_exit":
+	case ProcExitName:
 		return logging.ValueLoggers(fnd)
 	}
 
@@ -94,18 +94,18 @@ func Config(fnd api.FunctionDefinition) (pLoggers []logging.ParamLogger, rLogger
 
 func isLookupFlags(fnd api.FunctionDefinition, name string) bool {
 	switch fnd.Name() {
-	case "path_filestat_get", "path_filestat_set_times":
+	case PathFilestatGetName, PathFilestatSetTimesName:
 		return name == "flags"
-	case "path_link":
+	case PathLinkName:
 		return name == "old_flags"
-	case "path_open":
+	case PathOpenName:
 		return name == "dirflags"
 	}
 	return false
 }
 
 func logErrno(_ context.Context, _ api.Module, w logging.Writer, _, results []uint64) {
-	errno := wasi_snapshot_preview1.ErrnoName(uint32(results[0]))
+	errno := ErrnoName(uint32(results[0]))
 	w.WriteString("errno=") //nolint
 	w.WriteString(errno)    //nolint
 }
@@ -123,9 +123,9 @@ type logFilestat uint32
 func (i logFilestat) Log(_ context.Context, mod api.Module, w logging.Writer, params []uint64) {
 	offset, byteCount := uint32(params[i]), uint32(64)
 	if buf, ok := mod.Memory().Read(offset, byteCount); ok {
-		w.WriteString("{filetype=")                                 //nolint
-		w.WriteString(wasi_snapshot_preview1.FiletypeName(buf[16])) //nolint
-		w.WriteString(",size=")                                     //nolint
+		w.WriteString("{filetype=")          //nolint
+		w.WriteString(FiletypeName(buf[16])) //nolint
+		w.WriteString(",size=")              //nolint
 		writeI64(w, le.Uint64(buf[32:]))
 		w.WriteString(",mtim=") //nolint
 		writeI64(w, le.Uint64(buf[40:]))
@@ -138,15 +138,15 @@ type logFdstat uint32
 func (i logFdstat) Log(_ context.Context, mod api.Module, w logging.Writer, params []uint64) {
 	offset, byteCount := uint32(params[i]), uint32(24)
 	if buf, ok := mod.Memory().Read(offset, byteCount); ok {
-		w.WriteString("{filetype=")                                //nolint
-		w.WriteString(wasi_snapshot_preview1.FiletypeName(buf[0])) //nolint
-		w.WriteString(",fdflags=")                                 //nolint
-		writeFlags(w, fdflagNames[:], int(le.Uint16(buf[2:])))
-		w.WriteString(",fs_rights_base=") //nolint
-		writeFlags(w, rightNames[:], int(le.Uint16(buf[8:])))
-		w.WriteString(",fs_rights_inheriting=") //nolint
-		writeFlags(w, rightNames[:], int(le.Uint16(buf[16:])))
-		w.WriteString("}") //nolint
+		w.WriteString("{filetype=")                           //nolint
+		w.WriteString(FiletypeName(buf[0]))                   //nolint
+		w.WriteString(",fdflags=")                            //nolint
+		w.WriteString(FdFlagsString(int(le.Uint16(buf[2:])))) //nolint
+		w.WriteString(",fs_rights_base=")                     //nolint
+		w.WriteString(RightsString(int(le.Uint16(buf[8:]))))  //nolint
+		w.WriteString(",fs_rights_inheriting=")               //nolint
+		w.WriteString(RightsString(int(le.Uint16(buf[16:])))) //nolint
+		w.WriteString("}")                                    //nolint
 	}
 }
 
@@ -177,7 +177,7 @@ func resultParamLogger(name string, pLogger logging.ParamLogger) logging.ResultL
 	prefix := name + "="
 	return func(ctx context.Context, mod api.Module, w logging.Writer, params, results []uint64) {
 		w.WriteString(prefix) //nolint
-		if results[0] == 0 {  // ESUCCESS
+		if Errno(results[0]) == ErrnoSuccess {
 			pLogger(ctx, mod, w, params)
 		}
 	}
@@ -186,8 +186,8 @@ func resultParamLogger(name string, pLogger logging.ParamLogger) logging.ResultL
 type logFdflags int
 
 func (i logFdflags) Log(_ context.Context, _ api.Module, w logging.Writer, params []uint64) {
-	w.WriteString("fdflags=") //nolint
-	writeFlags(w, fdflagNames[:], int(params[i]))
+	w.WriteString("fdflags=")                    //nolint
+	w.WriteString(FdFlagsString(int(params[i]))) //nolint
 }
 
 type logLookupflags struct {
@@ -196,96 +196,30 @@ type logLookupflags struct {
 }
 
 func (l *logLookupflags) Log(_ context.Context, _ api.Module, w logging.Writer, params []uint64) {
-	w.WriteString(l.name) //nolint
-	w.WriteByte('=')      //nolint
-	writeFlags(w, lookupflagNames[:], int(params[l.i]))
+	w.WriteString(l.name)                              //nolint
+	w.WriteByte('=')                                   //nolint
+	w.WriteString(LookupflagsString(int(params[l.i]))) //nolint
 }
 
 type logFsRightsBase uint32
 
 func (i logFsRightsBase) Log(_ context.Context, _ api.Module, w logging.Writer, params []uint64) {
-	w.WriteString("fs_rights_base=") //nolint
-	writeFlags(w, rightNames[:], int(params[i]))
+	w.WriteString("fs_rights_base=")            //nolint
+	w.WriteString(RightsString(int(params[i]))) //nolint
 }
 
 type logFsRightsInheriting uint32
 
 func (i logFsRightsInheriting) Log(_ context.Context, _ api.Module, w logging.Writer, params []uint64) {
-	w.WriteString("fs_rights_inheriting=") //nolint
-	writeFlags(w, rightNames[:], int(params[i]))
+	w.WriteString("fs_rights_inheriting=")      //nolint
+	w.WriteString(RightsString(int(params[i]))) //nolint
 }
 
 type logOflags int
 
 func (i logOflags) Log(_ context.Context, _ api.Module, w logging.Writer, params []uint64) {
-	w.WriteString("oflags=") //nolint
-	writeFlags(w, oflagNames[:], int(params[i]))
-}
-
-func writeFlags(w logging.Writer, names []string, f int) {
-	first := true
-	for i, sf := range names {
-		target := 1 << i
-		if target&f != 0 {
-			if !first {
-				w.WriteByte('|') //nolint
-			} else {
-				first = false
-			}
-			w.WriteString(sf) //nolint
-		}
-	}
-}
-
-var oflagNames = [...]string{
-	"CREAT",
-	"DIRECTORY",
-	"EXCL",
-	"TRUNC",
-}
-
-var fdflagNames = [...]string{
-	"APPEND",
-	"DSYNC",
-	"NONBLOCK",
-	"RSYNC",
-	"SYNC",
-}
-
-var lookupflagNames = [...]string{
-	"SYMLINK_FOLLOW",
-}
-
-var rightNames = [...]string{
-	"FD_DATASYNC",
-	"FD_READ",
-	"FD_SEEK",
-	"FDSTAT_SET_FLAGS",
-	"FD_SYNC",
-	"FD_TELL",
-	"FD_WRITE",
-	"FD_ADVISE",
-	"FD_ALLOCATE",
-	"PATH_CREATE_DIRECTORY",
-	"PATH_CREATE_FILE",
-	"PATH_LINK_SOURCE",
-	"PATH_LINK_TARGET",
-	"PATH_OPEN",
-	"FD_READDIR",
-	"PATH_READLINK",
-	"PATH_RENAME_SOURCE",
-	"PATH_RENAME_TARGET",
-	"PATH_FILESTAT_GET",
-	"PATH_FILESTAT_SET_SIZE",
-	"PATH_FILESTAT_SET_TIMES",
-	"FD_FILESTAT_GET",
-	"FD_FILESTAT_SET_SIZE",
-	"FD_FILESTAT_SET_TIMES",
-	"PATH_SYMLINK",
-	"PATH_REMOVE_DIRECTORY",
-	"PATH_UNLINK_FILE",
-	"POLL_FD_READWRITE",
-	"SOCK_SHUTDOWN",
+	w.WriteString("oflags=")                    //nolint
+	w.WriteString(OflagsString(int(params[i]))) //nolint
 }
 
 func resultParamName(name string) string {
diff --git a/internal/wasi_snapshot_preview1/poll.go b/internal/wasi_snapshot_preview1/poll.go
new file mode 100644
index 00000000..1c234fd5
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/poll.go
@@ -0,0 +1,15 @@
+package wasi_snapshot_preview1
+
+// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-eventtype-enumu8
+const (
+	// EventTypeClock is the timeout event named "name".
+	EventTypeClock = iota
+	// EventTypeFdRead is the data available event named "fd_read".
+	EventTypeFdRead
+	// EventTypeFdWrite is the capacity available event named "fd_write".
+	EventTypeFdWrite
+)
+
+const (
+	PollOneoffName = "poll_oneoff"
+)
diff --git a/internal/wasi_snapshot_preview1/proc.go b/internal/wasi_snapshot_preview1/proc.go
new file mode 100644
index 00000000..d3d2d23a
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/proc.go
@@ -0,0 +1,6 @@
+package wasi_snapshot_preview1
+
+const (
+	ProcExitName  = "proc_exit"
+	ProcRaiseName = "proc_raise"
+)
diff --git a/internal/wasi_snapshot_preview1/random.go b/internal/wasi_snapshot_preview1/random.go
new file mode 100644
index 00000000..5ef2de24
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/random.go
@@ -0,0 +1,3 @@
+package wasi_snapshot_preview1
+
+const RandomGetName = "random_get"
diff --git a/internal/wasi_snapshot_preview1/rights.go b/internal/wasi_snapshot_preview1/rights.go
new file mode 100644
index 00000000..a720eb4d
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/rights.go
@@ -0,0 +1,148 @@
+package wasi_snapshot_preview1
+
+// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-rights-flagsu64
+const (
+	// RIGHT_FD_DATASYNC is the right to invoke fd_datasync. If RIGHT_PATH_OPEN
+	// is set, includes the right to invoke path_open with FD_DSYNC.
+	RIGHT_FD_DATASYNC uint32 = 1 << iota //nolint
+
+	// RIGHT_FD_READ is he right to invoke fd_read and sock_recv. If
+	// RIGHT_FD_SYNC is set, includes the right to invoke fd_pread.
+	RIGHT_FD_READ
+
+	// RIGHT_FD_SEEK is the right to invoke fd_seek. This flag implies
+	// RIGHT_FD_TELL.
+	RIGHT_FD_SEEK
+
+	// RIGHT_FDSTAT_SET_FLAGS is the right to invoke fd_fdstat_set_flags.
+	RIGHT_FDSTAT_SET_FLAGS
+
+	// RIGHT_FD_SYNC The right to invoke fd_sync. If path_open is set, includes
+	// the right to invoke path_open with FD_RSYNC and FD_DSYNC.
+	RIGHT_FD_SYNC
+
+	// RIGHT_FD_TELL is the right to invoke fd_seek in such a way that the file
+	// offset remains unaltered (i.e., whence::cur with offset zero), or to
+	// invoke fd_tell.
+	RIGHT_FD_TELL
+
+	// RIGHT_FD_WRITE is the right to invoke fd_write and sock_send. If
+	// RIGHT_FD_SEEK is set, includes the right to invoke fd_pwrite.
+	RIGHT_FD_WRITE
+
+	// RIGHT_FD_ADVISE is the right to invoke fd_advise.
+	RIGHT_FD_ADVISE
+
+	// RIGHT_FD_ALLOCATE is the right to invoke fd_allocate.
+	RIGHT_FD_ALLOCATE
+
+	// RIGHT_PATH_CREATE_DIRECTORY is the right to invoke
+	// path_create_directory.
+	RIGHT_PATH_CREATE_DIRECTORY
+
+	// RIGHT_PATH_CREATE_FILE when RIGHT_PATH_OPEN is set, the right to invoke
+	// path_open with O_CREATE.
+	RIGHT_PATH_CREATE_FILE
+
+	// RIGHT_PATH_LINK_SOURCE is the right to invoke path_link with the file
+	// descriptor as the source directory.
+	RIGHT_PATH_LINK_SOURCE
+
+	// RIGHT_PATH_LINK_TARGET is the right to invoke path_link with the file
+	// descriptor as the target directory.
+	RIGHT_PATH_LINK_TARGET
+
+	// RIGHT_PATH_OPEN is the right to invoke path_open.
+	RIGHT_PATH_OPEN
+
+	// RIGHT_FD_READDIR is the right to invoke fd_readdir.
+	RIGHT_FD_READDIR
+
+	// RIGHT_PATH_READLINK is the right to invoke path_readlink.
+	RIGHT_PATH_READLINK
+
+	// RIGHT_PATH_RENAME_SOURCE is the right to invoke path_rename with the
+	// file descriptor as the source directory.
+	RIGHT_PATH_RENAME_SOURCE
+
+	// RIGHT_PATH_RENAME_TARGET is the right to invoke path_rename with the
+	// file descriptor as the target directory.
+	RIGHT_PATH_RENAME_TARGET
+
+	// RIGHT_PATH_FILESTAT_GET is the right to invoke path_filestat_get.
+	RIGHT_PATH_FILESTAT_GET
+
+	// RIGHT_PATH_FILESTAT_SET_SIZE is the right to change a file's size (there
+	// is no path_filestat_set_size). If RIGHT_PATH_OPEN is set, includes the
+	// right to invoke path_open with O_TRUNC.
+	RIGHT_PATH_FILESTAT_SET_SIZE
+
+	// RIGHT_PATH_FILESTAT_SET_TIMES is the right to invoke
+	// path_filestat_set_times.
+	RIGHT_PATH_FILESTAT_SET_TIMES
+
+	// RIGHT_FD_FILESTAT_GET is the right to invoke fd_filestat_get.
+	RIGHT_FD_FILESTAT_GET
+
+	// RIGHT_FD_FILESTAT_SET_SIZE is the right to invoke fd_filestat_set_size.
+	RIGHT_FD_FILESTAT_SET_SIZE
+
+	// RIGHT_FD_FILESTAT_SET_TIMES is the right to invoke
+	// fd_filestat_set_times.
+	RIGHT_FD_FILESTAT_SET_TIMES
+
+	// RIGHT_PATH_SYMLINK is the right to invoke path_symlink.
+	RIGHT_PATH_SYMLINK
+
+	// RIGHT_PATH_REMOVE_DIRECTORY is the right to invoke
+	// path_remove_directory.
+	RIGHT_PATH_REMOVE_DIRECTORY
+
+	// RIGHT_PATH_UNLINK_FILE is the right to invoke path_unlink_file.
+	RIGHT_PATH_UNLINK_FILE
+
+	// RIGHT_POLL_FD_READWRITE when RIGHT_FD_READ is set, includes the right to
+	// invoke poll_oneoff to subscribe to eventtype::fd_read. If RIGHT_FD_WRITE
+	// is set, includes the right to invoke poll_oneoff to subscribe to
+	// eventtype::fd_write.
+	RIGHT_POLL_FD_READWRITE
+
+	// RIGHT_SOCK_SHUTDOWN is the right to invoke sock_shutdown.
+	RIGHT_SOCK_SHUTDOWN
+)
+
+func RightsString(rights int) string {
+	return flagsString(rightNames[:], rights)
+}
+
+var rightNames = [...]string{
+	"FD_DATASYNC",
+	"FD_READ",
+	"FD_SEEK",
+	"FDSTAT_SET_FLAGS",
+	"FD_SYNC",
+	"FD_TELL",
+	"FD_WRITE",
+	"FD_ADVISE",
+	"FD_ALLOCATE",
+	"PATH_CREATE_DIRECTORY",
+	"PATH_CREATE_FILE",
+	"PATH_LINK_SOURCE",
+	"PATH_LINK_TARGET",
+	"PATH_OPEN",
+	"FD_READDIR",
+	"PATH_READLINK",
+	"PATH_RENAME_SOURCE",
+	"PATH_RENAME_TARGET",
+	"PATH_FILESTAT_GET",
+	"PATH_FILESTAT_SET_SIZE",
+	"PATH_FILESTAT_SET_TIMES",
+	"FD_FILESTAT_GET",
+	"FD_FILESTAT_SET_SIZE",
+	"FD_FILESTAT_SET_TIMES",
+	"PATH_SYMLINK",
+	"PATH_REMOVE_DIRECTORY",
+	"PATH_UNLINK_FILE",
+	"POLL_FD_READWRITE",
+	"SOCK_SHUTDOWN",
+}
diff --git a/internal/wasi_snapshot_preview1/sched.go b/internal/wasi_snapshot_preview1/sched.go
new file mode 100644
index 00000000..6badce80
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/sched.go
@@ -0,0 +1,3 @@
+package wasi_snapshot_preview1
+
+const SchedYieldName = "sched_yield"
diff --git a/internal/wasi_snapshot_preview1/sock.go b/internal/wasi_snapshot_preview1/sock.go
new file mode 100644
index 00000000..48d4d11f
--- /dev/null
+++ b/internal/wasi_snapshot_preview1/sock.go
@@ -0,0 +1,8 @@
+package wasi_snapshot_preview1
+
+const (
+	SockAcceptName   = "sock_accept"
+	SockRecvName     = "sock_recv"
+	SockSendName     = "sock_send"
+	SockShutdownName = "sock_shutdown"
+)
diff --git a/internal/wasi_snapshot_preview1/wasi.go b/internal/wasi_snapshot_preview1/wasi.go
index ee51c4da..eb74fcad 100644
--- a/internal/wasi_snapshot_preview1/wasi.go
+++ b/internal/wasi_snapshot_preview1/wasi.go
@@ -1,268 +1,27 @@
-// Package wasi_snapshot_preview1 is an internal helper to remove package
-// cycles re-using errno
+// Package wasi_snapshot_preview1 is a helper to remove package cycles re-using
+// constants.
 package wasi_snapshot_preview1
 
 import (
-	"fmt"
+	"strings"
 )
 
-const ModuleName = "wasi_snapshot_preview1"
-
-// ErrnoName returns the POSIX error code name, except ErrnoSuccess, which is not an error. e.g. Errno2big -> "E2BIG"
-func ErrnoName(errno uint32) string {
-	if int(errno) < len(errnoToString) {
-		return errnoToString[errno]
-	}
-	return fmt.Sprintf("errno(%d)", errno)
-}
-
-var errnoToString = [...]string{
-	"ESUCCESS",
-	"E2BIG",
-	"EACCES",
-	"EADDRINUSE",
-	"EADDRNOTAVAIL",
-	"EAFNOSUPPORT",
-	"EAGAIN",
-	"EALREADY",
-	"EBADF",
-	"EBADMSG",
-	"EBUSY",
-	"ECANCELED",
-	"ECHILD",
-	"ECONNABORTED",
-	"ECONNREFUSED",
-	"ECONNRESET",
-	"EDEADLK",
-	"EDESTADDRREQ",
-	"EDOM",
-	"EDQUOT",
-	"EEXIST",
-	"EFAULT",
-	"EFBIG",
-	"EHOSTUNREACH",
-	"EIDRM",
-	"EILSEQ",
-	"EINPROGRESS",
-	"EINTR",
-	"EINVAL",
-	"EIO",
-	"EISCONN",
-	"EISDIR",
-	"ELOOP",
-	"EMFILE",
-	"EMLINK",
-	"EMSGSIZE",
-	"EMULTIHOP",
-	"ENAMETOOLONG",
-	"ENETDOWN",
-	"ENETRESET",
-	"ENETUNREACH",
-	"ENFILE",
-	"ENOBUFS",
-	"ENODEV",
-	"ENOENT",
-	"ENOEXEC",
-	"ENOLCK",
-	"ENOLINK",
-	"ENOMEM",
-	"ENOMSG",
-	"ENOPROTOOPT",
-	"ENOSPC",
-	"ENOSYS",
-	"ENOTCONN",
-	"ENOTDIR",
-	"ENOTEMPTY",
-	"ENOTRECOVERABLE",
-	"ENOTSOCK",
-	"ENOTSUP",
-	"ENOTTY",
-	"ENXIO",
-	"EOVERFLOW",
-	"EOWNERDEAD",
-	"EPERM",
-	"EPIPE",
-	"EPROTO",
-	"EPROTONOSUPPORT",
-	"EPROTOTYPE",
-	"ERANGE",
-	"EROFS",
-	"ESPIPE",
-	"ESRCH",
-	"ESTALE",
-	"ETIMEDOUT",
-	"ETXTBSY",
-	"EXDEV",
-	"ENOTCAPABLE",
-}
-
-// oflags are open flags used by path_open
-// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-oflags-flagsu16
-const (
-	// O_CREAT creates a file if it does not exist.
-	O_CREAT uint16 = 1 << iota //nolint
-	// O_DIRECTORY fails if not a directory.
-	O_DIRECTORY
-	// O_EXCL fails if file already exists.
-	O_EXCL //nolint
-	// O_TRUNC truncates the file to size 0.
-	O_TRUNC //nolint
-)
-
-// file descriptor flags
-// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fdflags
-const (
-	FD_APPEND uint16 = 1 << iota //nolint
-	FD_DSYNC
-	FD_NONBLOCK
-	FD_RSYNC
-	FD_SYNC
-)
-
-// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#lookupflags
-const (
-	// LOOKUP_SYMLINK_FOLLOW expands a path if it resolves into a symbolic
-	// link.
-	LOOKUP_SYMLINK_FOLLOW uint16 = 1 << iota //nolint
-)
-
-// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-rights-flagsu64
-const (
-	// RIGHT_FD_DATASYNC is the right to invoke fd_datasync. If RIGHT_PATH_OPEN
-	// is set, includes the right to invoke path_open with FD_DSYNC.
-	RIGHT_FD_DATASYNC uint32 = 1 << iota //nolint
-
-	// RIGHT_FD_READ is he right to invoke fd_read and sock_recv. If
-	// RIGHT_FD_SYNC is set, includes the right to invoke fd_pread.
-	RIGHT_FD_READ
-
-	// RIGHT_FD_SEEK is the right to invoke fd_seek. This flag implies
-	// RIGHT_FD_TELL.
-	RIGHT_FD_SEEK
-
-	// RIGHT_FDSTAT_SET_FLAGS is the right to invoke fd_fdstat_set_flags.
-	RIGHT_FDSTAT_SET_FLAGS
-
-	// RIGHT_FD_SYNC The right to invoke fd_sync. If path_open is set, includes
-	// the right to invoke path_open with FD_RSYNC and FD_DSYNC.
-	RIGHT_FD_SYNC
-
-	// RIGHT_FD_TELL is the right to invoke fd_seek in such a way that the file
-	// offset remains unaltered (i.e., whence::cur with offset zero), or to
-	// invoke fd_tell.
-	RIGHT_FD_TELL
-
-	// RIGHT_FD_WRITE is the right to invoke fd_write and sock_send. If
-	// RIGHT_FD_SEEK is set, includes the right to invoke fd_pwrite.
-	RIGHT_FD_WRITE
-
-	// RIGHT_FD_ADVISE is the right to invoke fd_advise.
-	RIGHT_FD_ADVISE
-
-	// RIGHT_FD_ALLOCATE is the right to invoke fd_allocate.
-	RIGHT_FD_ALLOCATE
-
-	// RIGHT_PATH_CREATE_DIRECTORY is the right to invoke
-	// path_create_directory.
-	RIGHT_PATH_CREATE_DIRECTORY
-
-	// RIGHT_PATH_CREATE_FILE when RIGHT_PATH_OPEN is set, the right to invoke
-	// path_open with O_CREATE.
-	RIGHT_PATH_CREATE_FILE
-
-	// RIGHT_PATH_LINK_SOURCE is the right to invoke path_link with the file
-	// descriptor as the source directory.
-	RIGHT_PATH_LINK_SOURCE
-
-	// RIGHT_PATH_LINK_TARGET is the right to invoke path_link with the file
-	// descriptor as the target directory.
-	RIGHT_PATH_LINK_TARGET
-
-	// RIGHT_PATH_OPEN is the right to invoke path_open.
-	RIGHT_PATH_OPEN
-
-	// RIGHT_FD_READDIR is the right to invoke fd_readdir.
-	RIGHT_FD_READDIR
-
-	// RIGHT_PATH_READLINK is the right to invoke path_readlink.
-	RIGHT_PATH_READLINK
-
-	// RIGHT_PATH_RENAME_SOURCE is the right to invoke path_rename with the
-	// file descriptor as the source directory.
-	RIGHT_PATH_RENAME_SOURCE
-
-	// RIGHT_PATH_RENAME_TARGET is the right to invoke path_rename with the
-	// file descriptor as the target directory.
-	RIGHT_PATH_RENAME_TARGET
-
-	// RIGHT_PATH_FILESTAT_GET is the right to invoke path_filestat_get.
-	RIGHT_PATH_FILESTAT_GET
-
-	// RIGHT_PATH_FILESTAT_SET_SIZE is the right to change a file's size (there
-	// is no path_filestat_set_size). If RIGHT_PATH_OPEN is set, includes the
-	// right to invoke path_open with O_TRUNC.
-	RIGHT_PATH_FILESTAT_SET_SIZE
-
-	// RIGHT_PATH_FILESTAT_SET_TIMES is the right to invoke
-	// path_filestat_set_times.
-	RIGHT_PATH_FILESTAT_SET_TIMES
-
-	// RIGHT_FD_FILESTAT_GET is the right to invoke fd_filestat_get.
-	RIGHT_FD_FILESTAT_GET
-
-	// RIGHT_FD_FILESTAT_SET_SIZE is the right to invoke fd_filestat_set_size.
-	RIGHT_FD_FILESTAT_SET_SIZE
-
-	// RIGHT_FD_FILESTAT_SET_TIMES is the right to invoke
-	// fd_filestat_set_times.
-	RIGHT_FD_FILESTAT_SET_TIMES
-
-	// RIGHT_PATH_SYMLINK is the right to invoke path_symlink.
-	RIGHT_PATH_SYMLINK
-
-	// RIGHT_PATH_REMOVE_DIRECTORY is the right to invoke
-	// path_remove_directory.
-	RIGHT_PATH_REMOVE_DIRECTORY
-
-	// RIGHT_PATH_UNLINK_FILE is the right to invoke path_unlink_file.
-	RIGHT_PATH_UNLINK_FILE
-
-	// RIGHT_POLL_FD_READWRITE when RIGHT_FD_READ is set, includes the right to
-	// invoke poll_oneoff to subscribe to eventtype::fd_read. If RIGHT_FD_WRITE
-	// is set, includes the right to invoke poll_oneoff to subscribe to
-	// eventtype::fd_write.
-	RIGHT_POLL_FD_READWRITE
-
-	// RIGHT_SOCK_SHUTDOWN is the right to invoke sock_shutdown.
-	RIGHT_SOCK_SHUTDOWN
-)
-
-const (
-	FILETYPE_UNKNOWN uint8 = iota
-	FILETYPE_BLOCK_DEVICE
-	FILETYPE_CHARACTER_DEVICE
-	FILETYPE_DIRECTORY
-	FILETYPE_REGULAR_FILE
-	FILETYPE_SOCKET_DGRAM
-	FILETYPE_SOCKET_STREAM
-	FILETYPE_SYMBOLIC_LINK
-)
-
-// FiletypeName returns string name of the file type.
-func FiletypeName(filetype uint8) string {
-	if int(filetype) < len(filetypeToString) {
-		return filetypeToString[filetype]
+// InternalModuleName is not named ModuleName, to avoid a clash on dot imports.
+const InternalModuleName = "wasi_snapshot_preview1"
+
+func flagsString(names []string, f int) string {
+	var builder strings.Builder
+	first := true
+	for i, sf := range names {
+		target := 1 << i
+		if target&f != 0 {
+			if !first {
+				builder.WriteByte('|')
+			} else {
+				first = false
+			}
+			builder.WriteString(sf)
+		}
 	}
-	return fmt.Sprintf("filetype(%d)", filetype)
-}
-
-var filetypeToString = [...]string{
-	"UNKNOWN",
-	"BLOCK_DEVICE",
-	"CHARACTER_DEVICE",
-	"DIRECTORY",
-	"REGULAR_FILE",
-	"SOCKET_DGRAM",
-	"SOCKET_STREAM",
-	"SYMBOLIC_LINK",
+	return builder.String()
 }


Test patch:
diff --git a/experimental/logging/log_listener_test.go b/experimental/logging/log_listener_test.go
index 050b1d65..6cd5c117 100644
--- a/experimental/logging/log_listener_test.go
+++ b/experimental/logging/log_listener_test.go
@@ -9,8 +9,8 @@ import (
 
 	"github.com/tetratelabs/wazero/api"
 	"github.com/tetratelabs/wazero/experimental/logging"
-	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	wasi "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
@@ -18,7 +18,7 @@ import (
 var testCtx = context.WithValue(context.Background(), struct{}{}, "arbitrary")
 
 func Test_loggingListener(t *testing.T) {
-	wasiFuncName := "random_get"
+	wasiFuncName := wasi.RandomGetName
 	wasiFuncType := &wasm.FunctionType{
 		Params:  []api.ValueType{api.ValueTypeI32, api.ValueTypeI32},
 		Results: []api.ValueType{api.ValueTypeI32},
@@ -63,13 +63,13 @@ func Test_loggingListener(t *testing.T) {
 		{
 			name:        "wasi",
 			functype:    wasiFuncType,
-			moduleName:  wasi_snapshot_preview1.ModuleName,
+			moduleName:  wasi.InternalModuleName,
 			funcName:    wasiFuncName,
 			paramNames:  wasiParamNames,
 			resultNames: wasiResultNames,
 			isHostFunc:  true,
 			params:      wasiParams,
-			results:     []uint64{uint64(wasi_snapshot_preview1.ErrnoSuccess)},
+			results:     []uint64{uint64(wasi.ErrnoSuccess)},
 			expected: `==> wasi_snapshot_preview1.random_get(buf=0,buf_len=8)
 <== errno=ESUCCESS
 `,
@@ -77,13 +77,13 @@ func Test_loggingListener(t *testing.T) {
 		{
 			name:        "wasi errno",
 			functype:    wasiFuncType,
-			moduleName:  wasi_snapshot_preview1.ModuleName,
+			moduleName:  wasi.InternalModuleName,
 			funcName:    wasiFuncName,
 			paramNames:  wasiParamNames,
 			resultNames: wasiResultNames,
 			isHostFunc:  true,
 			params:      wasiParams,
-			results:     []uint64{uint64(wasi_snapshot_preview1.ErrnoFault)},
+			results:     []uint64{uint64(wasi.ErrnoFault)},
 			expected: `==> wasi_snapshot_preview1.random_get(buf=0,buf_len=8)
 <== errno=EFAULT
 `,
@@ -91,7 +91,7 @@ func Test_loggingListener(t *testing.T) {
 		{
 			name:        "wasi error",
 			functype:    wasiFuncType,
-			moduleName:  wasi_snapshot_preview1.ModuleName,
+			moduleName:  wasi.InternalModuleName,
 			funcName:    wasiFuncName,
 			paramNames:  wasiParamNames,
 			resultNames: wasiResultNames,
diff --git a/imports/wasi_snapshot_preview1/args_test.go b/imports/wasi_snapshot_preview1/args_test.go
index 5c669be6..0173cda2 100644
--- a/imports/wasi_snapshot_preview1/args_test.go
+++ b/imports/wasi_snapshot_preview1/args_test.go
@@ -1,10 +1,11 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"testing"
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 func Test_argsGet(t *testing.T) {
@@ -25,7 +26,7 @@ func Test_argsGet(t *testing.T) {
 	maskMemory(t, mod, len(expectedMemory)+int(argvBuf))
 
 	// Invoke argsGet and check the memory side effects.
-	requireErrno(t, ErrnoSuccess, mod, argsGetName, uint64(argv), uint64(argvBuf))
+	requireErrno(t, ErrnoSuccess, mod, ArgsGetName, uint64(argv), uint64(argvBuf))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.args_get(argv=22,argv_buf=16)
 <== errno=ESUCCESS
@@ -94,7 +95,7 @@ func Test_argsGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, ErrnoFault, mod, argsGetName, uint64(tc.argv), uint64(tc.argvBuf))
+			requireErrno(t, ErrnoFault, mod, ArgsGetName, uint64(tc.argv), uint64(tc.argvBuf))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -117,7 +118,7 @@ func Test_argsSizesGet(t *testing.T) {
 	maskMemory(t, mod, int(resultArgc)+len(expectedMemory))
 
 	// Invoke argsSizesGet and check the memory side effects.
-	requireErrno(t, ErrnoSuccess, mod, argsSizesGetName, uint64(resultArgc), uint64(resultArgvLen))
+	requireErrno(t, ErrnoSuccess, mod, ArgsSizesGetName, uint64(resultArgc), uint64(resultArgvLen))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.args_sizes_get(result.argc=16,result.argv_len=21)
 <== errno=ESUCCESS
@@ -184,7 +185,7 @@ func Test_argsSizesGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, ErrnoFault, mod, argsSizesGetName, uint64(tc.argc), uint64(tc.argvLen))
+			requireErrno(t, ErrnoFault, mod, ArgsSizesGetName, uint64(tc.argc), uint64(tc.argvLen))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
diff --git a/imports/wasi_snapshot_preview1/clock_test.go b/imports/wasi_snapshot_preview1/clock_test.go
index 10ffd24f..339d29e0 100644
--- a/imports/wasi_snapshot_preview1/clock_test.go
+++ b/imports/wasi_snapshot_preview1/clock_test.go
@@ -1,4 +1,4 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	_ "embed"
@@ -6,6 +6,7 @@ import (
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 func Test_clockResGet(t *testing.T) {
@@ -32,7 +33,7 @@ func Test_clockResGet(t *testing.T) {
 	}{
 		{
 			name:           "Realtime",
-			clockID:        clockIDRealtime,
+			clockID:        ClockIDRealtime,
 			expectedMemory: expectedMemoryMicro,
 			expectedLog: `
 ==> wasi_snapshot_preview1.clock_res_get(id=0,result.resolution=16)
@@ -41,7 +42,7 @@ func Test_clockResGet(t *testing.T) {
 		},
 		{
 			name:           "Monotonic",
-			clockID:        clockIDMonotonic,
+			clockID:        ClockIDMonotonic,
 			expectedMemory: expectedMemoryNano,
 			expectedLog: `
 ==> wasi_snapshot_preview1.clock_res_get(id=1,result.resolution=16)
@@ -59,7 +60,7 @@ func Test_clockResGet(t *testing.T) {
 			resultResolution := 16 // arbitrary offset
 			maskMemory(t, mod, resultResolution+len(tc.expectedMemory))
 
-			requireErrno(t, ErrnoSuccess, mod, clockResGetName, uint64(tc.clockID), uint64(resultResolution))
+			requireErrno(t, ErrnoSuccess, mod, ClockResGetName, uint64(tc.clockID), uint64(resultResolution))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(uint32(resultResolution-1), uint32(len(tc.expectedMemory)))
@@ -115,7 +116,7 @@ func Test_clockResGet_Unsupported(t *testing.T) {
 			defer log.Reset()
 
 			resultResolution := 16 // arbitrary offset
-			requireErrno(t, tc.expectedErrno, mod, clockResGetName, uint64(tc.clockID), uint64(resultResolution))
+			requireErrno(t, tc.expectedErrno, mod, ClockResGetName, uint64(tc.clockID), uint64(resultResolution))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -133,7 +134,7 @@ func Test_clockTimeGet(t *testing.T) {
 	}{
 		{
 			name:    "Realtime",
-			clockID: clockIDRealtime,
+			clockID: ClockIDRealtime,
 			expectedMemory: []byte{
 				'?',                                          // resultTimestamp is after this
 				0x0, 0x0, 0x1f, 0xa6, 0x70, 0xfc, 0xc5, 0x16, // little endian-encoded epochNanos
@@ -146,7 +147,7 @@ func Test_clockTimeGet(t *testing.T) {
 		},
 		{
 			name:    "Monotonic",
-			clockID: clockIDMonotonic,
+			clockID: ClockIDMonotonic,
 			expectedMemory: []byte{
 				'?',                                    // resultTimestamp is after this
 				0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // fake nanotime starts at zero
@@ -167,7 +168,7 @@ func Test_clockTimeGet(t *testing.T) {
 			resultTimestamp := 16 // arbitrary offset
 			maskMemory(t, mod, resultTimestamp+len(tc.expectedMemory))
 
-			requireErrno(t, ErrnoSuccess, mod, clockTimeGetName, uint64(tc.clockID), 0 /* TODO: precision */, uint64(resultTimestamp))
+			requireErrno(t, ErrnoSuccess, mod, ClockTimeGetName, uint64(tc.clockID), 0 /* TODO: precision */, uint64(resultTimestamp))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(uint32(resultTimestamp-1), uint32(len(tc.expectedMemory)))
@@ -223,7 +224,7 @@ func Test_clockTimeGet_Unsupported(t *testing.T) {
 			defer log.Reset()
 
 			resultTimestamp := 16 // arbitrary offset
-			requireErrno(t, tc.expectedErrno, mod, clockTimeGetName, uint64(tc.clockID), uint64(0) /* TODO: precision */, uint64(resultTimestamp))
+			requireErrno(t, tc.expectedErrno, mod, ClockTimeGetName, uint64(tc.clockID), uint64(0) /* TODO: precision */, uint64(resultTimestamp))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -264,7 +265,7 @@ func Test_clockTimeGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, ErrnoFault, mod, clockTimeGetName, uint64(0) /* TODO: id */, uint64(0) /* TODO: precision */, uint64(tc.resultTimestamp))
+			requireErrno(t, ErrnoFault, mod, ClockTimeGetName, uint64(0) /* TODO: id */, uint64(0) /* TODO: precision */, uint64(tc.resultTimestamp))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
diff --git a/imports/wasi_snapshot_preview1/environ_test.go b/imports/wasi_snapshot_preview1/environ_test.go
index 798cb0f1..a5c11a43 100644
--- a/imports/wasi_snapshot_preview1/environ_test.go
+++ b/imports/wasi_snapshot_preview1/environ_test.go
@@ -1,10 +1,11 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"testing"
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 func Test_environGet(t *testing.T) {
@@ -27,7 +28,7 @@ func Test_environGet(t *testing.T) {
 	maskMemory(t, mod, len(expectedMemory)+int(resultEnvironBuf))
 
 	// Invoke environGet and check the memory side effects.
-	requireErrno(t, ErrnoSuccess, mod, environGetName, uint64(resultEnviron), uint64(resultEnvironBuf))
+	requireErrno(t, ErrnoSuccess, mod, EnvironGetName, uint64(resultEnviron), uint64(resultEnvironBuf))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.environ_get(environ=26,environ_buf=16)
 <== errno=ESUCCESS
@@ -97,7 +98,7 @@ func Test_environGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, ErrnoFault, mod, environGetName, uint64(tc.environ), uint64(tc.environBuf))
+			requireErrno(t, ErrnoFault, mod, EnvironGetName, uint64(tc.environ), uint64(tc.environBuf))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -121,7 +122,7 @@ func Test_environSizesGet(t *testing.T) {
 	maskMemory(t, mod, len(expectedMemory)+int(resultEnvironc))
 
 	// Invoke environSizesGet and check the memory side effects.
-	requireErrno(t, ErrnoSuccess, mod, environSizesGetName, uint64(resultEnvironc), uint64(resultEnvironvLen))
+	requireErrno(t, ErrnoSuccess, mod, EnvironSizesGetName, uint64(resultEnvironc), uint64(resultEnvironvLen))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.environ_sizes_get(result.environc=16,result.environv_len=21)
 <== errno=ESUCCESS
@@ -189,7 +190,7 @@ func Test_environSizesGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, ErrnoFault, mod, environSizesGetName, uint64(tc.environc), uint64(tc.environLen))
+			requireErrno(t, ErrnoFault, mod, EnvironSizesGetName, uint64(tc.environc), uint64(tc.environLen))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
diff --git a/imports/wasi_snapshot_preview1/example_test.go b/imports/wasi_snapshot_preview1/example_test.go
index aaed1cee..3abd0a4c 100644
--- a/imports/wasi_snapshot_preview1/example_test.go
+++ b/imports/wasi_snapshot_preview1/example_test.go
@@ -1,4 +1,4 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"context"
@@ -8,6 +8,7 @@ import (
 	"os"
 
 	"github.com/tetratelabs/wazero"
+	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/sys"
 )
 
@@ -27,13 +28,10 @@ func Example() {
 
 	// Create a new WebAssembly Runtime.
 	r := wazero.NewRuntime(ctx)
+	defer r.Close(ctx)
 
 	// Instantiate WASI, which implements system I/O such as console output.
-	wm, err := Instantiate(ctx, r)
-	if err != nil {
-		log.Panicln(err)
-	}
-	defer wm.Close(testCtx)
+	wasi_snapshot_preview1.MustInstantiate(ctx, r)
 
 	// Compile the WebAssembly module using the default configuration.
 	code, err := r.CompileModule(ctx, exitOnStartWasm)
diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go
index 00cb7be1..f96e5401 100644
--- a/imports/wasi_snapshot_preview1/fs_test.go
+++ b/imports/wasi_snapshot_preview1/fs_test.go
@@ -1,4 +1,4 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"bytes"
@@ -15,15 +15,15 @@ import (
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/api"
 	"github.com/tetratelabs/wazero/internal/leb128"
-	internalsys "github.com/tetratelabs/wazero/internal/sys"
+	"github.com/tetratelabs/wazero/internal/sys"
 	"github.com/tetratelabs/wazero/internal/testing/require"
-	"github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
 // Test_fdAdvise only tests it is stubbed for GrainLang per #271
 func Test_fdAdvise(t *testing.T) {
-	log := requireErrnoNosys(t, fdAdviseName, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, FdAdviseName, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_advise(fd=0,offset=0,len=0,advice=0)
 <-- errno=ENOSYS
@@ -32,7 +32,7 @@ func Test_fdAdvise(t *testing.T) {
 
 // Test_fdAllocate only tests it is stubbed for GrainLang per #271
 func Test_fdAllocate(t *testing.T) {
-	log := requireErrnoNosys(t, fdAllocateName, 0, 0, 0)
+	log := requireErrnoNosys(t, FdAllocateName, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_allocate(fd=0,offset=0,len=0)
 <-- errno=ENOSYS
@@ -57,7 +57,7 @@ func Test_fdClose(t *testing.T) {
 	require.NoError(t, err)
 
 	// Close
-	requireErrno(t, ErrnoSuccess, mod, fdCloseName, uint64(fdToClose))
+	requireErrno(t, ErrnoSuccess, mod, FdCloseName, uint64(fdToClose))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_close(fd=4)
 <== errno=ESUCCESS
@@ -73,7 +73,7 @@ func Test_fdClose(t *testing.T) {
 
 	log.Reset()
 	t.Run("ErrnoBadF for an invalid FD", func(t *testing.T) {
-		requireErrno(t, ErrnoBadf, mod, fdCloseName, uint64(42)) // 42 is an arbitrary invalid FD
+		requireErrno(t, ErrnoBadf, mod, FdCloseName, uint64(42)) // 42 is an arbitrary invalid FD
 		require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_close(fd=42)
 <== errno=EBADF
@@ -83,7 +83,7 @@ func Test_fdClose(t *testing.T) {
 
 // Test_fdDatasync only tests it is stubbed for GrainLang per #271
 func Test_fdDatasync(t *testing.T) {
-	log := requireErrnoNosys(t, fdDatasyncName, 0)
+	log := requireErrnoNosys(t, FdDatasyncName, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_datasync(fd=0)
 <-- errno=ENOSYS
@@ -116,7 +116,7 @@ func Test_fdFdstatGet(t *testing.T) {
 	}{
 		{
 			name: "stdin",
-			fd:   internalsys.FdStdin,
+			fd:   sys.FdStdin,
 			expectedMemory: []byte{
 				1, 0, // fs_filetype
 				0, 0, 0, 0, 0, 0, // fs_flags
@@ -130,7 +130,7 @@ func Test_fdFdstatGet(t *testing.T) {
 		},
 		{
 			name: "stdout",
-			fd:   internalsys.FdStdout,
+			fd:   sys.FdStdout,
 			expectedMemory: []byte{
 				1, 0, // fs_filetype
 				1, 0, 0, 0, 0, 0, // fs_flags
@@ -144,7 +144,7 @@ func Test_fdFdstatGet(t *testing.T) {
 		},
 		{
 			name: "stderr",
-			fd:   internalsys.FdStderr,
+			fd:   sys.FdStderr,
 			expectedMemory: []byte{
 				1, 0, // fs_filetype
 				1, 0, 0, 0, 0, 0, // fs_flags
@@ -158,7 +158,7 @@ func Test_fdFdstatGet(t *testing.T) {
 		},
 		{
 			name: "root",
-			fd:   internalsys.FdRoot,
+			fd:   sys.FdRoot,
 			expectedMemory: []byte{
 				3, 0, // fs_filetype
 				0, 0, 0, 0, 0, 0, // fs_flags
@@ -227,7 +227,7 @@ func Test_fdFdstatGet(t *testing.T) {
 
 			maskMemory(t, mod, len(tc.expectedMemory))
 
-			requireErrno(t, tc.expectedErrno, mod, fdFdstatGetName, uint64(tc.fd), uint64(tc.resultFdstat))
+			requireErrno(t, tc.expectedErrno, mod, FdFdstatGetName, uint64(tc.fd), uint64(tc.resultFdstat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
@@ -239,7 +239,7 @@ func Test_fdFdstatGet(t *testing.T) {
 
 // Test_fdFdstatSetFlags only tests it is stubbed for GrainLang per #271
 func Test_fdFdstatSetFlags(t *testing.T) {
-	log := requireErrnoNosys(t, fdFdstatSetFlagsName, 0, 0)
+	log := requireErrnoNosys(t, FdFdstatSetFlagsName, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_fdstat_set_flags(fd=0,flags=0)
 <-- errno=ENOSYS
@@ -248,7 +248,7 @@ func Test_fdFdstatSetFlags(t *testing.T) {
 
 // Test_fdFdstatSetRights only tests it is stubbed for GrainLang per #271
 func Test_fdFdstatSetRights(t *testing.T) {
-	log := requireErrnoNosys(t, fdFdstatSetRightsName, 0, 0, 0)
+	log := requireErrnoNosys(t, FdFdstatSetRightsName, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_fdstat_set_rights(fd=0,fs_rights_base=,fs_rights_inheriting=)
 <-- errno=ENOSYS
@@ -285,7 +285,7 @@ func Test_fdFilestatGet(t *testing.T) {
 	}{
 		{
 			name: "stdin",
-			fd:   internalsys.FdStdin,
+			fd:   sys.FdStdin,
 			expectedMemory: []byte{
 				0, 0, 0, 0, 0, 0, 0, 0, // dev
 				0, 0, 0, 0, 0, 0, 0, 0, // ino
@@ -304,7 +304,7 @@ func Test_fdFilestatGet(t *testing.T) {
 		},
 		{
 			name: "stdout",
-			fd:   internalsys.FdStdout,
+			fd:   sys.FdStdout,
 			expectedMemory: []byte{
 				0, 0, 0, 0, 0, 0, 0, 0, // dev
 				0, 0, 0, 0, 0, 0, 0, 0, // ino
@@ -323,7 +323,7 @@ func Test_fdFilestatGet(t *testing.T) {
 		},
 		{
 			name: "stderr",
-			fd:   internalsys.FdStderr,
+			fd:   sys.FdStderr,
 			expectedMemory: []byte{
 				0, 0, 0, 0, 0, 0, 0, 0, // dev
 				0, 0, 0, 0, 0, 0, 0, 0, // ino
@@ -342,7 +342,7 @@ func Test_fdFilestatGet(t *testing.T) {
 		},
 		{
 			name: "root",
-			fd:   internalsys.FdRoot,
+			fd:   sys.FdRoot,
 			expectedMemory: []byte{
 				0, 0, 0, 0, 0, 0, 0, 0, // dev
 				0, 0, 0, 0, 0, 0, 0, 0, // ino
@@ -423,7 +423,7 @@ func Test_fdFilestatGet(t *testing.T) {
 
 			maskMemory(t, mod, len(tc.expectedMemory))
 
-			requireErrno(t, tc.expectedErrno, mod, fdFilestatGetName, uint64(tc.fd), uint64(tc.resultFilestat))
+			requireErrno(t, tc.expectedErrno, mod, FdFilestatGetName, uint64(tc.fd), uint64(tc.resultFilestat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
@@ -435,7 +435,7 @@ func Test_fdFilestatGet(t *testing.T) {
 
 // Test_fdFilestatSetSize only tests it is stubbed for GrainLang per #271
 func Test_fdFilestatSetSize(t *testing.T) {
-	log := requireErrnoNosys(t, fdFilestatSetSizeName, 0, 0)
+	log := requireErrnoNosys(t, FdFilestatSetSizeName, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_filestat_set_size(fd=0,size=0)
 <-- errno=ENOSYS
@@ -444,7 +444,7 @@ func Test_fdFilestatSetSize(t *testing.T) {
 
 // Test_fdFilestatSetTimes only tests it is stubbed for GrainLang per #271
 func Test_fdFilestatSetTimes(t *testing.T) {
-	log := requireErrnoNosys(t, fdFilestatSetTimesName, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, FdFilestatSetTimesName, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_filestat_set_times(fd=0,atim=0,mtim=0,fst_flags=0)
 <-- errno=ENOSYS
@@ -518,7 +518,7 @@ func Test_fdPread(t *testing.T) {
 			ok := mod.Memory().Write(0, initialMemory)
 			require.True(t, ok)
 
-			requireErrno(t, ErrnoSuccess, mod, fdPreadName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(tc.offset), uint64(resultNread))
+			requireErrno(t, ErrnoSuccess, mod, FdPreadName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(tc.offset), uint64(resultNread))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
@@ -646,7 +646,7 @@ func Test_fdPread_Errors(t *testing.T) {
 			memoryWriteOK := mod.Memory().Write(offset, tc.memory)
 			require.True(t, memoryWriteOK)
 
-			requireErrno(t, tc.expectedErrno, mod, fdPreadName, uint64(tc.fd), uint64(tc.iovs+offset), uint64(tc.iovsCount+offset), uint64(tc.offset), uint64(tc.resultNread+offset))
+			requireErrno(t, tc.expectedErrno, mod, FdPreadName, uint64(tc.fd), uint64(tc.iovs+offset), uint64(tc.iovsCount+offset), uint64(tc.offset), uint64(tc.resultNread+offset))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -655,7 +655,7 @@ func Test_fdPread_Errors(t *testing.T) {
 func Test_fdPrestatGet(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.MapFS{}))
 	defer r.Close(testCtx)
-	fd := internalsys.FdRoot // only pre-opened directory currently supported.
+	fd := sys.FdRoot // only pre-opened directory currently supported.
 
 	resultPrestat := uint32(1) // arbitrary offset
 	expectedMemory := []byte{
@@ -669,7 +669,7 @@ func Test_fdPrestatGet(t *testing.T) {
 
 	maskMemory(t, mod, len(expectedMemory))
 
-	requireErrno(t, ErrnoSuccess, mod, fdPrestatGetName, uint64(fd), uint64(resultPrestat))
+	requireErrno(t, ErrnoSuccess, mod, FdPrestatGetName, uint64(fd), uint64(resultPrestat))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_prestat_get(fd=3)
 <== (prestat={pr_name_len=1},errno=ESUCCESS)
@@ -683,7 +683,7 @@ func Test_fdPrestatGet(t *testing.T) {
 func Test_fdPrestatGet_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.MapFS{}))
 	defer r.Close(testCtx)
-	fd := internalsys.FdRoot // only pre-opened directory currently supported.
+	fd := sys.FdRoot // only pre-opened directory currently supported.
 
 	memorySize := mod.Memory().Size()
 	tests := []struct {
@@ -722,7 +722,7 @@ func Test_fdPrestatGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, tc.expectedErrno, mod, fdPrestatGetName, uint64(tc.fd), uint64(tc.resultPrestat))
+			requireErrno(t, tc.expectedErrno, mod, FdPrestatGetName, uint64(tc.fd), uint64(tc.resultPrestat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -731,7 +731,7 @@ func Test_fdPrestatGet_Errors(t *testing.T) {
 func Test_fdPrestatDirName(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.MapFS{}))
 	defer r.Close(testCtx)
-	fd := internalsys.FdRoot // only pre-opened directory currently supported.
+	fd := sys.FdRoot // only pre-opened directory currently supported.
 
 	path := uint32(1)    // arbitrary offset
 	pathLen := uint32(0) // shorter than len("/") to prove truncation is ok
@@ -741,7 +741,7 @@ func Test_fdPrestatDirName(t *testing.T) {
 
 	maskMemory(t, mod, len(expectedMemory))
 
-	requireErrno(t, ErrnoSuccess, mod, fdPrestatDirNameName, uint64(fd), uint64(path), uint64(pathLen))
+	requireErrno(t, ErrnoSuccess, mod, FdPrestatDirNameName, uint64(fd), uint64(path), uint64(pathLen))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_prestat_dir_name(fd=3)
 <== (path=,errno=ESUCCESS)
@@ -755,7 +755,7 @@ func Test_fdPrestatDirName(t *testing.T) {
 func Test_fdPrestatDirName_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.MapFS{}))
 	defer r.Close(testCtx)
-	fd := internalsys.FdRoot // only pre-opened directory currently supported.
+	fd := sys.FdRoot // only pre-opened directory currently supported.
 
 	memorySize := mod.Memory().Size()
 	maskMemory(t, mod, 10)
@@ -824,7 +824,7 @@ func Test_fdPrestatDirName_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, tc.expectedErrno, mod, fdPrestatDirNameName, uint64(tc.fd), uint64(tc.path), uint64(tc.pathLen))
+			requireErrno(t, tc.expectedErrno, mod, FdPrestatDirNameName, uint64(tc.fd), uint64(tc.path), uint64(tc.pathLen))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -832,7 +832,7 @@ func Test_fdPrestatDirName_Errors(t *testing.T) {
 
 // Test_fdPwrite only tests it is stubbed for GrainLang per #271
 func Test_fdPwrite(t *testing.T) {
-	log := requireErrnoNosys(t, fdPwriteName, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, FdPwriteName, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_pwrite(fd=0,iovs=0,iovs_len=0,offset=0)
 <-- (nwritten=,errno=ENOSYS)
@@ -869,7 +869,7 @@ func Test_fdRead(t *testing.T) {
 	ok := mod.Memory().Write(0, initialMemory)
 	require.True(t, ok)
 
-	requireErrno(t, ErrnoSuccess, mod, fdReadName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNread))
+	requireErrno(t, ErrnoSuccess, mod, FdReadName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNread))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_read(fd=4,iovs=1,iovs_len=2)
 <== (nread=6,errno=ESUCCESS)
@@ -986,97 +986,12 @@ func Test_fdRead_Errors(t *testing.T) {
 			memoryWriteOK := mod.Memory().Write(offset, tc.memory)
 			require.True(t, memoryWriteOK)
 
-			requireErrno(t, tc.expectedErrno, mod, fdReadName, uint64(tc.fd), uint64(tc.iovs+offset), uint64(tc.iovsCount+offset), uint64(tc.resultNread+offset))
+			requireErrno(t, tc.expectedErrno, mod, FdReadName, uint64(tc.fd), uint64(tc.iovs+offset), uint64(tc.iovsCount+offset), uint64(tc.resultNread+offset))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
 }
 
-func Test_fdRead_shouldContinueRead(t *testing.T) {
-	tests := []struct {
-		name          string
-		n, l          uint32
-		err           error
-		expectedOk    bool
-		expectedErrno Errno
-	}{
-		{
-			name: "break when nothing to read",
-			n:    0,
-			l:    0,
-		},
-		{
-			name: "break when nothing read",
-			n:    0,
-			l:    4,
-		},
-		{
-			name: "break on partial read",
-			n:    3,
-			l:    4,
-		},
-		{
-			name:       "continue on full read",
-			n:          4,
-			l:          4,
-			expectedOk: true,
-		},
-		{
-			name: "break on EOF on nothing to read",
-			err:  io.EOF,
-		},
-		{
-			name: "break on EOF on nothing read",
-			l:    4,
-			err:  io.EOF,
-		},
-		{
-			name: "break on EOF on partial read",
-			n:    3,
-			l:    4,
-			err:  io.EOF,
-		},
-		{
-			name: "break on EOF on full read",
-			n:    4,
-			l:    4,
-			err:  io.EOF,
-		},
-		{
-			name:          "return ErrnoIo on error on nothing to read",
-			err:           io.ErrClosedPipe,
-			expectedErrno: ErrnoIo,
-		},
-		{
-			name:          "return ErrnoIo on error on nothing read",
-			l:             4,
-			err:           io.ErrClosedPipe,
-			expectedErrno: ErrnoIo,
-		},
-		{ // Special case, allows processing data before err
-			name: "break on error on partial read",
-			n:    3,
-			l:    4,
-			err:  io.ErrClosedPipe,
-		},
-		{ // Special case, allows processing data before err
-			name: "break on error on full read",
-			n:    4,
-			l:    4,
-			err:  io.ErrClosedPipe,
-		},
-	}
-	for _, tt := range tests {
-		tc := tt
-
-		t.Run(tc.name, func(t *testing.T) {
-			ok, errno := fdRead_shouldContinueRead(tc.n, tc.l, tc.err)
-			require.Equal(t, tc.expectedOk, ok)
-			require.Equal(t, tc.expectedErrno, errno)
-		})
-	}
-}
-
 var (
 	fdReadDirFs = fstest.MapFS{
 		"notdir":   {},
@@ -1129,90 +1044,90 @@ func Test_fdReaddir(t *testing.T) {
 
 	tests := []struct {
 		name            string
-		dir             func() *internalsys.FileEntry
+		dir             func() *sys.FileEntry
 		bufLen          uint32
 		cookie          int64
 		expectedMem     []byte
 		expectedMemSize int
 		expectedBufused uint32
-		expectedReadDir *internalsys.ReadDir
+		expectedReadDir *sys.ReadDir
 	}{
 		{
 			name: "empty dir",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("emptydir")
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{File: dir}
+				return &sys.FileEntry{File: dir}
 			},
-			bufLen:          direntSize,
+			bufLen:          DirentSize,
 			cookie:          0,
 			expectedBufused: 0,
 			expectedMem:     []byte{},
-			expectedReadDir: &internalsys.ReadDir{},
+			expectedReadDir: &sys.ReadDir{},
 		},
 		{
 			name: "full read",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{File: dir}
+				return &sys.FileEntry{File: dir}
 			},
 			bufLen:          4096,
 			cookie:          0,
 			expectedBufused: 78, // length of all entries
 			expectedMem:     append(append(dirent1, dirent2...), dirent3...),
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries,
 			},
 		},
 		{
 			name: "can't read name",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{File: dir}
+				return &sys.FileEntry{File: dir}
 			},
 			bufLen:          24, // length is long enough for first, but not the name.
 			cookie:          0,
 			expectedBufused: 24,           // == bufLen which is the size of the dirent
 			expectedMem:     dirent1[:24], // header without name
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries,
 			},
 		},
 		{
 			name: "read exactly first",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{File: dir}
+				return &sys.FileEntry{File: dir}
 			},
 			bufLen:          25, // length is long enough for first + the name, but not more.
 			cookie:          0,
 			expectedBufused: 25, // length to read exactly first.
 			expectedMem:     dirent1,
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries,
 			},
 		},
 		{
 			name: "read exactly second",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 				entry, err := dir.(fs.ReadDirFile).ReadDir(1)
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{
+				return &sys.FileEntry{
 					File: dir,
-					ReadDir: &internalsys.ReadDir{
+					ReadDir: &sys.ReadDir{
 						CountRead: 1,
 						Entries:   entry,
 					},
@@ -1222,22 +1137,22 @@ func Test_fdReaddir(t *testing.T) {
 			cookie:          1,  // d_next of first
 			expectedBufused: 26, // length to read exactly second.
 			expectedMem:     dirent2,
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries[1:],
 			},
 		},
 		{
 			name: "read second and a little more",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 				entry, err := dir.(fs.ReadDirFile).ReadDir(1)
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{
+				return &sys.FileEntry{
 					File: dir,
-					ReadDir: &internalsys.ReadDir{
+					ReadDir: &sys.ReadDir{
 						CountRead: 1,
 						Entries:   entry,
 					},
@@ -1248,22 +1163,22 @@ func Test_fdReaddir(t *testing.T) {
 			expectedBufused: 30, // length to read some more, but not enough for a header, so buf was exhausted.
 			expectedMem:     dirent2,
 			expectedMemSize: len(dirent2), // we do not want to compare the full buffer since we don't know what the leftover 4 bytes will contain.
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries[1:],
 			},
 		},
 		{
 			name: "read second and header of third",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 				entry, err := dir.(fs.ReadDirFile).ReadDir(1)
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{
+				return &sys.FileEntry{
 					File: dir,
-					ReadDir: &internalsys.ReadDir{
+					ReadDir: &sys.ReadDir{
 						CountRead: 1,
 						Entries:   entry,
 					},
@@ -1273,22 +1188,22 @@ func Test_fdReaddir(t *testing.T) {
 			cookie:          1,  // d_next of first
 			expectedBufused: 50, // length to read exactly second and the header of third.
 			expectedMem:     append(dirent2, dirent3[0:24]...),
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries[1:],
 			},
 		},
 		{
 			name: "read second and third",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 				entry, err := dir.(fs.ReadDirFile).ReadDir(1)
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{
+				return &sys.FileEntry{
 					File: dir,
-					ReadDir: &internalsys.ReadDir{
+					ReadDir: &sys.ReadDir{
 						CountRead: 1,
 						Entries:   entry,
 					},
@@ -1298,22 +1213,22 @@ func Test_fdReaddir(t *testing.T) {
 			cookie:          1,  // d_next of first
 			expectedBufused: 53, // length to read exactly one second and third.
 			expectedMem:     append(dirent2, dirent3...),
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries[1:],
 			},
 		},
 		{
 			name: "read exactly third",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 				two, err := dir.(fs.ReadDirFile).ReadDir(2)
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{
+				return &sys.FileEntry{
 					File: dir,
-					ReadDir: &internalsys.ReadDir{
+					ReadDir: &sys.ReadDir{
 						CountRead: 2,
 						Entries:   two[1:],
 					},
@@ -1323,22 +1238,22 @@ func Test_fdReaddir(t *testing.T) {
 			cookie:          2,  // d_next of second.
 			expectedBufused: 27, // length to read exactly third.
 			expectedMem:     dirent3,
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries[2:],
 			},
 		},
 		{
 			name: "read third and beyond",
-			dir: func() *internalsys.FileEntry {
+			dir: func() *sys.FileEntry {
 				dir, err := fdReadDirFs.Open("dir")
 				require.NoError(t, err)
 				two, err := dir.(fs.ReadDirFile).ReadDir(2)
 				require.NoError(t, err)
 
-				return &internalsys.FileEntry{
+				return &sys.FileEntry{
 					File: dir,
-					ReadDir: &internalsys.ReadDir{
+					ReadDir: &sys.ReadDir{
 						CountRead: 2,
 						Entries:   two[1:],
 					},
@@ -1348,7 +1263,7 @@ func Test_fdReaddir(t *testing.T) {
 			cookie:          2,   // d_next of second.
 			expectedBufused: 27,  // length to read exactly third.
 			expectedMem:     dirent3,
-			expectedReadDir: &internalsys.ReadDir{
+			expectedReadDir: &sys.ReadDir{
 				CountRead: 3,
 				Entries:   testDirEntries[2:],
 			},
@@ -1373,7 +1288,7 @@ func Test_fdReaddir(t *testing.T) {
 
 			resultBufused := uint32(0) // where to write the amount used out of bufLen
 			buf := uint32(8)           // where to start the dirents
-			requireErrno(t, ErrnoSuccess, mod, fdReaddirName,
+			requireErrno(t, ErrnoSuccess, mod, FdReaddirName,
 				uint64(fd), uint64(buf), uint64(tc.bufLen), uint64(tc.cookie), uint64(resultBufused))
 
 			// read back the bufused and compare memory against it
@@ -1411,10 +1326,10 @@ func Test_fdReaddir_Errors(t *testing.T) {
 
 	tests := []struct {
 		name                           string
-		dir                            func() *internalsys.FileEntry
+		dir                            func() *sys.FileEntry
 		fd, buf, bufLen, resultBufused uint32
 		cookie                         int64
-		readDir                        *internalsys.ReadDir
+		readDir                        *sys.ReadDir
 		expectedErrno                  Errno
 		expectedLog                    string
 	}{
@@ -1432,7 +1347,7 @@ func Test_fdReaddir_Errors(t *testing.T) {
 		{
 			name: "invalid fd",
 			fd:   42,                    // arbitrary invalid fd
-			buf:  0, bufLen: direntSize, // enough to read the dirent
+			buf:  0, bufLen: DirentSize, // enough to read the dirent
 			resultBufused: 1000, // arbitrary
 			expectedErrno: ErrnoBadf,
 			expectedLog: `
@@ -1443,7 +1358,7 @@ func Test_fdReaddir_Errors(t *testing.T) {
 		{
 			name: "not a dir",
 			fd:   fileFD,
-			buf:  0, bufLen: direntSize, // enough to read the dirent
+			buf:  0, bufLen: DirentSize, // enough to read the dirent
 			resultBufused: 1000, // arbitrary
 			expectedErrno: ErrnoBadf,
 			expectedLog: `
@@ -1513,7 +1428,7 @@ func Test_fdReaddir_Errors(t *testing.T) {
 			fd:   dirFD,
 			buf:  0, bufLen: 1000,
 			cookie:        -1,
-			readDir:       &internalsys.ReadDir{CountRead: 1},
+			readDir:       &sys.ReadDir{CountRead: 1},
 			resultBufused: 2000,
 			expectedErrno: ErrnoInval,
 			expectedLog: `
@@ -1538,239 +1453,16 @@ func Test_fdReaddir_Errors(t *testing.T) {
 				file.ReadDir = nil
 			}
 
-			requireErrno(t, tc.expectedErrno, mod, fdReaddirName,
+			requireErrno(t, tc.expectedErrno, mod, FdReaddirName,
 				uint64(tc.fd), uint64(tc.buf), uint64(tc.bufLen), uint64(tc.cookie), uint64(tc.resultBufused))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
 }
 
-func Test_lastDirEntries(t *testing.T) {
-	tests := []struct {
-		name            string
-		f               *internalsys.ReadDir
-		cookie          int64
-		expectedEntries []fs.DirEntry
-		expectedErrno   Errno
-	}{
-		{
-			name: "no prior call",
-		},
-		{
-			name:          "no prior call, but passed a cookie",
-			cookie:        1,
-			expectedErrno: ErrnoInval,
-		},
-		{
-			name: "cookie is negative",
-			f: &internalsys.ReadDir{
-				CountRead: 3,
-				Entries:   testDirEntries,
-			},
-			cookie:        -1,
-			expectedErrno: ErrnoInval,
-		},
-		{
-			name: "cookie is greater than last d_next",
-			f: &internalsys.ReadDir{
-				CountRead: 3,
-				Entries:   testDirEntries,
-			},
-			cookie:        5,
-			expectedErrno: ErrnoInval,
-		},
-		{
-			name: "cookie is last pos",
-			f: &internalsys.ReadDir{
-				CountRead: 3,
-				Entries:   testDirEntries,
-			},
-			cookie:          3,
-			expectedEntries: nil,
-		},
-		{
-			name: "cookie is one before last pos",
-			f: &internalsys.ReadDir{
-				CountRead: 3,
-				Entries:   testDirEntries,
-			},
-			cookie:          2,
-			expectedEntries: testDirEntries[2:],
-		},
-		{
-			name: "cookie is before current entries",
-			f: &internalsys.ReadDir{
-				CountRead: 5,
-				Entries:   testDirEntries,
-			},
-			cookie:        1,
-			expectedErrno: ErrnoNosys, // not implemented
-		},
-	}
-
-	for _, tt := range tests {
-		tc := tt
-
-		t.Run(tc.name, func(t *testing.T) {
-			f := tc.f
-			if f == nil {
-				f = &internalsys.ReadDir{}
-			}
-			entries, errno := lastDirEntries(f, tc.cookie)
-			require.Equal(t, tc.expectedErrno, errno)
-			require.Equal(t, tc.expectedEntries, entries)
-		})
-	}
-}
-
-func Test_maxDirents(t *testing.T) {
-	tests := []struct {
-		name                        string
-		entries                     []fs.DirEntry
-		maxLen                      uint32
-		expectedCount               uint32
-		expectedwriteTruncatedEntry bool
-		expectedBufused             uint32
-	}{
-		{
-			name: "no entries",
-		},
-		{
-			name:                        "can't fit one",
-			entries:                     testDirEntries,
-			maxLen:                      23,
-			expectedBufused:             23,
-			expectedwriteTruncatedEntry: false,
-		},
-		{
-			name:                        "only fits header",
-			entries:                     testDirEntries,
-			maxLen:                      24,
-			expectedBufused:             24,
-			expectedwriteTruncatedEntry: true,
-		},
-		{
-			name:            "one",
-			entries:         testDirEntries,
-			maxLen:          25,
-			expectedCount:   1,
-			expectedBufused: 25,
-		},
-		{
-			name:                        "one but not room for two's name",
-			entries:                     testDirEntries,
-			maxLen:                      25 + 25,
-			expectedCount:               1,
-			expectedwriteTruncatedEntry: true, // can write direntSize
-			expectedBufused:             25 + 25,
-		},
-		{
-			name:            "two",
-			entries:         testDirEntries,
-			maxLen:          25 + 26,
-			expectedCount:   2,
-			expectedBufused: 25 + 26,
-		},
-		{
-			name:                        "two but not three's dirent",
-			entries:                     testDirEntries,
-			maxLen:                      25 + 26 + 20,
-			expectedCount:               2,
-			expectedwriteTruncatedEntry: false, // 20 + 4 == direntSize
-			expectedBufused:             25 + 26 + 20,
-		},
-		{
-			name:                        "two but not three's name",
-			entries:                     testDirEntries,
-			maxLen:                      25 + 26 + 26,
-			expectedCount:               2,
-			expectedwriteTruncatedEntry: true, // can write direntSize
-			expectedBufused:             25 + 26 + 26,
-		},
-		{
-			name:                        "three",
-			entries:                     testDirEntries,
-			maxLen:                      25 + 26 + 27,
-			expectedCount:               3,
-			expectedwriteTruncatedEntry: false, // end of dir
-			expectedBufused:             25 + 26 + 27,
-		},
-		{
-			name:                        "max",
-			entries:                     testDirEntries,
-			maxLen:                      100,
-			expectedCount:               3,
-			expectedwriteTruncatedEntry: false, // end of dir
-			expectedBufused:             25 + 26 + 27,
-		},
-	}
-
-	for _, tt := range tests {
-		tc := tt
-
-		t.Run(tc.name, func(t *testing.T) {
-			bufused, direntCount, writeTruncatedEntry := maxDirents(tc.entries, tc.maxLen)
-			require.Equal(t, tc.expectedCount, direntCount)
-			require.Equal(t, tc.expectedwriteTruncatedEntry, writeTruncatedEntry)
-			require.Equal(t, tc.expectedBufused, bufused)
-		})
-	}
-}
-
-func Test_writeDirents(t *testing.T) {
-	tests := []struct {
-		name                string
-		entries             []fs.DirEntry
-		entryCount          uint32
-		writeTruncatedEntry bool
-		expectedEntriesBuf  []byte
-	}{
-		{
-			name:    "none",
-			entries: testDirEntries,
-		},
-		{
-			name:               "one",
-			entries:            testDirEntries,
-			entryCount:         1,
-			expectedEntriesBuf: dirent1,
-		},
-		{
-			name:               "two",
-			entries:            testDirEntries,
-			entryCount:         2,
-			expectedEntriesBuf: append(dirent1, dirent2...),
-		},
-		{
-			name:                "two with truncated",
-			entries:             testDirEntries,
-			entryCount:          2,
-			writeTruncatedEntry: true,
-			expectedEntriesBuf:  append(append(dirent1, dirent2...), dirent3[0:10]...),
-		},
-		{
-			name:               "three",
-			entries:            testDirEntries,
-			entryCount:         3,
-			expectedEntriesBuf: append(append(dirent1, dirent2...), dirent3...),
-		},
-	}
-
-	for _, tt := range tests {
-		tc := tt
-
-		t.Run(tc.name, func(t *testing.T) {
-			cookie := uint64(1)
-			entriesBuf := make([]byte, len(tc.expectedEntriesBuf))
-			writeDirents(tc.entries, tc.entryCount, tc.writeTruncatedEntry, entriesBuf, cookie)
-			require.Equal(t, tc.expectedEntriesBuf, entriesBuf)
-		})
-	}
-}
-
 // Test_fdRenumber only tests it is stubbed for GrainLang per #271
 func Test_fdRenumber(t *testing.T) {
-	log := requireErrnoNosys(t, fdRenumberName, 0, 0)
+	log := requireErrnoNosys(t, FdRenumberName, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_renumber(fd=0,to=0)
 <-- errno=ENOSYS
@@ -1856,7 +1548,7 @@ func Test_fdSeek(t *testing.T) {
 			require.NoError(t, err)
 			require.Equal(t, int64(1), offset)
 
-			requireErrno(t, ErrnoSuccess, mod, fdSeekName, uint64(fd), uint64(tc.offset), uint64(tc.whence), uint64(resultNewoffset))
+			requireErrno(t, ErrnoSuccess, mod, FdSeekName, uint64(fd), uint64(tc.offset), uint64(tc.whence), uint64(resultNewoffset))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
@@ -1920,7 +1612,7 @@ func Test_fdSeek_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, tc.expectedErrno, mod, fdSeekName, uint64(tc.fd), tc.offset, uint64(tc.whence), uint64(tc.resultNewoffset))
+			requireErrno(t, tc.expectedErrno, mod, FdSeekName, uint64(tc.fd), tc.offset, uint64(tc.whence), uint64(tc.resultNewoffset))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -1928,7 +1620,7 @@ func Test_fdSeek_Errors(t *testing.T) {
 
 // Test_fdSync only tests it is stubbed for GrainLang per #271
 func Test_fdSync(t *testing.T) {
-	log := requireErrnoNosys(t, fdSyncName, 0)
+	log := requireErrnoNosys(t, FdSyncName, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_sync(fd=0)
 <-- errno=ENOSYS
@@ -1937,7 +1629,7 @@ func Test_fdSync(t *testing.T) {
 
 // Test_fdTell only tests it is stubbed for GrainLang per #271
 func Test_fdTell(t *testing.T) {
-	log := requireErrnoNosys(t, fdTellName, 0, 0)
+	log := requireErrnoNosys(t, FdTellName, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.fd_tell(fd=0,result.offset=0)
 <-- errno=ENOSYS
@@ -1975,7 +1667,7 @@ func Test_fdWrite(t *testing.T) {
 	ok := mod.Memory().Write(0, initialMemory)
 	require.True(t, ok)
 
-	requireErrno(t, ErrnoSuccess, mod, fdWriteName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNwritten))
+	requireErrno(t, ErrnoSuccess, mod, FdWriteName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNwritten))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_write(fd=4,iovs=1,iovs_len=2)
 <== (nwritten=6,errno=ESUCCESS)
@@ -2026,7 +1718,7 @@ func Test_fdWrite_discard(t *testing.T) {
 	require.True(t, ok)
 
 	fd := 1 // stdout
-	requireErrno(t, ErrnoSuccess, mod, fdWriteName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNwritten))
+	requireErrno(t, ErrnoSuccess, mod, FdWriteName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNwritten))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.fd_write(fd=1,iovs=1,iovs_len=2)
 <== (nwritten=6,errno=ESUCCESS)
@@ -2126,7 +1818,7 @@ func Test_fdWrite_Errors(t *testing.T) {
 				'h', 'i', // iovs[0].length bytes
 			))
 
-			requireErrno(t, tc.expectedErrno, mod, fdWriteName, uint64(tc.fd), uint64(tc.iovs), uint64(iovsCount),
+			requireErrno(t, tc.expectedErrno, mod, FdWriteName, uint64(tc.fd), uint64(tc.iovs), uint64(iovsCount),
 				uint64(tc.resultNwritten))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
@@ -2135,7 +1827,7 @@ func Test_fdWrite_Errors(t *testing.T) {
 
 // Test_pathCreateDirectory only tests it is stubbed for GrainLang per #271
 func Test_pathCreateDirectory(t *testing.T) {
-	log := requireErrnoNosys(t, pathCreateDirectoryName, 0, 0, 0)
+	log := requireErrnoNosys(t, PathCreateDirectoryName, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_create_directory(fd=0,path=)
 <-- errno=ENOSYS
@@ -2334,7 +2026,7 @@ func Test_pathFilestatGet(t *testing.T) {
 			mod.Memory().Write(0, tc.memory)
 
 			flags := uint32(0)
-			requireErrno(t, tc.expectedErrno, mod, pathFilestatGetName, uint64(tc.fd), uint64(flags), uint64(1), uint64(tc.pathLen), uint64(tc.resultFilestat))
+			requireErrno(t, tc.expectedErrno, mod, PathFilestatGetName, uint64(tc.fd), uint64(flags), uint64(1), uint64(tc.pathLen), uint64(tc.resultFilestat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
 			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
@@ -2346,7 +2038,7 @@ func Test_pathFilestatGet(t *testing.T) {
 
 // Test_pathFilestatSetTimes only tests it is stubbed for GrainLang per #271
 func Test_pathFilestatSetTimes(t *testing.T) {
-	log := requireErrnoNosys(t, pathFilestatSetTimesName, 0, 0, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, PathFilestatSetTimesName, 0, 0, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_filestat_set_times(fd=0,flags=,path=,atim=0,mtim=0,fst_flags=0)
 <-- errno=ENOSYS
@@ -2355,7 +2047,7 @@ func Test_pathFilestatSetTimes(t *testing.T) {
 
 // Test_pathLink only tests it is stubbed for GrainLang per #271
 func Test_pathLink(t *testing.T) {
-	log := requireErrnoNosys(t, pathLinkName, 0, 0, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, PathLinkName, 0, 0, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_link(old_fd=0,old_flags=,old_path=,new_fd=0,new_path=)
 <-- errno=ENOSYS
@@ -2393,7 +2085,7 @@ func Test_pathOpen(t *testing.T) {
 	ok := mod.Memory().Write(0, initialMemory)
 	require.True(t, ok)
 
-	requireErrno(t, ErrnoSuccess, mod, pathOpenName, uint64(rootFD), uint64(dirflags), uint64(path),
+	requireErrno(t, ErrnoSuccess, mod, PathOpenName, uint64(rootFD), uint64(dirflags), uint64(path),
 		uint64(pathLen), uint64(oflags), fsRightsBase, fsRightsInheriting, uint64(fdflags), uint64(resultOpenedFd))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.path_open(fd=3,dirflags=,path=wazero,oflags=,fs_rights_base=FD_DATASYNC,fs_rights_inheriting=FD_READ,fdflags=)
@@ -2501,7 +2193,7 @@ func Test_pathOpen_Errors(t *testing.T) {
 		},
 		{
 			name:          "oflags=directory, but not a directory",
-			oflags:        uint32(wasi_snapshot_preview1.O_DIRECTORY),
+			oflags:        uint32(O_DIRECTORY),
 			fd:            validFD,
 			pathName:      fileName,
 			path:          validPath,
@@ -2521,7 +2213,7 @@ func Test_pathOpen_Errors(t *testing.T) {
 
 			mod.Memory().Write(validPath, []byte(tc.pathName))
 
-			requireErrno(t, tc.expectedErrno, mod, pathOpenName, uint64(tc.fd), uint64(0), uint64(tc.path),
+			requireErrno(t, tc.expectedErrno, mod, PathOpenName, uint64(tc.fd), uint64(0), uint64(tc.path),
 				uint64(tc.pathLen), uint64(tc.oflags), 0, 0, 0, uint64(tc.resultOpenedFd))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
@@ -2530,7 +2222,7 @@ func Test_pathOpen_Errors(t *testing.T) {
 
 // Test_pathReadlink only tests it is stubbed for GrainLang per #271
 func Test_pathReadlink(t *testing.T) {
-	log := requireErrnoNosys(t, pathReadlinkName, 0, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, PathReadlinkName, 0, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_readlink(fd=0,path=,buf=0,buf_len=0,result.bufused=0)
 <-- errno=ENOSYS
@@ -2539,7 +2231,7 @@ func Test_pathReadlink(t *testing.T) {
 
 // Test_pathRemoveDirectory only tests it is stubbed for GrainLang per #271
 func Test_pathRemoveDirectory(t *testing.T) {
-	log := requireErrnoNosys(t, pathRemoveDirectoryName, 0, 0, 0)
+	log := requireErrnoNosys(t, PathRemoveDirectoryName, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_remove_directory(fd=0,path=)
 <-- errno=ENOSYS
@@ -2548,7 +2240,7 @@ func Test_pathRemoveDirectory(t *testing.T) {
 
 // Test_pathRename only tests it is stubbed for GrainLang per #271
 func Test_pathRename(t *testing.T) {
-	log := requireErrnoNosys(t, pathRenameName, 0, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, PathRenameName, 0, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_rename(fd=0,old_path=,new_fd=0,new_path=)
 <-- errno=ENOSYS
@@ -2557,7 +2249,7 @@ func Test_pathRename(t *testing.T) {
 
 // Test_pathSymlink only tests it is stubbed for GrainLang per #271
 func Test_pathSymlink(t *testing.T) {
-	log := requireErrnoNosys(t, pathSymlinkName, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, PathSymlinkName, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_symlink(old_path=,fd=0,new_path=)
 <-- errno=ENOSYS
@@ -2566,7 +2258,7 @@ func Test_pathSymlink(t *testing.T) {
 
 // Test_pathUnlinkFile only tests it is stubbed for GrainLang per #271
 func Test_pathUnlinkFile(t *testing.T) {
-	log := requireErrnoNosys(t, pathUnlinkFileName, 0, 0, 0)
+	log := requireErrnoNosys(t, PathUnlinkFileName, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.path_unlink_file(fd=0,path=)
 <-- errno=ENOSYS
diff --git a/imports/wasi_snapshot_preview1/fs_unit_test.go b/imports/wasi_snapshot_preview1/fs_unit_test.go
new file mode 100644
index 00000000..3515106f
--- /dev/null
+++ b/imports/wasi_snapshot_preview1/fs_unit_test.go
@@ -0,0 +1,361 @@
+package wasi_snapshot_preview1
+
+import (
+	"io"
+	"io/fs"
+	"testing"
+	"testing/fstest"
+
+	"github.com/tetratelabs/wazero/internal/sys"
+	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+)
+
+func Test_fdRead_shouldContinueRead(t *testing.T) {
+	tests := []struct {
+		name          string
+		n, l          uint32
+		err           error
+		expectedOk    bool
+		expectedErrno Errno
+	}{
+		{
+			name: "break when nothing to read",
+			n:    0,
+			l:    0,
+		},
+		{
+			name: "break when nothing read",
+			n:    0,
+			l:    4,
+		},
+		{
+			name: "break on partial read",
+			n:    3,
+			l:    4,
+		},
+		{
+			name:       "continue on full read",
+			n:          4,
+			l:          4,
+			expectedOk: true,
+		},
+		{
+			name: "break on EOF on nothing to read",
+			err:  io.EOF,
+		},
+		{
+			name: "break on EOF on nothing read",
+			l:    4,
+			err:  io.EOF,
+		},
+		{
+			name: "break on EOF on partial read",
+			n:    3,
+			l:    4,
+			err:  io.EOF,
+		},
+		{
+			name: "break on EOF on full read",
+			n:    4,
+			l:    4,
+			err:  io.EOF,
+		},
+		{
+			name:          "return ErrnoIo on error on nothing to read",
+			err:           io.ErrClosedPipe,
+			expectedErrno: ErrnoIo,
+		},
+		{
+			name:          "return ErrnoIo on error on nothing read",
+			l:             4,
+			err:           io.ErrClosedPipe,
+			expectedErrno: ErrnoIo,
+		},
+		{ // Special case, allows processing data before err
+			name: "break on error on partial read",
+			n:    3,
+			l:    4,
+			err:  io.ErrClosedPipe,
+		},
+		{ // Special case, allows processing data before err
+			name: "break on error on full read",
+			n:    4,
+			l:    4,
+			err:  io.ErrClosedPipe,
+		},
+	}
+	for _, tt := range tests {
+		tc := tt
+
+		t.Run(tc.name, func(t *testing.T) {
+			ok, errno := fdRead_shouldContinueRead(tc.n, tc.l, tc.err)
+			require.Equal(t, tc.expectedOk, ok)
+			require.Equal(t, tc.expectedErrno, errno)
+		})
+	}
+}
+
+func Test_lastDirEntries(t *testing.T) {
+	tests := []struct {
+		name            string
+		f               *sys.ReadDir
+		cookie          int64
+		expectedEntries []fs.DirEntry
+		expectedErrno   Errno
+	}{
+		{
+			name: "no prior call",
+		},
+		{
+			name:          "no prior call, but passed a cookie",
+			cookie:        1,
+			expectedErrno: ErrnoInval,
+		},
+		{
+			name: "cookie is negative",
+			f: &sys.ReadDir{
+				CountRead: 3,
+				Entries:   testDirEntries,
+			},
+			cookie:        -1,
+			expectedErrno: ErrnoInval,
+		},
+		{
+			name: "cookie is greater than last d_next",
+			f: &sys.ReadDir{
+				CountRead: 3,
+				Entries:   testDirEntries,
+			},
+			cookie:        5,
+			expectedErrno: ErrnoInval,
+		},
+		{
+			name: "cookie is last pos",
+			f: &sys.ReadDir{
+				CountRead: 3,
+				Entries:   testDirEntries,
+			},
+			cookie:          3,
+			expectedEntries: nil,
+		},
+		{
+			name: "cookie is one before last pos",
+			f: &sys.ReadDir{
+				CountRead: 3,
+				Entries:   testDirEntries,
+			},
+			cookie:          2,
+			expectedEntries: testDirEntries[2:],
+		},
+		{
+			name: "cookie is before current entries",
+			f: &sys.ReadDir{
+				CountRead: 5,
+				Entries:   testDirEntries,
+			},
+			cookie:        1,
+			expectedErrno: ErrnoNosys, // not implemented
+		},
+	}
+
+	for _, tt := range tests {
+		tc := tt
+
+		t.Run(tc.name, func(t *testing.T) {
+			f := tc.f
+			if f == nil {
+				f = &sys.ReadDir{}
+			}
+			entries, errno := lastDirEntries(f, tc.cookie)
+			require.Equal(t, tc.expectedErrno, errno)
+			require.Equal(t, tc.expectedEntries, entries)
+		})
+	}
+}
+
+func Test_maxDirents(t *testing.T) {
+	tests := []struct {
+		name                        string
+		entries                     []fs.DirEntry
+		maxLen                      uint32
+		expectedCount               uint32
+		expectedwriteTruncatedEntry bool
+		expectedBufused             uint32
+	}{
+		{
+			name: "no entries",
+		},
+		{
+			name:                        "can't fit one",
+			entries:                     testDirEntries,
+			maxLen:                      23,
+			expectedBufused:             23,
+			expectedwriteTruncatedEntry: false,
+		},
+		{
+			name:                        "only fits header",
+			entries:                     testDirEntries,
+			maxLen:                      24,
+			expectedBufused:             24,
+			expectedwriteTruncatedEntry: true,
+		},
+		{
+			name:            "one",
+			entries:         testDirEntries,
+			maxLen:          25,
+			expectedCount:   1,
+			expectedBufused: 25,
+		},
+		{
+			name:                        "one but not room for two's name",
+			entries:                     testDirEntries,
+			maxLen:                      25 + 25,
+			expectedCount:               1,
+			expectedwriteTruncatedEntry: true, // can write DirentSize
+			expectedBufused:             25 + 25,
+		},
+		{
+			name:            "two",
+			entries:         testDirEntries,
+			maxLen:          25 + 26,
+			expectedCount:   2,
+			expectedBufused: 25 + 26,
+		},
+		{
+			name:                        "two but not three's dirent",
+			entries:                     testDirEntries,
+			maxLen:                      25 + 26 + 20,
+			expectedCount:               2,
+			expectedwriteTruncatedEntry: false, // 20 + 4 == DirentSize
+			expectedBufused:             25 + 26 + 20,
+		},
+		{
+			name:                        "two but not three's name",
+			entries:                     testDirEntries,
+			maxLen:                      25 + 26 + 26,
+			expectedCount:               2,
+			expectedwriteTruncatedEntry: true, // can write DirentSize
+			expectedBufused:             25 + 26 + 26,
+		},
+		{
+			name:                        "three",
+			entries:                     testDirEntries,
+			maxLen:                      25 + 26 + 27,
+			expectedCount:               3,
+			expectedwriteTruncatedEntry: false, // end of dir
+			expectedBufused:             25 + 26 + 27,
+		},
+		{
+			name:                        "max",
+			entries:                     testDirEntries,
+			maxLen:                      100,
+			expectedCount:               3,
+			expectedwriteTruncatedEntry: false, // end of dir
+			expectedBufused:             25 + 26 + 27,
+		},
+	}
+
+	for _, tt := range tests {
+		tc := tt
+
+		t.Run(tc.name, func(t *testing.T) {
+			bufused, direntCount, writeTruncatedEntry := maxDirents(tc.entries, tc.maxLen)
+			require.Equal(t, tc.expectedCount, direntCount)
+			require.Equal(t, tc.expectedwriteTruncatedEntry, writeTruncatedEntry)
+			require.Equal(t, tc.expectedBufused, bufused)
+		})
+	}
+}
+
+var (
+	fdReadDirFs = fstest.MapFS{
+		"notdir":   {},
+		"emptydir": {Mode: fs.ModeDir},
+		"dir":      {Mode: fs.ModeDir},
+		"dir/-":    {},                 // len = 24+1 = 25
+		"dir/a-":   {Mode: fs.ModeDir}, // len = 24+2 = 26
+		"dir/ab-":  {},                 // len = 24+3 = 27
+	}
+
+	testDirEntries = func() []fs.DirEntry {
+		entries, err := fdReadDirFs.ReadDir("dir")
+		if err != nil {
+			panic(err)
+		}
+		return entries
+	}()
+
+	dirent1 = []byte{
+		1, 0, 0, 0, 0, 0, 0, 0, // d_next = 1
+		0, 0, 0, 0, 0, 0, 0, 0, // d_ino = 0
+		1, 0, 0, 0, // d_namlen = 1 character
+		4, 0, 0, 0, // d_type = regular_file
+		'-', // name
+	}
+	dirent2 = []byte{
+		2, 0, 0, 0, 0, 0, 0, 0, // d_next = 2
+		0, 0, 0, 0, 0, 0, 0, 0, // d_ino = 0
+		2, 0, 0, 0, // d_namlen = 1 character
+		3, 0, 0, 0, // d_type =  directory
+		'a', '-', // name
+	}
+	dirent3 = []byte{
+		3, 0, 0, 0, 0, 0, 0, 0, // d_next = 3
+		0, 0, 0, 0, 0, 0, 0, 0, // d_ino = 0
+		3, 0, 0, 0, // d_namlen = 3 characters
+		4, 0, 0, 0, // d_type = regular_file
+		'a', 'b', '-', // name
+	}
+)
+
+func Test_writeDirents(t *testing.T) {
+	tests := []struct {
+		name                string
+		entries             []fs.DirEntry
+		entryCount          uint32
+		writeTruncatedEntry bool
+		expectedEntriesBuf  []byte
+	}{
+		{
+			name:    "none",
+			entries: testDirEntries,
+		},
+		{
+			name:               "one",
+			entries:            testDirEntries,
+			entryCount:         1,
+			expectedEntriesBuf: dirent1,
+		},
+		{
+			name:               "two",
+			entries:            testDirEntries,
+			entryCount:         2,
+			expectedEntriesBuf: append(dirent1, dirent2...),
+		},
+		{
+			name:                "two with truncated",
+			entries:             testDirEntries,
+			entryCount:          2,
+			writeTruncatedEntry: true,
+			expectedEntriesBuf:  append(append(dirent1, dirent2...), dirent3[0:10]...),
+		},
+		{
+			name:               "three",
+			entries:            testDirEntries,
+			entryCount:         3,
+			expectedEntriesBuf: append(append(dirent1, dirent2...), dirent3...),
+		},
+	}
+
+	for _, tt := range tests {
+		tc := tt
+
+		t.Run(tc.name, func(t *testing.T) {
+			cookie := uint64(1)
+			entriesBuf := make([]byte, len(tc.expectedEntriesBuf))
+			writeDirents(tc.entries, tc.entryCount, tc.writeTruncatedEntry, entriesBuf, cookie)
+			require.Equal(t, tc.expectedEntriesBuf, entriesBuf)
+		})
+	}
+}
diff --git a/imports/wasi_snapshot_preview1/poll_test.go b/imports/wasi_snapshot_preview1/poll_test.go
index b25ddb9d..bf183574 100644
--- a/imports/wasi_snapshot_preview1/poll_test.go
+++ b/imports/wasi_snapshot_preview1/poll_test.go
@@ -1,11 +1,12 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"testing"
 
 	"github.com/tetratelabs/wazero"
-	internalsys "github.com/tetratelabs/wazero/internal/sys"
+	"github.com/tetratelabs/wazero/internal/sys"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
@@ -15,8 +16,8 @@ func Test_pollOneoff(t *testing.T) {
 
 	mem := []byte{
 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // userdata
-		eventTypeClock, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // event type and padding
-		clockIDMonotonic, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // clockID
+		EventTypeClock, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // event type and padding
+		ClockIDMonotonic, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // clockID
 		0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // timeout (ns)
 		0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // precision (ns)
 		0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // flags (relative)
@@ -26,7 +27,7 @@ func Test_pollOneoff(t *testing.T) {
 	expectedMem := []byte{
 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // userdata
 		byte(ErrnoSuccess), 0x0, // errno is 16 bit
-		eventTypeClock, 0x0, 0x0, 0x0, // 4 bytes for type enum
+		EventTypeClock, 0x0, 0x0, 0x0, // 4 bytes for type enum
 		'?', // stopped after encoding
 	}
 
@@ -38,7 +39,7 @@ func Test_pollOneoff(t *testing.T) {
 	maskMemory(t, mod, 1024)
 	mod.Memory().Write(in, mem)
 
-	requireErrno(t, ErrnoSuccess, mod, pollOneoffName, uint64(in), uint64(out), uint64(nsubscriptions),
+	requireErrno(t, ErrnoSuccess, mod, PollOneoffName, uint64(in), uint64(out), uint64(nsubscriptions),
 		uint64(resultNevents))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.poll_oneoff(in=0,out=128,nsubscriptions=1,result.nevents=512)
@@ -110,12 +111,12 @@ func Test_pollOneoff_Errors(t *testing.T) {
 `,
 		},
 		{
-			name:           "unsupported eventTypeFdRead",
+			name:           "unsupported EventTypeFdRead",
 			nsubscriptions: 1,
 			mem: []byte{
 				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // userdata
-				eventTypeFdRead, 0x0, 0x0, 0x0,
-				byte(internalsys.FdStdin), 0x0, 0x0, 0x0, // valid readable FD
+				EventTypeFdRead, 0x0, 0x0, 0x0,
+				byte(sys.FdStdin), 0x0, 0x0, 0x0, // valid readable FD
 				'?', // stopped after encoding
 			},
 			expectedErrno: ErrnoSuccess,
@@ -124,7 +125,7 @@ func Test_pollOneoff_Errors(t *testing.T) {
 			expectedMem: []byte{
 				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // userdata
 				byte(ErrnoNotsup), 0x0, // errno is 16 bit
-				eventTypeFdRead, 0x0, 0x0, 0x0, // 4 bytes for type enum
+				EventTypeFdRead, 0x0, 0x0, 0x0, // 4 bytes for type enum
 				'?', // stopped after encoding
 			},
 			expectedLog: `
@@ -145,7 +146,7 @@ func Test_pollOneoff_Errors(t *testing.T) {
 				mod.Memory().Write(tc.in, tc.mem)
 			}
 
-			requireErrno(t, tc.expectedErrno, mod, pollOneoffName, uint64(tc.in), uint64(tc.out),
+			requireErrno(t, tc.expectedErrno, mod, PollOneoffName, uint64(tc.in), uint64(tc.out),
 				uint64(tc.nsubscriptions), uint64(tc.resultNevents))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
diff --git a/imports/wasi_snapshot_preview1/proc_test.go b/imports/wasi_snapshot_preview1/proc_test.go
index c66396f3..8ab55e44 100644
--- a/imports/wasi_snapshot_preview1/proc_test.go
+++ b/imports/wasi_snapshot_preview1/proc_test.go
@@ -1,10 +1,11 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"testing"
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/sys"
 )
 
@@ -40,7 +41,7 @@ func Test_procExit(t *testing.T) {
 			defer log.Reset()
 
 			// Since procExit panics, any opcodes afterwards cannot be reached.
-			_, err := mod.ExportedFunction(procExitName).Call(testCtx, uint64(tc.exitCode))
+			_, err := mod.ExportedFunction(ProcExitName).Call(testCtx, uint64(tc.exitCode))
 			require.Error(t, err)
 			sysErr, ok := err.(*sys.ExitError)
 			require.True(t, ok, err)
@@ -52,7 +53,7 @@ func Test_procExit(t *testing.T) {
 
 // Test_procRaise only tests it is stubbed for GrainLang per #271
 func Test_procRaise(t *testing.T) {
-	log := requireErrnoNosys(t, procRaiseName, 0)
+	log := requireErrnoNosys(t, ProcRaiseName, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.proc_raise(sig=0)
 <-- errno=ENOSYS
diff --git a/imports/wasi_snapshot_preview1/random_test.go b/imports/wasi_snapshot_preview1/random_test.go
index 18a35194..a65ecf0a 100644
--- a/imports/wasi_snapshot_preview1/random_test.go
+++ b/imports/wasi_snapshot_preview1/random_test.go
@@ -1,4 +1,4 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"bytes"
@@ -9,6 +9,7 @@ import (
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 func Test_randomGet(t *testing.T) {
@@ -27,7 +28,7 @@ func Test_randomGet(t *testing.T) {
 	maskMemory(t, mod, len(expectedMemory))
 
 	// Invoke randomGet and check the memory side effects!
-	requireErrno(t, ErrnoSuccess, mod, randomGetName, uint64(offset), uint64(length))
+	requireErrno(t, ErrnoSuccess, mod, RandomGetName, uint64(offset), uint64(length))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.random_get(buf=1,buf_len=5)
 <== errno=ESUCCESS
@@ -75,7 +76,7 @@ func Test_randomGet_Errors(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			defer log.Reset()
 
-			requireErrno(t, ErrnoFault, mod, randomGetName, uint64(tc.offset), uint64(tc.length))
+			requireErrno(t, ErrnoFault, mod, RandomGetName, uint64(tc.offset), uint64(tc.length))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
@@ -112,7 +113,7 @@ func Test_randomGet_SourceError(t *testing.T) {
 				WithRandSource(tc.randSource))
 			defer r.Close(testCtx)
 
-			requireErrno(t, ErrnoIo, mod, randomGetName, uint64(1), uint64(5)) // arbitrary offset and length
+			requireErrno(t, ErrnoIo, mod, RandomGetName, uint64(1), uint64(5)) // arbitrary offset and length
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 		})
 	}
diff --git a/imports/wasi_snapshot_preview1/sched_test.go b/imports/wasi_snapshot_preview1/sched_test.go
index cdf3f6d2..52d0e3d3 100644
--- a/imports/wasi_snapshot_preview1/sched_test.go
+++ b/imports/wasi_snapshot_preview1/sched_test.go
@@ -1,14 +1,15 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"testing"
 
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 // Test_schedYield only tests it is stubbed for GrainLang per #271
 func Test_schedYield(t *testing.T) {
-	log := requireErrnoNosys(t, schedYieldName)
+	log := requireErrnoNosys(t, SchedYieldName)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.sched_yield()
 <-- errno=ENOSYS
diff --git a/imports/wasi_snapshot_preview1/sock_test.go b/imports/wasi_snapshot_preview1/sock_test.go
index e8d3f7d6..98cbc056 100644
--- a/imports/wasi_snapshot_preview1/sock_test.go
+++ b/imports/wasi_snapshot_preview1/sock_test.go
@@ -1,14 +1,15 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"testing"
 
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 // Test_sockAccept only tests it is stubbed for GrainLang per #271
 func Test_sockAccept(t *testing.T) {
-	log := requireErrnoNosys(t, sockAcceptName, 0, 0, 0)
+	log := requireErrnoNosys(t, SockAcceptName, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.sock_accept(fd=0,flags=0,result.fd=0)
 <-- errno=ENOSYS
@@ -17,7 +18,7 @@ func Test_sockAccept(t *testing.T) {
 
 // Test_sockRecv only tests it is stubbed for GrainLang per #271
 func Test_sockRecv(t *testing.T) {
-	log := requireErrnoNosys(t, sockRecvName, 0, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, SockRecvName, 0, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.sock_recv(fd=0,ri_data=0,ri_data_count=0,ri_flags=0,result.ro_datalen=0,result.ro_flags=0)
 <-- errno=ENOSYS
@@ -26,7 +27,7 @@ func Test_sockRecv(t *testing.T) {
 
 // Test_sockSend only tests it is stubbed for GrainLang per #271
 func Test_sockSend(t *testing.T) {
-	log := requireErrnoNosys(t, sockSendName, 0, 0, 0, 0, 0)
+	log := requireErrnoNosys(t, SockSendName, 0, 0, 0, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.sock_send(fd=0,si_data=0,si_data_count=0,si_flags=0,result.so_datalen=0)
 <-- errno=ENOSYS
@@ -35,7 +36,7 @@ func Test_sockSend(t *testing.T) {
 
 // Test_sockShutdown only tests it is stubbed for GrainLang per #271
 func Test_sockShutdown(t *testing.T) {
-	log := requireErrnoNosys(t, sockShutdownName, 0, 0)
+	log := requireErrnoNosys(t, SockShutdownName, 0, 0)
 	require.Equal(t, `
 --> wasi_snapshot_preview1.sock_shutdown(fd=0,how=0)
 <-- errno=ENOSYS
diff --git a/imports/wasi_snapshot_preview1/wasi_bench_test.go b/imports/wasi_snapshot_preview1/wasi_bench_test.go
index 9523d8b4..bfebf86d 100644
--- a/imports/wasi_snapshot_preview1/wasi_bench_test.go
+++ b/imports/wasi_snapshot_preview1/wasi_bench_test.go
@@ -1,4 +1,4 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"embed"
@@ -8,8 +8,10 @@ import (
 
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/api"
+	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/sys"
 	"github.com/tetratelabs/wazero/internal/testing/proxy"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/wasm"
 )
 
@@ -30,10 +32,10 @@ func Benchmark_ArgsEnviron(b *testing.B) {
 	}
 
 	for _, n := range []string{
-		argsGetName,
-		argsSizesGetName,
-		environGetName,
-		environSizesGetName,
+		ArgsGetName,
+		ArgsSizesGetName,
+		EnvironGetName,
+		EnvironSizesGetName,
 	} {
 		n := n
 		fn := mod.ExportedFunction(n)
@@ -69,7 +71,7 @@ func Benchmark_fdRead(b *testing.B) {
 	if err != nil {
 		b.Fatal(err)
 	}
-	fn := mod.ExportedFunction(fdReadName)
+	fn := mod.ExportedFunction(FdReadName)
 
 	mod.Memory().Write(0, []byte{
 		32, 0, 0, 0, // = iovs[0].offset
@@ -168,7 +170,7 @@ func Benchmark_fdReaddir(b *testing.B) {
 				b.Fatal(err)
 			}
 
-			fn := mod.ExportedFunction(fdReaddirName)
+			fn := mod.ExportedFunction(FdReaddirName)
 
 			// Open the root directory as a file-descriptor.
 			fsc := mod.(*wasm.CallContext).Sys.FS()
@@ -285,7 +287,7 @@ func Benchmark_pathFilestat(b *testing.B) {
 				defer fsc.CloseFile(fd)
 			}
 
-			fn := mod.ExportedFunction(pathFilestatGetName)
+			fn := mod.ExportedFunction(PathFilestatGetName)
 
 			b.ResetTimer()
 			b.ReportAllocs()
@@ -338,7 +340,7 @@ func Benchmark_fdWrite(b *testing.B) {
 	if err != nil {
 		b.Fatal(err)
 	}
-	fn := mod.ExportedFunction(fdWriteName)
+	fn := mod.ExportedFunction(FdWriteName)
 
 	iovs := uint32(1) // arbitrary offset
 	mod.Memory().Write(0, []byte{
@@ -389,7 +391,7 @@ func Benchmark_fdWrite(b *testing.B) {
 
 // instantiateProxyModule instantiates a guest that re-exports WASI functions.
 func instantiateProxyModule(r wazero.Runtime, config wazero.ModuleConfig) (api.Module, error) {
-	wasiModuleCompiled, err := (&builder{r}).hostModuleBuilder().Compile(testCtx)
+	wasiModuleCompiled, err := wasi_snapshot_preview1.NewBuilder(r).Compile(testCtx)
 	if err != nil {
 		return nil, err
 	}
@@ -398,7 +400,7 @@ func instantiateProxyModule(r wazero.Runtime, config wazero.ModuleConfig) (api.M
 		return nil, err
 	}
 
-	proxyBin := proxy.NewModuleBinary(ModuleName, wasiModuleCompiled)
+	proxyBin := proxy.NewModuleBinary(wasi_snapshot_preview1.ModuleName, wasiModuleCompiled)
 
 	proxyCompiled, err := r.CompileModule(testCtx, proxyBin)
 	if err != nil {
diff --git a/imports/wasi_snapshot_preview1/wasi_stdlib_test.go b/imports/wasi_snapshot_preview1/wasi_stdlib_test.go
index 6cbcfc26..a560c956 100644
--- a/imports/wasi_snapshot_preview1/wasi_stdlib_test.go
+++ b/imports/wasi_snapshot_preview1/wasi_stdlib_test.go
@@ -1,6 +1,4 @@
-// package wasi_snapshot_preview1 ensures that the behavior we've implemented
-// not only matches the wasi spec, but also at least two compilers use of sdks.
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"bytes"
@@ -12,10 +10,14 @@ import (
 	"testing/fstest"
 
 	"github.com/tetratelabs/wazero"
+	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/testing/require"
 	"github.com/tetratelabs/wazero/sys"
 )
 
+// This file ensures that the behavior we've implemented not only the wasi
+// spec, but also at least two compilers use of sdks.
+
 // wasmCargoWasi was compiled from testdata/cargo-wasi/wasi.rs
 //
 //go:embed testdata/cargo-wasi/wasi.wasm
@@ -126,7 +128,7 @@ func compileAndRun(t *testing.T, config wazero.ModuleConfig, bin []byte) (consol
 	r := wazero.NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
-	_, err := Instantiate(testCtx, r)
+	_, err := wasi_snapshot_preview1.Instantiate(testCtx, r)
 	require.NoError(t, err)
 
 	compiled, err := r.CompileModule(testCtx, bin)
diff --git a/imports/wasi_snapshot_preview1/wasi_test.go b/imports/wasi_snapshot_preview1/wasi_test.go
index 0ad71283..36056d64 100644
--- a/imports/wasi_snapshot_preview1/wasi_test.go
+++ b/imports/wasi_snapshot_preview1/wasi_test.go
@@ -1,4 +1,4 @@
-package wasi_snapshot_preview1
+package wasi_snapshot_preview1_test
 
 import (
 	"bytes"
@@ -9,8 +9,10 @@ import (
 	"github.com/tetratelabs/wazero"
 	"github.com/tetratelabs/wazero/api"
 	. "github.com/tetratelabs/wazero/experimental"
+	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/testing/proxy"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/sys"
 )
 
@@ -34,7 +36,7 @@ func TestNewFunctionExporter(t *testing.T) {
 		// Instantiate the current WASI functions under the wasi_unstable
 		// instead of wasi_snapshot_preview1.
 		wasiBuilder := r.NewHostModuleBuilder("wasi_unstable")
-		NewFunctionExporter().ExportFunctions(wasiBuilder)
+		wasi_snapshot_preview1.NewFunctionExporter().ExportFunctions(wasiBuilder)
 		_, err := wasiBuilder.Instantiate(testCtx, r)
 		require.NoError(t, err)
 
@@ -50,8 +52,8 @@ func TestNewFunctionExporter(t *testing.T) {
 		defer r.Close(testCtx)
 
 		// Export the default WASI functions
-		wasiBuilder := r.NewHostModuleBuilder(ModuleName)
-		NewFunctionExporter().ExportFunctions(wasiBuilder)
+		wasiBuilder := r.NewHostModuleBuilder(wasi_snapshot_preview1.ModuleName)
+		wasi_snapshot_preview1.NewFunctionExporter().ExportFunctions(wasiBuilder)
 
 		// Override proc_exit to prove the point that you can add or replace
 		// functions like this.
@@ -88,13 +90,13 @@ func requireProxyModule(t *testing.T, config wazero.ModuleConfig) (api.Module, a
 
 	r := wazero.NewRuntime(ctx)
 
-	wasiModuleCompiled, err := (&builder{r}).hostModuleBuilder().Compile(ctx)
+	wasiModuleCompiled, err := wasi_snapshot_preview1.NewBuilder(r).Compile(ctx)
 	require.NoError(t, err)
 
 	_, err = r.InstantiateModule(ctx, wasiModuleCompiled, config)
 	require.NoError(t, err)
 
-	proxyBin := proxy.NewModuleBinary(ModuleName, wasiModuleCompiled)
+	proxyBin := proxy.NewModuleBinary(wasi_snapshot_preview1.ModuleName, wasiModuleCompiled)
 
 	proxyCompiled, err := r.CompileModule(ctx, proxyBin)
 	require.NoError(t, err)
@@ -118,13 +120,13 @@ func requireErrnoNosys(t *testing.T, funcName string, params ...uint64) string {
 	defer r.Close(ctx)
 
 	// Instantiate the wasi module.
-	wasiModuleCompiled, err := (&builder{r}).hostModuleBuilder().Compile(ctx)
+	wasiModuleCompiled, err := wasi_snapshot_preview1.NewBuilder(r).Compile(ctx)
 	require.NoError(t, err)
 
 	_, err = r.InstantiateModule(ctx, wasiModuleCompiled, wazero.NewModuleConfig())
 	require.NoError(t, err)
 
-	proxyBin := proxy.NewModuleBinary(ModuleName, wasiModuleCompiled)
+	proxyBin := proxy.NewModuleBinary(wasi_snapshot_preview1.ModuleName, wasiModuleCompiled)
 
 	proxyCompiled, err := r.CompileModule(ctx, proxyBin)
 	require.NoError(t, err)
diff --git a/internal/integration_test/fs/fs_test.go b/internal/integration_test/fs/fs_test.go
index 2e9be67b..1f24c3c7 100644
--- a/internal/integration_test/fs/fs_test.go
+++ b/internal/integration_test/fs/fs_test.go
@@ -14,6 +14,7 @@ import (
 	"github.com/tetratelabs/wazero/api"
 	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
 	"github.com/tetratelabs/wazero/internal/testing/require"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 var testCtx = context.Background()
@@ -64,7 +65,7 @@ func (fs *wasiFs) Open(name string) (fs.File, error) {
 		uint64(fd), uint64(dirflags), uint64(pathPtr), uint64(pathLen), uint64(oflags),
 		fsRightsBase, fsRightsInheriting, uint64(fdflags), uint64(resultOpenedFd))
 	require.NoError(fs.t, err)
-	require.Equal(fs.t, uint64(wasi_snapshot_preview1.ErrnoSuccess), res[0])
+	require.Equal(fs.t, uint64(ErrnoSuccess), res[0])
 
 	resFd, ok := fs.memory.ReadUint32Le(resultOpenedFd)
 	require.True(fs.t, ok)
@@ -105,7 +106,7 @@ func (f *wasiFile) Read(bytes []byte) (int, error) {
 	res, err := f.fs.fdRead.Call(testCtx, uint64(f.fd), uint64(iovsOff), uint64(iovsCount), uint64(resultSizeOff))
 	require.NoError(f.fs.t, err)
 
-	require.NotEqual(f.fs.t, uint64(wasi_snapshot_preview1.ErrnoFault), res[0])
+	require.NotEqual(f.fs.t, uint64(ErrnoFault), res[0])
 
 	numRead, ok := f.fs.memory.ReadUint32Le(resultSizeOff)
 	require.True(f.fs.t, ok)
@@ -114,7 +115,7 @@ func (f *wasiFile) Read(bytes []byte) (int, error) {
 		if len(bytes) == 0 {
 			return 0, nil
 		}
-		if wasi_snapshot_preview1.Errno(res[0]) == wasi_snapshot_preview1.ErrnoSuccess {
+		if Errno(res[0]) == ErrnoSuccess {
 			return 0, io.EOF
 		} else {
 			return 0, fmt.Errorf("could not read from file")
@@ -130,7 +131,7 @@ func (f *wasiFile) Read(bytes []byte) (int, error) {
 func (f *wasiFile) Close() error {
 	res, err := f.fs.fdClose.Call(testCtx, uint64(f.fd))
 	require.NoError(f.fs.t, err)
-	require.NotEqual(f.fs.t, uint64(wasi_snapshot_preview1.ErrnoFault), res[0])
+	require.NotEqual(f.fs.t, uint64(ErrnoFault), res[0])
 	return nil
 }
 
@@ -140,7 +141,7 @@ func (f *wasiFile) Seek(offset int64, whence int) (int64, error) {
 
 	res, err := f.fs.fdSeek.Call(testCtx, uint64(f.fd), uint64(offset), uint64(whence), uint64(resultNewoffsetOff))
 	require.NoError(f.fs.t, err)
-	require.NotEqual(f.fs.t, uint64(wasi_snapshot_preview1.ErrnoFault), res[0])
+	require.NotEqual(f.fs.t, uint64(ErrnoFault), res[0])
 
 	newOffset, ok := f.fs.memory.ReadUint32Le(resultNewoffsetOff)
 	require.True(f.fs.t, ok)
diff --git a/internal/wasm/host_test.go b/internal/wasm/host_test.go
index 623790a0..5d88041c 100644
--- a/internal/wasm/host_test.go
+++ b/internal/wasm/host_test.go
@@ -6,7 +6,7 @@ import (
 
 	"github.com/tetratelabs/wazero/api"
 	"github.com/tetratelabs/wazero/internal/testing/require"
-	"github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
+	. "github.com/tetratelabs/wazero/internal/wasi_snapshot_preview1"
 )
 
 func argsSizesGet(ctx context.Context, mod api.Module, resultArgc, resultArgvBufSize uint32) uint32 {
@@ -22,8 +22,6 @@ func swap(ctx context.Context, x, y uint32) (uint32, uint32) {
 }
 
 func TestNewHostModule(t *testing.T) {
-	argsSizesGetName := "args_sizes_get"
-	fdWriteName := "fd_write"
 	swapName := "swap"
 
 	tests := []struct {
@@ -43,19 +41,19 @@ func TestNewHostModule(t *testing.T) {
 		},
 		{
 			name:       "funcs",
-			moduleName: wasi_snapshot_preview1.ModuleName,
+			moduleName: InternalModuleName,
 			nameToGoFunc: map[string]interface{}{
-				argsSizesGetName: argsSizesGet,
-				fdWriteName:      fdWrite,
+				ArgsSizesGetName: argsSizesGet,
+				FdWriteName:      fdWrite,
 			},
 			funcToNames: map[string]*HostFuncNames{
-				argsSizesGetName: {
-					Name:        argsSizesGetName,
+				ArgsSizesGetName: {
+					Name:        ArgsSizesGetName,
 					ParamNames:  []string{"result.argc", "result.argv_len"},
 					ResultNames: []string{"errno"},
 				},
-				fdWriteName: {
-					Name:        fdWriteName,
+				FdWriteName: {
+					Name:        FdWriteName,
 					ParamNames:  []string{"fd", "iovs", "iovs_len", "result.size"},
 					ResultNames: []string{"errno"},
 				},
@@ -68,14 +66,14 @@ func TestNewHostModule(t *testing.T) {
 				FunctionSection: []Index{0, 1},
 				CodeSection:     []*Code{MustParseGoReflectFuncCode(argsSizesGet), MustParseGoReflectFuncCode(fdWrite)},
 				ExportSection: []*Export{
-					{Name: "args_sizes_get", Type: ExternTypeFunc, Index: 0},
-					{Name: "fd_write", Type: ExternTypeFunc, Index: 1},
+					{Name: ArgsSizesGetName, Type: ExternTypeFunc, Index: 0},
+					{Name: FdWriteName, Type: ExternTypeFunc, Index: 1},
 				},
 				NameSection: &NameSection{
-					ModuleName: wasi_snapshot_preview1.ModuleName,
+					ModuleName: InternalModuleName,
 					FunctionNames: NameMap{
-						{Index: 0, Name: "args_sizes_get"},
-						{Index: 1, Name: "fd_write"},
+						{Index: 0, Name: ArgsSizesGetName},
+						{Index: 1, Name: FdWriteName},
 					},
 					LocalNames: IndirectNameMap{
 						{Index: 0, NameMap: NameMap{