return true
}
-func toWasmFields(result *abi.ABIParamResultInfo, abiParams []abi.ABIParamAssignment) []obj.WasmField {
+func paramsToWasmFields(f *ir.Func, result *abi.ABIParamResultInfo, abiParams []abi.ABIParamAssignment) []obj.WasmField {
wfs := make([]obj.WasmField, len(abiParams))
for i, p := range abiParams {
t := p.Type
- switch {
- case t.IsInteger() && t.Size() == 4:
+ switch t.Kind() {
+ case types.TINT32, types.TUINT32:
wfs[i].Type = obj.WasmI32
- case t.IsInteger() && t.Size() == 8:
+ case types.TINT64, types.TUINT64:
wfs[i].Type = obj.WasmI64
- case t.IsFloat() && t.Size() == 4:
+ case types.TFLOAT32:
wfs[i].Type = obj.WasmF32
- case t.IsFloat() && t.Size() == 8:
+ case types.TFLOAT64:
wfs[i].Type = obj.WasmF64
- case t.IsPtr():
+ case types.TUNSAFEPTR:
wfs[i].Type = obj.WasmPtr
default:
- base.Fatalf("wasm import has bad function signature")
+ base.ErrorfAt(f.Pos(), 0, "go:wasmimport %s %s: unsupported parameter type %s", f.WasmImport.Module, f.WasmImport.Name, t.String())
+ }
+ wfs[i].Offset = p.FrameOffset(result)
+ }
+ return wfs
+}
+
+func resultsToWasmFields(f *ir.Func, result *abi.ABIParamResultInfo, abiParams []abi.ABIParamAssignment) []obj.WasmField {
+ if len(abiParams) > 1 {
+ base.ErrorfAt(f.Pos(), 0, "go:wasmimport %s %s: too many return values", f.WasmImport.Module, f.WasmImport.Name)
+ return nil
+ }
+ wfs := make([]obj.WasmField, len(abiParams))
+ for i, p := range abiParams {
+ t := p.Type
+ switch t.Kind() {
+ case types.TINT32, types.TUINT32:
+ wfs[i].Type = obj.WasmI32
+ case types.TINT64, types.TUINT64:
+ wfs[i].Type = obj.WasmI64
+ case types.TFLOAT32:
+ wfs[i].Type = obj.WasmF32
+ case types.TFLOAT64:
+ wfs[i].Type = obj.WasmF64
+ default:
+ base.ErrorfAt(f.Pos(), 0, "go:wasmimport %s %s: unsupported result type %s", f.WasmImport.Module, f.WasmImport.Name, t.String())
}
wfs[i].Offset = p.FrameOffset(result)
}
// (import "a_module" "add" (func (param i32 i32) (result i32)))
abiConfig := AbiForBodylessFuncStackMap(f)
abiInfo := abiConfig.ABIAnalyzeFuncType(f.Type().FuncType())
- wi.Params = toWasmFields(abiInfo, abiInfo.InParams())
- wi.Results = toWasmFields(abiInfo, abiInfo.OutParams())
+ wi.Params = paramsToWasmFields(f, abiInfo, abiInfo.InParams())
+ wi.Results = resultsToWasmFields(f, abiInfo, abiInfo.OutParams())
}
f.LSym.Func().WasmImport = &wi
}
//go:wasmimport wasi_snapshot_preview1 args_get
//go:noescape
-func args_get(argv *uintptr32, argvBuf *byte) errno
+func args_get(argv, argvBuf unsafe.Pointer) errno
//go:wasmimport wasi_snapshot_preview1 args_sizes_get
//go:noescape
-func args_sizes_get(argc *size, argvBufLen *size) errno
+func args_sizes_get(argc, argvBufLen unsafe.Pointer) errno
//go:wasmimport wasi_snapshot_preview1 clock_time_get
//go:noescape
-func clock_time_get(clock_id clockid, precision timestamp, time *timestamp) errno
+func clock_time_get(clock_id clockid, precision timestamp, time unsafe.Pointer) errno
//go:wasmimport wasi_snapshot_preview1 environ_get
//go:noescape
-func environ_get(environ *uintptr32, environBuf *byte) errno
+func environ_get(environ, environBuf unsafe.Pointer) errno
//go:wasmimport wasi_snapshot_preview1 environ_sizes_get
//go:noescape
-func environ_sizes_get(environCount *size, environBufLen *size) errno
+func environ_sizes_get(environCount, environBufLen unsafe.Pointer) errno
//go:wasmimport wasi_snapshot_preview1 fd_write
//go:noescape
-func fd_write(fd int32, iovs *iovec, iovsLen size, nwritten *size) errno
+func fd_write(fd int32, iovs unsafe.Pointer, iovsLen size, nwritten unsafe.Pointer) errno
//go:wasmimport wasi_snapshot_preview1 random_get
//go:noescape
-func random_get(buf *byte, bufLen size) errno
+func random_get(buf unsafe.Pointer, bufLen size) errno
type eventtype = uint8
//go:wasmimport wasi_snapshot_preview1 poll_oneoff
//go:noescape
-func poll_oneoff(in *subscription, out *event, nsubscriptions size, nevents *size) errno
+func poll_oneoff(in, out unsafe.Pointer, nsubscriptions size, nevents unsafe.Pointer) errno
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
iov := iovec{
bufLen: size(n),
}
var nwritten size
- if fd_write(int32(fd), &iov, 1, &nwritten) != 0 {
+ if fd_write(int32(fd), unsafe.Pointer(&iov), 1, unsafe.Pointer(&nwritten)) != 0 {
throw("fd_write failed")
}
return int32(nwritten)
subscription.timeout = timestamp(usec) * 1e3
subscription.precision = 1e3
- if poll_oneoff(&in, &out, 1, &nevents) != 0 {
+ if poll_oneoff(unsafe.Pointer(&in), unsafe.Pointer(&out), 1, unsafe.Pointer(&nevents)) != 0 {
throw("wasi_snapshot_preview1.poll_oneoff")
}
}
func getRandomData(r []byte) {
- if random_get(&r[0], size(len(r))) != 0 {
+ if random_get(unsafe.Pointer(&r[0]), size(len(r))) != 0 {
throw("random_get failed")
}
}
// arguments
var argc size
var argvBufLen size
- if args_sizes_get(&argc, &argvBufLen) != 0 {
+ if args_sizes_get(unsafe.Pointer(&argc), unsafe.Pointer(&argvBufLen)) != 0 {
throw("args_sizes_get failed")
}
if argc > 0 {
argv := make([]uintptr32, argc)
argvBuf := make([]byte, argvBufLen)
- if args_get(&argv[0], &argvBuf[0]) != 0 {
+ if args_get(unsafe.Pointer(&argv[0]), unsafe.Pointer(&argvBuf[0])) != 0 {
throw("args_get failed")
}
// environment
var environCount size
var environBufLen size
- if environ_sizes_get(&environCount, &environBufLen) != 0 {
+ if environ_sizes_get(unsafe.Pointer(&environCount), unsafe.Pointer(&environBufLen)) != 0 {
throw("environ_sizes_get failed")
}
if environCount > 0 {
environ := make([]uintptr32, environCount)
environBuf := make([]byte, environBufLen)
- if environ_get(&environ[0], &environBuf[0]) != 0 {
+ if environ_get(unsafe.Pointer(&environ[0]), unsafe.Pointer(&environBuf[0])) != 0 {
throw("environ_get failed")
}
func walltime1() (sec int64, nsec int32) {
var time timestamp
- if clock_time_get(clockRealtime, 0, &time) != 0 {
+ if clock_time_get(clockRealtime, 0, unsafe.Pointer(&time)) != 0 {
throw("clock_time_get failed")
}
return int64(time / 1000000000), int32(time % 1000000000)
func nanotime1() int64 {
var time timestamp
- if clock_time_get(clockMonotonic, 0, &time) != 0 {
+ if clock_time_get(clockMonotonic, 0, unsafe.Pointer(&time)) != 0 {
throw("clock_time_get failed")
}
return int64(time)
//
//go:wasmimport wasi_snapshot_preview1 fd_pread
//go:noescape
-func fd_pread(fd int32, iovs *iovec, iovsLen size, offset filesize, nread *size) Errno
+func fd_pread(fd int32, iovs unsafe.Pointer, iovsLen size, offset filesize, nread unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_pwrite
//go:noescape
-func fd_pwrite(fd int32, iovs *iovec, iovsLen size, offset filesize, nwritten *size) Errno
+func fd_pwrite(fd int32, iovs unsafe.Pointer, iovsLen size, offset filesize, nwritten unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_read
//go:noescape
-func fd_read(fd int32, iovs *iovec, iovsLen size, nread *size) Errno
+func fd_read(fd int32, iovs unsafe.Pointer, iovsLen size, nread unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_readdir
//go:noescape
-func fd_readdir(fd int32, buf *byte, bufLen size, cookie dircookie, nwritten *size) Errno
+func fd_readdir(fd int32, buf unsafe.Pointer, bufLen size, cookie dircookie, nwritten unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_seek
//go:noescape
-func fd_seek(fd int32, offset filedelta, whence uint32, newoffset *filesize) Errno
+func fd_seek(fd int32, offset filedelta, whence uint32, newoffset unsafe.Pointer) Errno
// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-fd_fdstat_set_rightsfd-fd-fs_rights_base-rights-fs_rights_inheriting-rights---result-errno
//
//go:wasmimport wasi_snapshot_preview1 fd_filestat_get
//go:noescape
-func fd_filestat_get(fd int32, buf *Stat_t) Errno
+func fd_filestat_get(fd int32, buf unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_write
//go:noescape
-func fd_write(fd int32, iovs *iovec, iovsLen size, nwritten *size) Errno
+func fd_write(fd int32, iovs unsafe.Pointer, iovsLen size, nwritten unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_sync
//go:noescape
//go:wasmimport wasi_snapshot_preview1 path_create_directory
//go:noescape
-func path_create_directory(fd int32, path *byte, pathLen size) Errno
+func path_create_directory(fd int32, path unsafe.Pointer, pathLen size) Errno
//go:wasmimport wasi_snapshot_preview1 path_filestat_get
//go:noescape
-func path_filestat_get(fd int32, flags lookupflags, path *byte, pathLen size, buf *Stat_t) Errno
+func path_filestat_get(fd int32, flags lookupflags, path unsafe.Pointer, pathLen size, buf unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 path_filestat_set_times
//go:noescape
-func path_filestat_set_times(fd int32, flags lookupflags, path *byte, pathLen size, atim timestamp, mtim timestamp, fstflags fstflags) Errno
+func path_filestat_set_times(fd int32, flags lookupflags, path unsafe.Pointer, pathLen size, atim timestamp, mtim timestamp, fstflags fstflags) Errno
//go:wasmimport wasi_snapshot_preview1 path_link
//go:noescape
-func path_link(oldFd int32, oldFlags lookupflags, oldPath *byte, oldPathLen size, newFd int32, newPath *byte, newPathLen size) Errno
+func path_link(oldFd int32, oldFlags lookupflags, oldPath unsafe.Pointer, oldPathLen size, newFd int32, newPath unsafe.Pointer, newPathLen size) Errno
//go:wasmimport wasi_snapshot_preview1 path_readlink
//go:noescape
-func path_readlink(fd int32, path *byte, pathLen size, buf *byte, bufLen size, nwritten *size) Errno
+func path_readlink(fd int32, path unsafe.Pointer, pathLen size, buf unsafe.Pointer, bufLen size, nwritten unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 path_remove_directory
//go:noescape
-func path_remove_directory(fd int32, path *byte, pathLen size) Errno
+func path_remove_directory(fd int32, path unsafe.Pointer, pathLen size) Errno
//go:wasmimport wasi_snapshot_preview1 path_rename
//go:noescape
-func path_rename(oldFd int32, oldPath *byte, oldPathLen size, newFd int32, newPath *byte, newPathLen size) Errno
+func path_rename(oldFd int32, oldPath unsafe.Pointer, oldPathLen size, newFd int32, newPath unsafe.Pointer, newPathLen size) Errno
//go:wasmimport wasi_snapshot_preview1 path_symlink
//go:noescape
-func path_symlink(oldPath *byte, oldPathLen size, fd int32, newPath *byte, newPathLen size) Errno
+func path_symlink(oldPath unsafe.Pointer, oldPathLen size, fd int32, newPath unsafe.Pointer, newPathLen size) Errno
//go:wasmimport wasi_snapshot_preview1 path_unlink_file
//go:noescape
-func path_unlink_file(fd int32, path *byte, pathLen size) Errno
+func path_unlink_file(fd int32, path unsafe.Pointer, pathLen size) Errno
//go:wasmimport wasi_snapshot_preview1 path_open
//go:noescape
-func path_open(rootFD int32, dirflags lookupflags, path *byte, pathLen size, oflags oflags, fsRightsBase rights, fsRightsInheriting rights, fsFlags fdflags, fd *int32) Errno
+func path_open(rootFD int32, dirflags lookupflags, path unsafe.Pointer, pathLen size, oflags oflags, fsRightsBase rights, fsRightsInheriting rights, fsFlags fdflags, fd unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 random_get
//go:noescape
-func random_get(buf *byte, bufLen size) Errno
+func random_get(buf unsafe.Pointer, bufLen size) Errno
type preopentype = uint8
//go:wasmimport wasi_snapshot_preview1 fd_prestat_get
//go:noescape
-func fd_prestat_get(fd int32, prestat *prestat) Errno
+func fd_prestat_get(fd int32, prestat unsafe.Pointer) Errno
//go:wasmimport wasi_snapshot_preview1 fd_prestat_dir_name
//go:noescape
-func fd_prestat_dir_name(fd int32, path *byte, pathLen size) Errno
+func fd_prestat_dir_name(fd int32, path unsafe.Pointer, pathLen size) Errno
type opendir struct {
fd int32
for preopenFd := int32(3); ; preopenFd++ {
var prestat prestat
- errno := fd_prestat_get(preopenFd, &prestat)
+ errno := fd_prestat_get(preopenFd, unsafe.Pointer(&prestat))
if errno == EBADF {
break
}
dirNameBuf = make([]byte, prestat.dir.prNameLen)
}
- errno = fd_prestat_dir_name(preopenFd, &dirNameBuf[0], prestat.dir.prNameLen)
+ errno = fd_prestat_dir_name(preopenFd, unsafe.Pointer(&dirNameBuf[0]), prestat.dir.prNameLen)
if errno != 0 {
panic("fd_prestat_dir_name: " + errno.Error())
}
//
// If the path argument is not absolute, it is first appended to the current
// working directory before resolution.
-func preparePath(path string) (int32, *byte, size) {
+func preparePath(path string) (int32, unsafe.Pointer, size) {
var dirFd = int32(-1)
var dirName string
path = "."
}
- return dirFd, unsafe.StringData(path), size(len(path))
+ return dirFd, stringPointer(path), size(len(path))
}
func Open(path string, openmode int, perm uint32) (int, error) {
LOOKUP_SYMLINK_FOLLOW,
pathPtr,
pathLen,
- &fi,
+ unsafe.Pointer(&fi),
); errno != 0 && errno != ENOENT {
return -1, errnoErr(errno)
}
rights,
fullRights,
fdflags,
- &fd,
+ unsafe.Pointer(&fd),
)
return int(fd), errnoErr(errno)
}
func ReadDir(fd int, buf []byte, cookie dircookie) (int, error) {
var nwritten size
- errno := fd_readdir(int32(fd), &buf[0], size(len(buf)), cookie, &nwritten)
+ errno := fd_readdir(int32(fd), unsafe.Pointer(&buf[0]), size(len(buf)), cookie, unsafe.Pointer(&nwritten))
return int(nwritten), errnoErr(errno)
}
return EINVAL
}
dirFd, pathPtr, pathLen := preparePath(path)
- errno := path_filestat_get(dirFd, LOOKUP_SYMLINK_FOLLOW, pathPtr, pathLen, st)
+ errno := path_filestat_get(dirFd, LOOKUP_SYMLINK_FOLLOW, pathPtr, pathLen, unsafe.Pointer(st))
setDefaultMode(st)
return errnoErr(errno)
}
return EINVAL
}
dirFd, pathPtr, pathLen := preparePath(path)
- errno := path_filestat_get(dirFd, 0, pathPtr, pathLen, st)
+ errno := path_filestat_get(dirFd, 0, pathPtr, pathLen, unsafe.Pointer(st))
setDefaultMode(st)
return errnoErr(errno)
}
func Fstat(fd int, st *Stat_t) error {
- errno := fd_filestat_get(int32(fd), st)
+ errno := fd_filestat_get(int32(fd), unsafe.Pointer(st))
setDefaultMode(st)
return errnoErr(errno)
}
var stat Stat_t
dirFd, pathPtr, pathLen := preparePath(path)
- errno := path_filestat_get(dirFd, LOOKUP_SYMLINK_FOLLOW, pathPtr, pathLen, &stat)
+ errno := path_filestat_get(dirFd, LOOKUP_SYMLINK_FOLLOW, pathPtr, pathLen, unsafe.Pointer(&stat))
if errno != 0 {
return errnoErr(errno)
}
dirFd,
pathPtr,
pathLen,
- &buf[0],
+ unsafe.Pointer(&buf[0]),
size(len(buf)),
- &nwritten,
+ unsafe.Pointer(&nwritten),
)
// For some reason wasmtime returns ERANGE when the output buffer is
// shorter than the symbolic link value. os.Readlink expects a nil
}
dirFd, pathPtr, pathlen := preparePath(link)
errno := path_symlink(
- unsafe.StringData(path),
+ stringPointer(path),
size(len(path)),
dirFd,
pathPtr,
return errnoErr(errno)
}
-func makeIOVec(b []byte) *iovec {
- return &iovec{
- buf: uintptr32(uintptr(unsafe.Pointer(unsafe.SliceData(b)))),
+func bytesPointer(b []byte) unsafe.Pointer {
+ return unsafe.Pointer(unsafe.SliceData(b))
+}
+
+func stringPointer(s string) unsafe.Pointer {
+ return unsafe.Pointer(unsafe.StringData(s))
+}
+
+func makeIOVec(b []byte) unsafe.Pointer {
+ return unsafe.Pointer(&iovec{
+ buf: uintptr32(uintptr(bytesPointer(b))),
bufLen: size(len(b)),
- }
+ })
}
func Read(fd int, b []byte) (int, error) {
var nread size
- errno := fd_read(int32(fd), makeIOVec(b), 1, &nread)
+ errno := fd_read(int32(fd), makeIOVec(b), 1, unsafe.Pointer(&nread))
runtime.KeepAlive(b)
return int(nread), errnoErr(errno)
}
func Write(fd int, b []byte) (int, error) {
var nwritten size
- errno := fd_write(int32(fd), makeIOVec(b), 1, &nwritten)
+ errno := fd_write(int32(fd), makeIOVec(b), 1, unsafe.Pointer(&nwritten))
runtime.KeepAlive(b)
return int(nwritten), errnoErr(errno)
}
func Pread(fd int, b []byte, offset int64) (int, error) {
var nread size
- errno := fd_pread(int32(fd), makeIOVec(b), 1, filesize(offset), &nread)
+ errno := fd_pread(int32(fd), makeIOVec(b), 1, filesize(offset), unsafe.Pointer(&nread))
runtime.KeepAlive(b)
return int(nread), errnoErr(errno)
}
func Pwrite(fd int, b []byte, offset int64) (int, error) {
var nwritten size
- errno := fd_pwrite(int32(fd), makeIOVec(b), 1, filesize(offset), &nwritten)
+ errno := fd_pwrite(int32(fd), makeIOVec(b), 1, filesize(offset), unsafe.Pointer(&nwritten))
runtime.KeepAlive(b)
return int(nwritten), errnoErr(errno)
}
func Seek(fd int, offset int64, whence int) (int64, error) {
var newoffset filesize
- errno := fd_seek(int32(fd), filedelta(offset), uint32(whence), &newoffset)
+ errno := fd_seek(int32(fd), filedelta(offset), uint32(whence), unsafe.Pointer(&newoffset))
return int64(newoffset), errnoErr(errno)
}
}
func RandomGet(b []byte) error {
- errno := random_get(unsafe.SliceData(b), size(len(b)))
+ errno := random_get(bytesPointer(b), size(len(b)))
return errnoErr(errno)
}