diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 965e983..5b88d05 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,6 +48,10 @@ jobs: cmake --build build - name: Test WebAssembly spec run: cd test && python3 run-spec-test.py + - name: Test previous WebAssembly specs + run: | + cd test + python3 run-spec-test.py --spec=v1.1 - name: Test WASI apps run: cd test && python3 run-wasi-test.py @@ -95,6 +99,10 @@ jobs: cmake --build build - name: Test WebAssembly spec run: cd test && python3 run-spec-test.py + - name: Test previous WebAssembly specs + run: | + cd test + python3 run-spec-test.py --spec=v1.1 - name: Test WASI apps run: cd test && python3 run-wasi-test.py @@ -136,6 +144,10 @@ jobs: run: | cd test python run-spec-test.py + - name: Test previous WebAssembly specs + run: | + cd test + python run-spec-test.py --spec=v1.1 - name: Test WASI apps run: | cd test diff --git a/README.md b/README.md index 41afb69..4f97654 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Minimum useful system requirements: **~64Kb** for code and **~10Kb** RAM ☑ Big-Endian systems support ☑ Self-hosting ☑ Gas metering -☐ Multi-value +☑ Multi-value ☐ Reference types ☐ Bulk memory operations ☐ Tail call optimization diff --git a/source/m3_api_meta_wasi.c b/source/m3_api_meta_wasi.c index 83d414a..be233dd 100644 --- a/source/m3_api_meta_wasi.c +++ b/source/m3_api_meta_wasi.c @@ -192,15 +192,60 @@ m3ApiRawFunction(m3_wasi_generic_fd_fdstat_set_flags) m3ApiReturn(ret); } -m3ApiRawFunction(m3_wasi_generic_fd_filestat_get) +m3ApiRawFunction(m3_wasi_unstable_fd_filestat_get) { m3ApiReturnType (uint32_t) m3ApiGetArg (__wasi_fd_t , fd) - m3ApiGetArgMem (__wasi_filestat_t * , buff) + m3ApiGetArgMem (uint8_t * , buf) + + m3ApiCheckMem(buf, 56); // wasi_filestat_t + + __wasi_filestat_t stat; - m3ApiCheckMem(buff, sizeof(__wasi_filestat_t)); + __wasi_errno_t ret = __wasi_fd_filestat_get(fd, &stat); - __wasi_errno_t ret = __wasi_fd_filestat_get(fd, buff); + if (ret != __WASI_ERRNO_SUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 56); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+20, stat.st_nlink); + m3ApiWriteMem64(buf+24, stat.st_size); + m3ApiWriteMem64(buf+32, stat.st_atim); + m3ApiWriteMem64(buf+40, stat.st_mtim); + m3ApiWriteMem64(buf+48, stat.st_ctim); + + m3ApiReturn(ret); +} + +m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_filestat_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArgMem (uint8_t * , buf) + + m3ApiCheckMem(buf, 64); // wasi_filestat_t + + __wasi_filestat_t stat; + + __wasi_errno_t ret = __wasi_fd_filestat_get(fd, &stat); + + if (ret != __WASI_ERRNO_SUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 64); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+24, stat.st_nlink); + m3ApiWriteMem64(buf+32, stat.st_size); + m3ApiWriteMem64(buf+40, stat.st_atim); + m3ApiWriteMem64(buf+48, stat.st_mtim); + m3ApiWriteMem64(buf+56, stat.st_ctim); m3ApiReturn(ret); } @@ -362,19 +407,68 @@ m3ApiRawFunction(m3_wasi_generic_path_open) m3ApiReturn(ret); } -m3ApiRawFunction(m3_wasi_generic_path_filestat_get) +m3ApiRawFunction(m3_wasi_unstable_path_filestat_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArg (__wasi_lookupflags_t , flags) + m3ApiGetArgMem (const char * , path) + m3ApiGetArg (uint32_t , path_len) + m3ApiGetArgMem (uint8_t * , buf) + + m3ApiCheckMem(path, path_len); + m3ApiCheckMem(buf, 56); // wasi_filestat_t + + __wasi_filestat_t stat; + + __wasi_errno_t ret = __wasi_path_filestat_get(fd, flags, path, path_len, &stat); + + if (ret != __WASI_ERRNO_SUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 56); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+20, stat.st_nlink); + m3ApiWriteMem64(buf+24, stat.st_size); + m3ApiWriteMem64(buf+32, stat.st_atim); + m3ApiWriteMem64(buf+40, stat.st_mtim); + m3ApiWriteMem64(buf+48, stat.st_ctim); + + m3ApiReturn(ret); +} + +m3ApiRawFunction(m3_wasi_snapshot_preview1_path_filestat_get) { m3ApiReturnType (uint32_t) m3ApiGetArg (__wasi_fd_t , fd) m3ApiGetArg (__wasi_lookupflags_t , flags) m3ApiGetArgMem (const char * , path) m3ApiGetArg (uint32_t , path_len) - m3ApiGetArgMem (__wasi_filestat_t * , buf) + m3ApiGetArgMem (uint8_t * , buf) m3ApiCheckMem(path, path_len); - m3ApiCheckMem(buf, sizeof(__wasi_filestat_t)); + m3ApiCheckMem(buf, 64); // wasi_filestat_t + + __wasi_filestat_t stat; + + __wasi_errno_t ret = __wasi_path_filestat_get(fd, flags, path, path_len, &stat); + + if (ret != __WASI_ERRNO_SUCCESS) { + m3ApiReturn(ret); + } - __wasi_errno_t ret = __wasi_path_filestat_get(fd, flags, path, path_len, buf); + memset(buf, 0, 64); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+24, stat.st_nlink); + m3ApiWriteMem64(buf+32, stat.st_size); + m3ApiWriteMem64(buf+40, stat.st_atim); + m3ApiWriteMem64(buf+48, stat.st_mtim); + m3ApiWriteMem64(buf+56, stat.st_ctim); m3ApiReturn(ret); } @@ -574,8 +668,12 @@ M3Result m3_LinkWASI (IM3Module module) static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" }; // fd_seek is incompatible -_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_seek", "i(iIi*)", &m3_wasi_snapshot_preview1_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_seek", "i(iIi*)", &m3_wasi_snapshot_preview1_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_filestat_get", "i(i*)", &m3_wasi_unstable_fd_filestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_filestat_get", "i(i*)", &m3_wasi_snapshot_preview1_fd_filestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "path_filestat_get", "i(ii*i*)", &m3_wasi_unstable_path_filestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "path_filestat_get", "i(ii*i*)", &m3_wasi_snapshot_preview1_path_filestat_get))); for (int i=0; i<2; i++) { @@ -595,7 +693,6 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_datasync", _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_get", "i(i*)", &m3_wasi_generic_fd_fdstat_get))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_flags", "i(ii)", &m3_wasi_generic_fd_fdstat_set_flags))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_rights", "i(iII)", ))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_get", "i(i*)", &m3_wasi_generic_fd_filestat_get))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_size", "i(iI)", ))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_times","i(iIIi)", ))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pread", "i(i*iI*)",&m3_wasi_generic_fd_pread))); @@ -610,7 +707,6 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_readdir", _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_write", "i(i*i*)", &m3_wasi_generic_fd_write))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_create_directory", "i(i*i)", &m3_wasi_generic_path_create_directory))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_get", "i(ii*i*)", &m3_wasi_generic_path_filestat_get))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_set_times", "i(ii*iIIi)", ))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_link", "i(ii*ii*i)", ))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open", "i(ii*iiIIi*)", &m3_wasi_generic_path_open))); diff --git a/source/m3_api_uvwasi.c b/source/m3_api_uvwasi.c index a8c72e6..86951c0 100644 --- a/source/m3_api_uvwasi.c +++ b/source/m3_api_uvwasi.c @@ -36,6 +36,97 @@ typedef struct wasi_iovec_t uvwasi_size_t buf_len; } wasi_iovec_t; +#if d_m3EnableWasiTracing + +const char* wasi_errno2str(uvwasi_errno_t err) +{ + switch (err) { + case 0: return "ESUCCESS"; + case 1: return "E2BIG"; + case 2: return "EACCES"; + case 3: return "EADDRINUSE"; + case 4: return "EADDRNOTAVAIL"; + case 5: return "EAFNOSUPPORT"; + case 6: return "EAGAIN"; + case 7: return "EALREADY"; + case 8: return "EBADF"; + case 9: return "EBADMSG"; + case 10: return "EBUSY"; + case 11: return "ECANCELED"; + case 12: return "ECHILD"; + case 13: return "ECONNABORTED"; + case 14: return "ECONNREFUSED"; + case 15: return "ECONNRESET"; + case 16: return "EDEADLK"; + case 17: return "EDESTADDRREQ"; + case 18: return "EDOM"; + case 19: return "EDQUOT"; + case 20: return "EEXIST"; + case 21: return "EFAULT"; + case 22: return "EFBIG"; + case 23: return "EHOSTUNREACH"; + case 24: return "EIDRM"; + case 25: return "EILSEQ"; + case 26: return "EINPROGRESS"; + case 27: return "EINTR"; + case 28: return "EINVAL"; + case 29: return "EIO"; + case 30: return "EISCONN"; + case 31: return "EISDIR"; + case 32: return "ELOOP"; + case 33: return "EMFILE"; + case 34: return "EMLINK"; + case 35: return "EMSGSIZE"; + case 36: return "EMULTIHOP"; + case 37: return "ENAMETOOLONG"; + case 38: return "ENETDOWN"; + case 39: return "ENETRESET"; + case 40: return "ENETUNREACH"; + case 41: return "ENFILE"; + case 42: return "ENOBUFS"; + case 43: return "ENODEV"; + case 44: return "ENOENT"; + case 45: return "ENOEXEC"; + case 46: return "ENOLCK"; + case 47: return "ENOLINK"; + case 48: return "ENOMEM"; + case 49: return "ENOMSG"; + case 50: return "ENOPROTOOPT"; + case 51: return "ENOSPC"; + case 52: return "ENOSYS"; + case 53: return "ENOTCONN"; + case 54: return "ENOTDIR"; + case 55: return "ENOTEMPTY"; + case 56: return "ENOTRECOVERABLE"; + case 57: return "ENOTSOCK"; + case 58: return "ENOTSUP"; + case 59: return "ENOTTY"; + case 60: return "ENXIO"; + case 61: return "EOVERFLOW"; + case 62: return "EOWNERDEAD"; + case 63: return "EPERM"; + case 64: return "EPIPE"; + case 65: return "EPROTO"; + case 66: return "EPROTONOSUPPORT"; + case 67: return "EPROTOTYPE"; + case 68: return "ERANGE"; + case 69: return "EROFS"; + case 70: return "ESPIPE"; + case 71: return "ESRCH"; + case 72: return "ESTALE"; + case 73: return "ETIMEDOUT"; + case 74: return "ETXTBSY"; + case 75: return "EXDEV"; + case 76: return "ENOTCAPABLE"; + default: return ""; + } +} + +# define WASI_TRACE(fmt, ...) { fprintf(stderr, "%s " fmt, __FUNCTION__+16, ##__VA_ARGS__); fprintf(stderr, " => %s\n", wasi_errno2str(ret)); } +#else +# define WASI_TRACE(fmt, ...) +#endif + /* * WASI API implementation */ @@ -165,6 +256,8 @@ m3ApiRawFunction(m3_wasi_generic_fd_prestat_dir_name) uvwasi_errno_t ret = uvwasi_fd_prestat_dir_name(&uvwasi, fd, path, path_len); + WASI_TRACE("fd:%d, len:%d | path:%s", fd, path_len, path); + m3ApiReturn(ret); } @@ -174,41 +267,46 @@ m3ApiRawFunction(m3_wasi_generic_fd_prestat_get) m3ApiGetArg (uvwasi_fd_t , fd) m3ApiGetArgMem (uint8_t * , buf) - m3ApiCheckMem(buf, 2*sizeof(uint32_t)); + m3ApiCheckMem(buf, 8); uvwasi_prestat_t prestat; - uvwasi_errno_t ret; - ret = uvwasi_fd_prestat_get(&uvwasi, fd, &prestat); + uvwasi_errno_t ret = uvwasi_fd_prestat_get(&uvwasi, fd, &prestat); + + WASI_TRACE("fd:%d | type:%d, name_len:%d", fd, prestat.pr_type, prestat.u.dir.pr_name_len); + if (ret != UVWASI_ESUCCESS) { m3ApiReturn(ret); } - m3ApiWriteMem32(buf, prestat.pr_type); + m3ApiWriteMem32(buf+0, prestat.pr_type); m3ApiWriteMem32(buf+4, prestat.u.dir.pr_name_len); - m3ApiReturn(UVWASI_ESUCCESS); + m3ApiReturn(ret); } m3ApiRawFunction(m3_wasi_generic_fd_fdstat_get) { m3ApiReturnType (uint32_t) m3ApiGetArg (uvwasi_fd_t , fd) - m3ApiGetArgMem (uint8_t * , fdstat) + m3ApiGetArgMem (uint8_t * , buf) - m3ApiCheckMem(fdstat, 24); + m3ApiCheckMem(buf, 24); uvwasi_fdstat_t stat; uvwasi_errno_t ret = uvwasi_fd_fdstat_get(&uvwasi, fd, &stat); + WASI_TRACE("fd:%d", fd); + if (ret != UVWASI_ESUCCESS) { m3ApiReturn(ret); } - m3ApiWriteMem16(fdstat, stat.fs_filetype); - m3ApiWriteMem16(fdstat+2, stat.fs_flags); - m3ApiWriteMem64(fdstat+8, stat.fs_rights_base); - m3ApiWriteMem64(fdstat+16, stat.fs_rights_inheriting); - m3ApiReturn(UVWASI_ESUCCESS); + memset(buf, 0, 24); + m3ApiWriteMem8 (buf+0, stat.fs_filetype); + m3ApiWriteMem16(buf+2, stat.fs_flags); + m3ApiWriteMem64(buf+8, stat.fs_rights_base); + m3ApiWriteMem64(buf+16, stat.fs_rights_inheriting); + m3ApiReturn(ret); } m3ApiRawFunction(m3_wasi_generic_fd_fdstat_set_flags) @@ -219,22 +317,71 @@ m3ApiRawFunction(m3_wasi_generic_fd_fdstat_set_flags) uvwasi_errno_t ret = uvwasi_fd_fdstat_set_flags(&uvwasi, fd, flags); + WASI_TRACE("fd:%d, flags:0x%x", fd, flags); + m3ApiReturn(ret); } -m3ApiRawFunction(m3_wasi_generic_fd_filestat_get) +m3ApiRawFunction(m3_wasi_unstable_fd_filestat_get) { m3ApiReturnType (uint32_t) m3ApiGetArg (uvwasi_fd_t , fd) - m3ApiGetArgMem (uvwasi_filestat_t * , buff) + m3ApiGetArgMem (uint8_t * , buf) - //TODO: m3ApiCheckMem + m3ApiCheckMem(buf, 56); // wasi_filestat_t - uvwasi_errno_t ret = uvwasi_fd_filestat_get(&uvwasi, fd, buff); + uvwasi_filestat_t stat; - //TODO: m3ApiWriteMem + uvwasi_errno_t ret = uvwasi_fd_filestat_get(&uvwasi, fd, &stat); - m3ApiReturn(ret); + WASI_TRACE("fd:%d | fs.size:%d", fd, stat.st_size); + + if (ret != UVWASI_ESUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 56); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+20, stat.st_nlink); + m3ApiWriteMem64(buf+24, stat.st_size); + m3ApiWriteMem64(buf+32, stat.st_atim); + m3ApiWriteMem64(buf+40, stat.st_mtim); + m3ApiWriteMem64(buf+48, stat.st_ctim); + + m3ApiReturn(UVWASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_filestat_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (uvwasi_fd_t , fd) + m3ApiGetArgMem (uint8_t * , buf) + + m3ApiCheckMem(buf, 64); // wasi_filestat_t + + uvwasi_filestat_t stat; + + uvwasi_errno_t ret = uvwasi_fd_filestat_get(&uvwasi, fd, &stat); + + WASI_TRACE("fd:%d | fs.size:%d", fd, stat.st_size); + + if (ret != UVWASI_ESUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 64); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+24, stat.st_nlink); + m3ApiWriteMem64(buf+32, stat.st_size); + m3ApiWriteMem64(buf+40, stat.st_atim); + m3ApiWriteMem64(buf+48, stat.st_mtim); + m3ApiWriteMem64(buf+56, stat.st_ctim); + + m3ApiReturn(UVWASI_ESUCCESS); } m3ApiRawFunction(m3_wasi_unstable_fd_seek) @@ -247,17 +394,19 @@ m3ApiRawFunction(m3_wasi_unstable_fd_seek) m3ApiCheckMem(result, sizeof(uvwasi_filesize_t)); - uvwasi_whence_t whence; + uvwasi_whence_t whence = -1; + const char* whstr = "???"; switch (wasi_whence) { - case 0: whence = UVWASI_WHENCE_CUR; break; - case 1: whence = UVWASI_WHENCE_END; break; - case 2: whence = UVWASI_WHENCE_SET; break; - default: m3ApiReturn(UVWASI_EINVAL); + case 0: whence = UVWASI_WHENCE_CUR; whstr = "CUR"; break; + case 1: whence = UVWASI_WHENCE_END; whstr = "END"; break; + case 2: whence = UVWASI_WHENCE_SET; whstr = "SET"; break; } uvwasi_errno_t ret = uvwasi_fd_seek(&uvwasi, fd, offset, whence, result); + WASI_TRACE("fd:%d, offset:%d, whence:%s | result:%d", fd, offset, whstr, *result); + //TODO: m3ApiWriteMem m3ApiReturn(ret); @@ -273,17 +422,19 @@ m3ApiRawFunction(m3_wasi_snapshot_preview1_fd_seek) m3ApiCheckMem(result, sizeof(uvwasi_filesize_t)); - uvwasi_whence_t whence; + uvwasi_whence_t whence = -1; + const char* whstr = "???"; switch (wasi_whence) { - case 0: whence = UVWASI_WHENCE_SET; break; - case 1: whence = UVWASI_WHENCE_CUR; break; - case 2: whence = UVWASI_WHENCE_END; break; - default: m3ApiReturn(UVWASI_EINVAL); + case 0: whence = UVWASI_WHENCE_SET; whstr = "SET"; break; + case 1: whence = UVWASI_WHENCE_CUR; whstr = "CUR"; break; + case 2: whence = UVWASI_WHENCE_END; whstr = "END"; break; } uvwasi_errno_t ret = uvwasi_fd_seek(&uvwasi, fd, offset, whence, result); + WASI_TRACE("fd:%d, offset:%d, whence:%s | result:%d", fd, offset, whstr, *result); + //TODO: m3ApiWriteMem m3ApiReturn(ret); @@ -300,6 +451,8 @@ m3ApiRawFunction(m3_wasi_generic_path_create_directory) uvwasi_errno_t ret = uvwasi_path_create_directory(&uvwasi, fd, path, path_len); + WASI_TRACE("fd:%d, path:%s", fd, path); + m3ApiReturn(ret); } @@ -321,6 +474,8 @@ m3ApiRawFunction(m3_wasi_generic_path_readlink) uvwasi_errno_t ret = uvwasi_path_readlink(&uvwasi, fd, path, path_len, buf, buf_len, &uvbufused); + WASI_TRACE("fd:%d, path:%s | buf:%s, bufused:%d", fd, path, buf, uvbufused); + m3ApiWriteMem32(bufused, uvbufused); m3ApiReturn(ret); @@ -337,6 +492,8 @@ m3ApiRawFunction(m3_wasi_generic_path_remove_directory) uvwasi_errno_t ret = uvwasi_path_remove_directory(&uvwasi, fd, path, path_len); + WASI_TRACE("fd:%d, path:%s", fd, path); + m3ApiReturn(ret); } @@ -356,6 +513,8 @@ m3ApiRawFunction(m3_wasi_generic_path_rename) uvwasi_errno_t ret = uvwasi_path_rename(&uvwasi, old_fd, old_path, old_path_len, new_fd, new_path, new_path_len); + WASI_TRACE("old_fd:%d, old_path:%s, new_fd:%d, new_path:%s", old_fd, old_path, new_fd, new_path); + m3ApiReturn(ret); } @@ -370,6 +529,8 @@ m3ApiRawFunction(m3_wasi_generic_path_unlink_file) uvwasi_errno_t ret = uvwasi_path_unlink_file(&uvwasi, fd, path, path_len); + WASI_TRACE("fd:%d, path:%s", fd, path); + m3ApiReturn(ret); } @@ -402,28 +563,81 @@ m3ApiRawFunction(m3_wasi_generic_path_open) fs_flags, &uvfd); + WASI_TRACE("dirfd:%d, dirflags:0x%x, path:%s, oflags:0x%x, fs_flags:0x%x | fd:%d", dirfd, dirflags, path, oflags, fs_flags, uvfd); + m3ApiWriteMem32(fd, uvfd); m3ApiReturn(ret); } -m3ApiRawFunction(m3_wasi_generic_path_filestat_get) +m3ApiRawFunction(m3_wasi_unstable_path_filestat_get) { m3ApiReturnType (uint32_t) m3ApiGetArg (uvwasi_fd_t , fd) m3ApiGetArg (uvwasi_lookupflags_t , flags) m3ApiGetArgMem (const char * , path) m3ApiGetArg (uint32_t , path_len) - m3ApiGetArgMem (uvwasi_filestat_t * , buf) + m3ApiGetArgMem (uint8_t * , buf) m3ApiCheckMem(path, path_len); - m3ApiCheckMem(buf, sizeof(uvwasi_filestat_t)); + m3ApiCheckMem(buf, 56); // wasi_filestat_t - uvwasi_errno_t ret = uvwasi_path_filestat_get(&uvwasi, fd, flags, path, path_len, buf); + uvwasi_filestat_t stat; - //TODO: m3ApiWriteMem + uvwasi_errno_t ret = uvwasi_path_filestat_get(&uvwasi, fd, flags, path, path_len, &stat); - m3ApiReturn(ret); + WASI_TRACE("fd:%d, flags:0x%x, path:%s | fs.size:%d", fd, flags, path, stat.st_size); + + if (ret != UVWASI_ESUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 56); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+20, stat.st_nlink); + m3ApiWriteMem64(buf+24, stat.st_size); + m3ApiWriteMem64(buf+32, stat.st_atim); + m3ApiWriteMem64(buf+40, stat.st_mtim); + m3ApiWriteMem64(buf+48, stat.st_ctim); + + m3ApiReturn(UVWASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_snapshot_preview1_path_filestat_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (uvwasi_fd_t , fd) + m3ApiGetArg (uvwasi_lookupflags_t , flags) + m3ApiGetArgMem (const char * , path) + m3ApiGetArg (uint32_t , path_len) + m3ApiGetArgMem (uint8_t * , buf) + + m3ApiCheckMem(path, path_len); + m3ApiCheckMem(buf, 64); // wasi_filestat_t + + uvwasi_filestat_t stat; + + uvwasi_errno_t ret = uvwasi_path_filestat_get(&uvwasi, fd, flags, path, path_len, &stat); + + WASI_TRACE("fd:%d, flags:0x%x, path:%s | fs.size:%d", fd, flags, path, stat.st_size); + + if (ret != UVWASI_ESUCCESS) { + m3ApiReturn(ret); + } + + memset(buf, 0, 64); + m3ApiWriteMem64(buf+0, stat.st_dev); + m3ApiWriteMem64(buf+8, stat.st_ino); + m3ApiWriteMem8 (buf+16, stat.st_filetype); + m3ApiWriteMem64(buf+24, stat.st_nlink); + m3ApiWriteMem64(buf+32, stat.st_size); + m3ApiWriteMem64(buf+40, stat.st_atim); + m3ApiWriteMem64(buf+48, stat.st_mtim); + m3ApiWriteMem64(buf+56, stat.st_ctim); + + m3ApiReturn(UVWASI_ESUCCESS); } m3ApiRawFunction(m3_wasi_generic_fd_pread) @@ -445,15 +659,20 @@ m3ApiRawFunction(m3_wasi_generic_fd_pread) if (iovs_len > 128) m3ApiReturn(UVWASI_EINVAL); uvwasi_ciovec_t iovs[iovs_len]; #endif - uvwasi_size_t num_read; - uvwasi_errno_t ret; for (uvwasi_size_t i = 0; i < iovs_len; ++i) { iovs[i].buf = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); iovs[i].buf_len = m3ApiReadMem32(&wasi_iovs[i].buf_len); + + //fprintf(stderr, "> fd_pread fd:%d iov%d.len:%d\n", fd, i, iovs[i].buf_len); } - ret = uvwasi_fd_pread(&uvwasi, fd, (const uvwasi_iovec_t *) iovs, iovs_len, offset, &num_read); + uvwasi_size_t num_read; + + uvwasi_errno_t ret = uvwasi_fd_pread(&uvwasi, fd, (const uvwasi_iovec_t *) iovs, iovs_len, offset, &num_read); + + WASI_TRACE("fd:%d | nread:%d", fd, num_read); + m3ApiWriteMem32(nread, num_read); m3ApiReturn(ret); } @@ -482,9 +701,14 @@ m3ApiRawFunction(m3_wasi_generic_fd_read) for (uvwasi_size_t i = 0; i < iovs_len; ++i) { iovs[i].buf = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); iovs[i].buf_len = m3ApiReadMem32(&wasi_iovs[i].buf_len); + + //fprintf(stderr, "> fd_read fd:%d iov%d.len:%d\n", fd, i, iovs[i].buf_len); } ret = uvwasi_fd_read(&uvwasi, fd, (const uvwasi_iovec_t *) iovs, iovs_len, &num_read); + + WASI_TRACE("fd:%d | nread:%d", fd, num_read); + m3ApiWriteMem32(nread, num_read); m3ApiReturn(ret); } @@ -516,6 +740,9 @@ m3ApiRawFunction(m3_wasi_generic_fd_write) } ret = uvwasi_fd_write(&uvwasi, fd, iovs, iovs_len, &num_written); + + WASI_TRACE("fd:%d | nwritten:%d", fd, num_written); + m3ApiWriteMem32(nwritten, num_written); m3ApiReturn(ret); } @@ -535,6 +762,8 @@ m3ApiRawFunction(m3_wasi_generic_fd_readdir) uvwasi_size_t uvbufused; uvwasi_errno_t ret = uvwasi_fd_readdir(&uvwasi, fd, buf, buf_len, cookie, &uvbufused); + WASI_TRACE("fd:%d | bufused:%d", fd, uvbufused); + m3ApiWriteMem32(bufused, uvbufused); m3ApiReturn(ret); @@ -547,6 +776,8 @@ m3ApiRawFunction(m3_wasi_generic_fd_close) uvwasi_errno_t ret = uvwasi_fd_close(&uvwasi, fd); + WASI_TRACE("fd:%d", fd); + m3ApiReturn(ret); } @@ -557,6 +788,8 @@ m3ApiRawFunction(m3_wasi_generic_fd_datasync) uvwasi_errno_t ret = uvwasi_fd_datasync(&uvwasi, fd); + WASI_TRACE("fd:%d", fd); + m3ApiReturn(ret); } @@ -570,6 +803,8 @@ m3ApiRawFunction(m3_wasi_generic_random_get) uvwasi_errno_t ret = uvwasi_random_get(&uvwasi, buf, buf_len); + WASI_TRACE("len:%d", buf_len); + m3ApiReturn(ret); } @@ -583,6 +818,8 @@ m3ApiRawFunction(m3_wasi_generic_clock_res_get) uvwasi_errno_t ret = uvwasi_clock_res_get(&uvwasi, wasi_clk_id, resolution); + WASI_TRACE("clk_id:%d", wasi_clk_id); + //TODO: m3ApiWriteMem64 m3ApiReturn(ret); @@ -599,6 +836,8 @@ m3ApiRawFunction(m3_wasi_generic_clock_time_get) uvwasi_errno_t ret = uvwasi_clock_time_get(&uvwasi, wasi_clk_id, precision, time); + WASI_TRACE("clk_id:%d", wasi_clk_id); + //TODO: m3ApiWriteMem64 m3ApiReturn(ret); @@ -616,8 +855,12 @@ m3ApiRawFunction(m3_wasi_generic_poll_oneoff) m3ApiCheckMem(out, nsubscriptions * sizeof(uvwasi_event_t)); m3ApiCheckMem(nevents, sizeof(uvwasi_size_t)); + // TODO: unstable/snapshot_preview1 compatibility + uvwasi_errno_t ret = uvwasi_poll_oneoff(&uvwasi, in, out, nsubscriptions, nevents); + WASI_TRACE("nsubscriptions:%d | nevents:%d", nsubscriptions, *nevents); + //TODO: m3ApiWriteMem m3ApiReturn(ret); @@ -633,6 +876,8 @@ m3ApiRawFunction(m3_wasi_generic_proc_exit) context->exit_code = code; } + //TODO: fprintf(stderr, "proc_exit code:%d\n", code); + m3ApiTrap(m3Err_trapExit); } @@ -674,7 +919,7 @@ M3Result m3_LinkWASI (IM3Module module) uvwasi_preopen_t preopens[PREOPENS_COUNT]; preopens[0].mapped_path = "/"; preopens[0].real_path = "."; - preopens[1].mapped_path = "."; + preopens[1].mapped_path = "./"; preopens[1].real_path = "."; uvwasi_options_t init_options; @@ -700,8 +945,12 @@ M3Result m3_LinkWASI (IM3Module module) static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" }; // fd_seek is incompatible -_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_seek", "i(iIi*)", &m3_wasi_snapshot_preview1_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_seek", "i(iIi*)", &m3_wasi_snapshot_preview1_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "fd_filestat_get", "i(i*)", &m3_wasi_unstable_fd_filestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "fd_filestat_get", "i(i*)", &m3_wasi_snapshot_preview1_fd_filestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_unstable", "path_filestat_get", "i(ii*i*)", &m3_wasi_unstable_path_filestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1", "path_filestat_get", "i(ii*i*)", &m3_wasi_snapshot_preview1_path_filestat_get))); for (int i=0; i<2; i++) { @@ -721,7 +970,6 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_datasync", _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_get", "i(i*)", &m3_wasi_generic_fd_fdstat_get))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_flags", "i(ii)", &m3_wasi_generic_fd_fdstat_set_flags))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_rights", "i(iII)", ))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_get", "i(i*)", &m3_wasi_generic_fd_filestat_get))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_size", "i(iI)", ))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_times","i(iIIi)", ))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pread", "i(i*iI*)",&m3_wasi_generic_fd_pread))); @@ -736,7 +984,6 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_readdir", _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_write", "i(i*i*)", &m3_wasi_generic_fd_write))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_create_directory", "i(i*i)", &m3_wasi_generic_path_create_directory))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_get", "i(ii*i*)", &m3_wasi_generic_path_filestat_get))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_set_times", "i(ii*iIIi)", ))); //_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_link", "i(ii*ii*i)", ))); _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open", "i(ii*iiIIi*)", &m3_wasi_generic_path_open))); diff --git a/source/m3_api_wasi.c b/source/m3_api_wasi.c index 413d07e..c5698cc 100644 --- a/source/m3_api_wasi.c +++ b/source/m3_api_wasi.c @@ -83,8 +83,8 @@ Preopen preopen[PREOPEN_CNT] = { { 0, "" , "" }, { 1, "", "" }, { 2, "", "" }, - { -1, "./" , "." }, { -1, "/" , "." }, + { -1, "./" , "." }, }; #if defined(APE) @@ -293,7 +293,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_prestat_dir_name) m3ApiCheckMem(path, path_len); if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_ERRNO_BADF); } - size_t slen = strlen(preopen[fd].path); + size_t slen = strlen(preopen[fd].path) + 1; memcpy(path, preopen[fd].path, M3_MIN(slen, path_len)); m3ApiReturn(__WASI_ERRNO_SUCCESS); } @@ -302,13 +302,14 @@ m3ApiRawFunction(m3_wasi_generic_fd_prestat_get) { m3ApiReturnType (uint32_t) m3ApiGetArg (__wasi_fd_t , fd) - m3ApiGetArgMem (uint32_t * , buf) // TODO: use actual struct + m3ApiGetArgMem (uint8_t * , buf) - m3ApiCheckMem(buf, 2*sizeof(uint32_t)); + m3ApiCheckMem(buf, 8); if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_ERRNO_BADF); } - m3ApiWriteMem32(buf, __WASI_PREOPENTYPE_DIR); - m3ApiWriteMem32(buf+1, strlen(preopen[fd].path)); + + m3ApiWriteMem32(buf+0, __WASI_PREOPENTYPE_DIR); + m3ApiWriteMem32(buf+4, strlen(preopen[fd].path) + 1); m3ApiReturn(__WASI_ERRNO_SUCCESS); } @@ -499,7 +500,8 @@ m3ApiRawFunction(m3_wasi_generic_path_open) int flags = ((oflags & __WASI_OFLAGS_CREAT) ? _O_CREAT : 0) | ((oflags & __WASI_OFLAGS_EXCL) ? _O_EXCL : 0) | ((oflags & __WASI_OFLAGS_TRUNC) ? _O_TRUNC : 0) | - ((fs_flags & __WASI_FDFLAGS_APPEND) ? _O_APPEND : 0); + ((fs_flags & __WASI_FDFLAGS_APPEND) ? _O_APPEND : 0) | + _O_BINARY; if ((fs_rights_base & __WASI_RIGHTS_FD_READ) && (fs_rights_base & __WASI_RIGHTS_FD_WRITE)) { diff --git a/source/m3_compile.c b/source/m3_compile.c index ad12540..4ac321a 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -131,7 +131,7 @@ u8 GetStackTypeFromTop (IM3Compilation o, u16 i_offset) if (o->stackIndex >= i_offset) { u16 index = o->stackIndex - i_offset; - + if (index >= o->stackFirstDynamicIndex) type = o->typeStack [index]; } @@ -208,13 +208,13 @@ u16 GetSlotForStackIndex (IM3Compilation o, u16 i_stackIndex) u16 GetExtraSlotForStackIndex (IM3Compilation o, u16 i_stackIndex) { u16 baseSlot = GetSlotForStackIndex (o, i_stackIndex); - + if (baseSlot != c_slotUnused) { u16 extraSlot = GetTypeNumSlots (GetStackTypeFromBottom (o, i_stackIndex)) - 1; baseSlot += extraSlot; } - + return baseSlot; } @@ -233,9 +233,9 @@ void TouchSlot (IM3Compilation o, u16 i_slot) void MarkSlotAllocated (IM3Compilation o, u16 i_slot) { d_m3Assert (o->m3Slots [i_slot] == 0); // shouldn't be already allocated o->m3Slots [i_slot] = 1; - + o->slotMaxAllocatedIndexPlusOne = M3_MAX (o->slotMaxAllocatedIndexPlusOne, i_slot + 1); - + TouchSlot (o, i_slot); } @@ -723,7 +723,7 @@ void PatchBranches (IM3Compilation o) pc_t patches = o->block.patches; o->block.patches = NULL; - + while (patches) { m3log (compile, "patching location: %p to pc: %p", patches, pc); pc_t next = * (pc_t *) patches; @@ -895,20 +895,20 @@ M3Result GetBlockScope (IM3Compilation o, IM3CompilationScope * o_scope, i32 i M3Result CopyStackSlotsR (IM3Compilation o, u16 i_targetSlotStackIndex, u16 i_stackIndex, u16 i_endStackIndex, u16 i_tempSlot) { M3Result result = m3Err_none; - + if (i_stackIndex < i_endStackIndex) { u16 srcSlot = GetSlotForStackIndex (o, i_stackIndex); - + u8 type = GetStackTypeFromBottom (o, i_stackIndex); u16 numSlots = GetTypeNumSlots (type); u16 extraSlot = numSlots - 1; - + u16 targetSlot = GetSlotForStackIndex (o, i_targetSlotStackIndex); - + u16 preserveIndex = i_stackIndex; u16 collisionSlot = srcSlot; - + if (targetSlot != srcSlot) { // search for collisions @@ -917,7 +917,7 @@ M3Result CopyStackSlotsR (IM3Compilation o, u16 i_targetSlotStackIndex, u16 i_ { u16 otherSlot1 = GetSlotForStackIndex (o, checkIndex); u16 otherSlot2 = GetExtraSlotForStackIndex (o, checkIndex); - + if (targetSlot == otherSlot1 or targetSlot == otherSlot2 or targetSlot + extraSlot == otherSlot1) @@ -932,13 +932,13 @@ _ (CopyStackIndexToSlot (o, i_tempSlot, checkIndex)); // restore this on the way back down preserveIndex = checkIndex; collisionSlot = otherSlot1; - + break; } - + ++checkIndex; } - + _ (CopyStackIndexToSlot (o, targetSlot, i_stackIndex)); m3log (compile, " copying slot: %d to slot: %d", srcSlot, targetSlot); o->wasmStack [i_stackIndex] = targetSlot; @@ -950,7 +950,7 @@ _ (CopyStackSlotsR (o, i_targetSlotStackIndex + 1, i_stackIndex + 1, i_end o->wasmStack [i_stackIndex] = srcSlot; o->wasmStack [preserveIndex] = collisionSlot; } - + _catch: return result; } @@ -961,10 +961,10 @@ M3Result ResolveBlockResults (IM3Compilation o, IM3CompilationScope i_targetBl M3Result result = m3Err_none; if (d_m3LogWasmStack) dump_type_stack (o); bool isLoop = (i_targetBlock->opcode == c_waOp_loop and i_isBranch); - + u16 numParams = GetFuncTypeNumParams (i_targetBlock->type); u16 numResults = GetFuncTypeNumResults (i_targetBlock->type); - + u16 slotRecords = i_targetBlock->exitStackIndex; u16 numValues; @@ -975,21 +975,21 @@ M3Result ResolveBlockResults (IM3Compilation o, IM3CompilationScope i_targetBl slotRecords += numParams; } else numValues = numParams; - + u16 blockHeight = GetNumBlockValuesOnStack (o); - + _throwif (m3Err_typeCountMismatch, i_isBranch ? (blockHeight < numValues) : (blockHeight != numValues)); if (numValues) { u16 endIndex = GetStackTopIndex (o) + 1; - + if (not isLoop and IsFpType (GetStackTopType (o))) { _ (CopyStackTopToRegister (o, false)); --endIndex; } - + // TODO: tempslot affects maxStackSlots, so can grow unnecess each time. u16 tempSlot = o->maxStackSlots;// GetMaxUsedSlotPlusOne (o); doesn't work cause can collide with slotRecords AlignSlotToType (& tempSlot, c_m3Type_i64); @@ -998,7 +998,7 @@ _ (CopyStackSlotsR (o, slotRecords, endIndex - numValues, endIndex, tempSl if (d_m3LogWasmStack) dump_type_stack (o); } - + _catch: return result; } @@ -1023,12 +1023,12 @@ M3Result ReturnValues (IM3Compilation o, IM3CompilationScope i_functionBlock, for (u16 i = 0; i < numReturns; ++i) { u8 returnType = GetFuncTypeResultType (i_functionBlock->type, numReturns - 1 - i); - + u8 stackType = GetStackTypeFromTop (o, i); // using FromTop so that only dynamic items are checked - + if (IsStackPolymorphic (o) and stackType == c_m3Type_none) stackType = returnType; - + _throwif (m3Err_typeMismatch, returnType != stackType); if (not IsStackPolymorphic (o)) @@ -1037,7 +1037,7 @@ M3Result ReturnValues (IM3Compilation o, IM3CompilationScope i_functionBlock, _ (CopyStackIndexToSlot (o, returnSlot, stackTop--)); } } - + if (not i_isBranch) { while (numReturns--) @@ -1134,11 +1134,11 @@ M3Result Compile_Return (IM3Compilation o, m3opcode_t i_opcode) { IM3CompilationScope functionScope; _ (GetBlockScope (o, & functionScope, o->block.depth)); - + _ (ReturnValues (o, functionScope, true)); - + _ (EmitOp (o, op_Return)); - + _ (SetStackPolymorphic (o)); } @@ -1152,7 +1152,7 @@ M3Result ValidateBlockEnd (IM3Compilation o) /* u16 numResults = GetFuncTypeNumResults (o->block.type); u16 blockHeight = GetNumBlockValuesOnStack (o); - + if (IsStackPolymorphic (o)) { } @@ -1179,7 +1179,7 @@ M3Result Compile_End (IM3Compilation o, m3opcode_t i_opcode) { _ (ReturnValues (o, & o->block, false)); } - + _ (EmitOp (o, op_Return)); } } @@ -1342,9 +1342,9 @@ _ (GetBlockScope (o, & scope, depth)); _ (EmitOp (o, op)); _ (EmitSlotNumOfStackTopAndPop (o)); - + pc_t * jumpTo = (pc_t *) ReservePointer (o); - + _ (ResolveBlockResults (o, scope, /* isBranch: */ true)); _ (EmitOp (o, op_ContinueLoop)); @@ -1357,11 +1357,11 @@ _ (EmitOp (o, op_ContinueLoop)); // move the condition to a register _ (CopyStackTopToRegister (o, false)); _ (PopType (o, c_m3Type_i32)); - + _ (EmitOp (o, op_ContinueLoopIf)); EmitPointer (o, scope->pc); } - + // dump_type_stack(o); } else // is c_waOp_branch @@ -1374,7 +1374,7 @@ _ (EmitOp (o, op_ContinueLoopIf)); else // forward branch { pc_t * jumpTo = NULL; - + bool isReturn = (scope->depth == 0); bool targetHasResults = GetFuncTypeNumResults (scope->type); @@ -1386,7 +1386,7 @@ _ (EmitOp (o, op_ContinueLoopIf)); _ (EmitOp (o, op)); _ (EmitSlotNumOfStackTopAndPop (o)); // condition - + // this is continuation point, if the branch isn't taken jumpTo = (pc_t *) ReservePointer (o); } @@ -1396,12 +1396,12 @@ _ (EmitOp (o, op_ContinueLoopIf)); _ (EmitOp (o, op)); _ (EmitSlotNumOfStackTopAndPop (o)); // condition - + EmitPatchingBranchPointer (o, scope); goto _catch; } } - + if (not IsStackPolymorphic (o)) { if (isReturn) @@ -1415,12 +1415,12 @@ _ (ResolveBlockResults (o, scope, true)); _ (EmitPatchingBranch (o, scope)); } } - + if (jumpTo) { * jumpTo = GetPC (o); } - + if (i_opcode == c_waOp_branch) _ (SetStackPolymorphic (o)); } @@ -1552,7 +1552,7 @@ _ (Pop (o)); _ (Push (o, type, topSlot)); MarkSlotsAllocatedByType (o, topSlot, type); - + topSlot += c_ioSlotCount; } @@ -1678,7 +1678,7 @@ static M3Result ReadBlockType (IM3Compilation o, IM3FuncType * o_blockType) { M3Result result; - + i64 type; _ (ReadLebSigned (& type, 33, & o->wasm, o->wasmEnd)); @@ -1756,7 +1756,7 @@ _ (ReadBlockType (o, & blockType)); { u16 slot = GetSlotForStackIndex (o, i); u8 type = GetStackTypeFromBottom (o, i); - + if (IsConstantSlot (o, slot)) { u16 newSlot; @@ -1767,7 +1767,7 @@ _ (CopyStackIndexToSlot (o, newSlot, i)); } } } - + _ (EmitOp (o, op_Loop)); } else @@ -1785,7 +1785,7 @@ M3Result CompileElseBlock (IM3Compilation o, pc_t * o_startPC, IM3FuncType i_b M3Result result; _try { - + IM3CodePage elsePage; _ (AcquireCompilationCodePage (o, & elsePage)); @@ -1811,15 +1811,15 @@ _ (EmitOp (o, op_Branch)); M3Result Compile_If (IM3Compilation o, m3opcode_t i_opcode) { M3Result result; - + /* [ op_If ] [ ] ----> [ ..else.. ] [ ..if.. ] [ ..block.. ] [ ..block.. ] [ op_Branch ] [ end ] <----- [ ] */ - + _try { - + _ (PreserveNonTopRegisters (o)); _ (PreserveArgsAndLocals (o)); @@ -1832,11 +1832,11 @@ _ (EmitSlotNumOfStackTopAndPop (o)); IM3FuncType blockType; _ (ReadBlockType (o, & blockType)); - + // dump_type_stack (o); - + u16 stackIndex = o->stackIndex; - + _ (CompileBlock (o, blockType, i_opcode)); if (o->previousOpcode == c_waOp_else) @@ -2463,13 +2463,13 @@ _catch: M3Result PushBlockResults (IM3Compilation o) { M3Result result = m3Err_none; - + u16 numResults = GetFuncTypeNumResults (o->block.type); for (u16 i = 0; i < numResults; ++i) { u8 type = GetFuncTypeResultType (o->block.type, i); - + if (i == numResults - 1 and IsFpType (type)) { _ (PushRegister (o, type)); @@ -2505,7 +2505,7 @@ M3Result CompileBlock (IM3Compilation o, IM3FuncType i_blockType, m3opcode_t i (deallocated) and the stack top is readjusted to keep these records in pace. This allows branch instructions to find their result landing pads. Finally, the params are copied from the "dead" records and pushed back onto the stack as active stack items for the CompileBlockStatements () call. - + [ block ] [ params ] ------------------ @@ -2516,14 +2516,14 @@ M3Result CompileBlock (IM3Compilation o, IM3FuncType i_blockType, m3opcode_t i [ records ] <----- exitStackIndex */ - + _try { // validate and dealloc params ---------------------------- - + u16 stackIndex = o->stackIndex; - + u16 numParams = GetFuncTypeNumParams (i_blockType); - + if (i_blockOpcode != c_waOp_else) { for (u16 i = 0; i < numParams; ++i) @@ -2549,9 +2549,9 @@ _ (PopType (o, type)); u16 numResults = GetFuncTypeNumResults (i_blockType); while (numResults--) Pop (o); - + block->blockStackIndex = o->stackIndex = stackIndex; - + // push the params back onto the stack ------------------- for (u16 i = 0; i < numParams; ++i) { @@ -2559,13 +2559,13 @@ _ (PopType (o, type)); u16 slot = GetSlotForStackIndex (o, paramIndex + i); Push (o, type, slot); - + if (slot >= o->slotFirstDynamicIndex) MarkSlotsAllocatedByType (o, slot, type); } //-------------------------------------------------------- - + _ (CompileBlockStatements (o)); _ (ValidateBlockEnd (o)); @@ -2574,7 +2574,7 @@ _ (ValidateBlockEnd (o)); { if (not IsStackPolymorphic (o)) _ (ResolveBlockResults (o, & o->block, /* isBranch: */ false)); - + _ (UnwindBlockStack (o)) if (not ((i_blockOpcode == c_waOp_if and numResults) or o->previousOpcode == c_waOp_else)) @@ -2634,7 +2634,7 @@ M3Result ReserveConstants (IM3Compilation o) numConstantSlots += 1; else if (code == c_waOp_i64_const or code == c_waOp_f64_const) numConstantSlots += GetTypeNumSlots (c_m3Type_i64); - + if (numConstantSlots >= d_m3MaxConstantTableSize) break; } @@ -2658,7 +2658,7 @@ M3Result ReserveConstants (IM3Compilation o) M3Result CompileFunction (IM3Function io_function) { M3Result result = m3Err_none; - + if (!io_function->wasm) return "function body is missing"; IM3FuncType funcType = io_function->funcType; m3log (compile, "compiling: [%d] %s %s; wasm-size: %d", diff --git a/source/m3_emit.c b/source/m3_emit.c index 9c1e9fa..4a96a75 100644 --- a/source/m3_emit.c +++ b/source/m3_emit.c @@ -90,10 +90,10 @@ void EmitSlotOffset (IM3Compilation o, const i32 i_offset) pc_t EmitPointer (IM3Compilation o, const void * const i_pointer) { pc_t ptr = GetPagePC (o->page); - + if (o->page) EmitWord (o->page, i_pointer); - + return ptr; } diff --git a/source/m3_info.c b/source/m3_info.c index 17e27ac..53710db 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -357,17 +357,17 @@ void dump_type_stack (IM3Compilation o) for (u32 p = 1; p <= 2; ++p) { d_m3Log(stack, " "); - + for (u32 i = 0; i < o->stackIndex; ++i) { if (i > 0 and i == o->stackFirstDynamicIndex) printf ("#"); - + if (i == o->block.blockStackIndex) printf (">"); - + const char * type = c_waCompactTypes [o->typeStack [i]]; - + const char * location = ""; i32 slot = o->wasmStack [i]; @@ -394,7 +394,7 @@ void dump_type_stack (IM3Compilation o) } char item [100]; - + if (slot >= 0) sprintf (item, "%s%s%d", type, location, slot); else @@ -403,22 +403,22 @@ void dump_type_stack (IM3Compilation o) if (p == 1) { size_t s = strlen (item); - + sprintf (item, "%d", i); - + while (strlen (item) < s) strcat (item, " "); } - + printf ("|%s ", item); - + } printf ("\n"); } // for (u32 r = 0; r < 2; ++r) // d_m3Assert (regAllocated [r] == 0); // reg allocation & stack out of sync - + u16 maxSlot = GetMaxUsedSlotPlusOne (o); if (maxSlot > o->slotFirstDynamicIndex) diff --git a/test/run-spec-test.py b/test/run-spec-test.py index 03d6b8f..fdd9e51 100755 --- a/test/run-spec-test.py +++ b/test/run-spec-test.py @@ -49,7 +49,7 @@ from pprint import pprint parser = argparse.ArgumentParser() parser.add_argument("--exec", metavar="", default="../build/wasm3 --repl") -parser.add_argument("--spec", default="v1.1") +parser.add_argument("--spec", default="opam-1.1.1") parser.add_argument("--timeout", type=int, default=30) parser.add_argument("--line", metavar="", type=int) parser.add_argument("--all", action="store_true") diff --git a/test/run-wasi-test.py b/test/run-wasi-test.py index f789e79..9773b1e 100755 --- a/test/run-wasi-test.py +++ b/test/run-wasi-test.py @@ -65,7 +65,11 @@ commands_full = [ "args": ["16", "64"], "expect_sha1": "d85df3561eb15f6f0e6f20d5640e8e1306222c6d" }, { - "skip": True, # TODO + "name": "smallpt (explicit light sampling, multi-value)", + "wasm": "./wasi/smallpt/smallpt-ex-mv.wasm", + "args": ["16", "64"], + "expect_sha1": "d85df3561eb15f6f0e6f20d5640e8e1306222c6d" + }, { "name": "mal", "wasm": "./wasi/mal/mal.wasm", "args": ["./wasi/mal/test-fib.mal", "16"], @@ -127,7 +131,11 @@ commands_fast = [ "args": ["4", "32"], "expect_sha1": "ea05d85998b2f453b588ef76a1256215bf9b851c" }, { - "skip": True, # TODO + "name": "smallpt (explicit light sampling, multi-value)", + "wasm": "./wasi/smallpt/smallpt-ex-mv.wasm", + "args": ["4", "32"], + "expect_sha1": "ea05d85998b2f453b588ef76a1256215bf9b851c" + }, { "name": "mal", "wasm": "./wasi/mal/mal.wasm", "args": ["./wasi/mal/test-fib.mal", "16"], diff --git a/test/wasi/mal/.gitattributes b/test/wasi/mal/.gitattributes new file mode 100644 index 0000000..f1a8064 --- /dev/null +++ b/test/wasi/mal/.gitattributes @@ -0,0 +1 @@ +*.mal binary diff --git a/test/wasi/smallpt/smallpt-ex-mv.wasm b/test/wasi/smallpt/smallpt-ex-mv.wasm new file mode 100644 index 0000000..1c2de15 Binary files /dev/null and b/test/wasi/smallpt/smallpt-ex-mv.wasm differ