From facbe9aa5d0ba5cf85d6989631053abec764f576 Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Wed, 21 Sep 2022 15:26:01 -0700 Subject: [PATCH 01/10] Turn on uvwasi for compiled apps in build. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c443fbfc7..3f1d0ae35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ endif () option(BUILD_TESTS "Build GTest-based tests" ON) option(USE_SYSTEM_GTEST "Use system GTest, instead of building" OFF) option(BUILD_TOOLS "Build wabt commandline tools" ON) +option(BUILD_UVWASI "Build uvwasi for use by compiled applications" ON) option(BUILD_FUZZ_TOOLS "Build tools that can repro fuzz bugs" OFF) option(BUILD_LIBWASM "Build libwasm" ON) option(USE_ASAN "Use address sanitizer" OFF) @@ -353,6 +354,7 @@ set(WABT_LIBRARY_SRC add_library(wabt STATIC ${WABT_LIBRARY_SRC}) add_library(wabt::wabt ALIAS wabt) + target_compile_features(wabt PUBLIC cxx_std_17) if (WABT_INSTALL_RULES) @@ -395,6 +397,10 @@ IF (NOT WIN32) endif () endif () +if (BUILD_UVWASI) + add_subdirectory("third_party/uvwasi" ) +endif () + if (BUILD_FUZZ_TOOLS) set(FUZZ_FLAGS "-fsanitize=fuzzer,address") add_library(wabt-fuzz STATIC ${WABT_LIBRARY_SRC}) From 21091684b6b79d282552a959ae31455317aae1d5 Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Wed, 21 Sep 2022 15:30:56 -0700 Subject: [PATCH 02/10] uvwasi runtime bindings. --- wasm2c/uvwasi-rt.c | 588 +++++++++++++++++++++++++++++++++++++++++++++ wasm2c/uvwasi-rt.h | 15 ++ 2 files changed, 603 insertions(+) create mode 100644 wasm2c/uvwasi-rt.c create mode 100644 wasm2c/uvwasi-rt.h diff --git a/wasm2c/uvwasi-rt.c b/wasm2c/uvwasi-rt.c new file mode 100644 index 000000000..162fd03ff --- /dev/null +++ b/wasm2c/uvwasi-rt.c @@ -0,0 +1,588 @@ +#include +#include +#include +#include + +#include "wasm-rt.h" +#include "uvwasi.h" +#include "uvwasi-rt.h" + +typedef uint8_t u8; +typedef int8_t s8; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint32_t u32; +typedef int32_t s32; +typedef uint64_t u64; +typedef int64_t s64; +typedef float f32; +typedef double f64; + +#ifndef WASM_RT_MODULE_PREFIX +#define WASM_RT_MODULE_PREFIX +#endif + +#define WASM_RT_PASTE_(x, y) x ## y +#define WASM_RT_PASTE(x, y) WASM_RT_PASTE_(x, y) +#define WASM_RT_ADD_PREFIX(x) WASM_RT_PASTE(WASM_RT_MODULE_PREFIX, x) + +#define IMPORT_IMPL(ret, name, params, body) ret name params body + +#define IMPORT_IMPL_WASI_UNSTABLE(ret, name, params, body) IMPORT_IMPL(ret, Z_wasi_unstable##name, params, body) +#define IMPORT_IMPL_WASI_PREVIEW1(ret, name, params, body) IMPORT_IMPL(ret, Z_wasi_snapshot_preview1##name, params, body) + +#define IMPORT_IMPL_WASI_ALL(ret, name, params, body) \ + IMPORT_IMPL_WASI_UNSTABLE(ret, name, params, body) \ + IMPORT_IMPL_WASI_PREVIEW1(ret, name, params, body) + +#define MEMACCESS(addr) ((void*)&WASM_RT_ADD_PREFIX(wp->instance_memory->data[(addr)])) + +#define MEM_SET(addr, value, len) memset(MEMACCESS(addr), value, len) +#define MEM_WRITE8(addr, value) (*(u8*) MEMACCESS(addr)) = value +#define MEM_WRITE16(addr, value) (*(u16*)MEMACCESS(addr)) = value +#define MEM_WRITE32(addr, value) (*(u32*)MEMACCESS(addr)) = value +#define MEM_WRITE64(addr, value) (*(u64*)MEMACCESS(addr)) = value + +#define MEM_READ32(addr) (*(u32*)MEMACCESS(addr)) +#define READ32(x) (*(u32*)(x)) + +// XXX TODO: Add linear memory boundary checks + + + +typedef u32 wasm_ptr; + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_prestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf), +{ + uvwasi_prestat_t prestat; + uvwasi_errno_t ret = uvwasi_fd_prestat_get(wp->uvwasi, fd, &prestat); + if (ret == UVWASI_ESUCCESS) { + MEM_WRITE32(buf+0, prestat.pr_type); + MEM_WRITE32(buf+4, prestat.u.dir.pr_name_len); + } + return ret; +}); + + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_prestat_dir_name, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +{ + uvwasi_errno_t ret = uvwasi_fd_prestat_dir_name(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_environ_sizes_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env_count, wasm_ptr env_buf_size), +{ + uvwasi_size_t uvcount; + uvwasi_size_t uvbufsize; + uvwasi_errno_t ret = uvwasi_environ_sizes_get(wp->uvwasi, &uvcount, &uvbufsize); + if (ret == UVWASI_ESUCCESS) { + MEM_WRITE32(env_count, uvcount); + MEM_WRITE32(env_buf_size, uvbufsize); + } + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_environ_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env, wasm_ptr buf), +{ + uvwasi_size_t uvcount; + uvwasi_size_t uvbufsize; + uvwasi_errno_t ret; + ret = uvwasi_environ_sizes_get(wp->uvwasi, &uvcount, &uvbufsize); + if (ret != UVWASI_ESUCCESS) { + return ret; + } + + // TODO XXX: check mem + + char** uvenv = calloc(uvcount, sizeof(char*)); + if (uvenv == NULL) { + return UVWASI_ENOMEM; + } + + ret = uvwasi_environ_get(wp->uvwasi, uvenv, (char*)MEMACCESS(buf)); + if (ret != UVWASI_ESUCCESS) { + free(uvenv); + return ret; + } + + for (u32 i = 0; i < uvcount; ++i) + { + uint32_t offset = buf + (uvenv[i] - uvenv[0]); + MEM_WRITE32(env+(i*sizeof(wasm_ptr)), offset); + } + + free(uvenv); + + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_args_sizes_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argc, wasm_ptr argv_buf_size), +{ + uvwasi_size_t uvcount; + uvwasi_size_t uvbufsize; + uvwasi_errno_t ret = uvwasi_args_sizes_get(wp->uvwasi, &uvcount, &uvbufsize); + if (ret == UVWASI_ESUCCESS) { + MEM_WRITE32(argc, uvcount); + MEM_WRITE32(argv_buf_size, uvbufsize); + } + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_args_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argv, wasm_ptr buf), +{ + uvwasi_size_t uvcount; + uvwasi_size_t uvbufsize; + uvwasi_errno_t ret; + ret = uvwasi_args_sizes_get(wp->uvwasi, &uvcount, &uvbufsize); + if (ret != UVWASI_ESUCCESS) { + return ret; + } + + // TODO XXX: check mem + + char** uvarg = calloc(uvcount, sizeof(char*)); + if (uvarg == NULL) { + return UVWASI_ENOMEM; + } + + ret = uvwasi_args_get(wp->uvwasi, uvarg, (char*)MEMACCESS(buf)); + if (ret != UVWASI_ESUCCESS) { + free(uvarg); + return ret; + } + + for (u32 i = 0; i < uvcount; ++i) + { + uint32_t offset = buf + (uvarg[i] - uvarg[0]); + MEM_WRITE32(argv+(i*sizeof(wasm_ptr)), offset); + } + + free(uvarg); + + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat), +{ + uvwasi_fdstat_t uvstat; + uvwasi_errno_t ret = uvwasi_fd_fdstat_get(wp->uvwasi, fd, &uvstat); + if (ret == UVWASI_ESUCCESS) { + MEM_SET(stat, 0, 24); + MEM_WRITE8 (stat+0, uvstat.fs_filetype); + MEM_WRITE16(stat+2, uvstat.fs_flags); + MEM_WRITE64(stat+8, uvstat.fs_rights_base); + MEM_WRITE64(stat+16, uvstat.fs_rights_inheriting); + } + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_set_flags, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags), +{ + uvwasi_errno_t ret = uvwasi_fd_fdstat_set_flags(wp->uvwasi, fd, flags); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_set_rights, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 fs_rights_base, u64 fs_rights_inheriting), +{ + uvwasi_errno_t ret = uvwasi_fd_fdstat_set_rights(wp->uvwasi, fd, fs_rights_base, fs_rights_inheriting); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_filestat_set_times, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, u64 atim, u64 mtim, u32 fst_flags), +{ + uvwasi_errno_t ret = uvwasi_path_filestat_set_times(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, atim, mtim, fst_flags); + return ret; +}); + + + +IMPORT_IMPL_WASI_UNSTABLE(u32, Z_path_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, wasm_ptr stat), +{ + uvwasi_filestat_t uvstat; + uvwasi_errno_t ret = uvwasi_path_filestat_get(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, &uvstat); + if (ret == UVWASI_ESUCCESS) { + MEM_SET(stat, 0, 56); + MEM_WRITE64(stat+0, uvstat.st_dev); + MEM_WRITE64(stat+8, uvstat.st_ino); + MEM_WRITE8 (stat+16, uvstat.st_filetype); + MEM_WRITE32(stat+20, uvstat.st_nlink); + MEM_WRITE64(stat+24, uvstat.st_size); + MEM_WRITE64(stat+32, uvstat.st_atim); + MEM_WRITE64(stat+40, uvstat.st_mtim); + MEM_WRITE64(stat+48, uvstat.st_ctim); + } + return ret; +}); + +IMPORT_IMPL_WASI_PREVIEW1(u32, Z_path_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, wasm_ptr stat), +{ + uvwasi_filestat_t uvstat; + uvwasi_errno_t ret = uvwasi_path_filestat_get(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, &uvstat); + if (ret == UVWASI_ESUCCESS) { + MEM_SET(stat, 0, 64); + MEM_WRITE64(stat+0, uvstat.st_dev); + MEM_WRITE64(stat+8, uvstat.st_ino); + MEM_WRITE8 (stat+16, uvstat.st_filetype); + MEM_WRITE64(stat+24, uvstat.st_nlink); + MEM_WRITE64(stat+32, uvstat.st_size); + MEM_WRITE64(stat+40, uvstat.st_atim); + MEM_WRITE64(stat+48, uvstat.st_mtim); + MEM_WRITE64(stat+56, uvstat.st_ctim); + } + return ret; +}); + +IMPORT_IMPL_WASI_UNSTABLE(u32, Z_fd_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat), +{ + uvwasi_filestat_t uvstat; + uvwasi_errno_t ret = uvwasi_fd_filestat_get(wp->uvwasi, fd, &uvstat); + if (ret == UVWASI_ESUCCESS) { + MEM_SET(stat, 0, 56); + MEM_WRITE64(stat+0, uvstat.st_dev); + MEM_WRITE64(stat+8, uvstat.st_ino); + MEM_WRITE8 (stat+16, uvstat.st_filetype); + MEM_WRITE32(stat+20, uvstat.st_nlink); + MEM_WRITE64(stat+24, uvstat.st_size); + MEM_WRITE64(stat+32, uvstat.st_atim); + MEM_WRITE64(stat+40, uvstat.st_mtim); + MEM_WRITE64(stat+48, uvstat.st_ctim); + } + return ret; +}); + +IMPORT_IMPL_WASI_PREVIEW1(u32, Z_fd_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat), +{ + uvwasi_filestat_t uvstat; + uvwasi_errno_t ret = uvwasi_fd_filestat_get(wp->uvwasi, fd, &uvstat); + if (ret == UVWASI_ESUCCESS) { + MEM_SET(stat, 0, 64); + MEM_WRITE64(stat+0, uvstat.st_dev); + MEM_WRITE64(stat+8, uvstat.st_ino); + MEM_WRITE8 (stat+16, uvstat.st_filetype); + MEM_WRITE64(stat+24, uvstat.st_nlink); + MEM_WRITE64(stat+32, uvstat.st_size); + MEM_WRITE64(stat+40, uvstat.st_atim); + MEM_WRITE64(stat+48, uvstat.st_mtim); + MEM_WRITE64(stat+56, uvstat.st_ctim); + } + return ret; +}); + + +IMPORT_IMPL_WASI_UNSTABLE(u32, Z_fd_seek, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u32 wasi_whence, wasm_ptr pos), +{ + uvwasi_whence_t whence = -1; + switch (wasi_whence) { + case 0: whence = UVWASI_WHENCE_CUR; break; + case 1: whence = UVWASI_WHENCE_END; break; + case 2: whence = UVWASI_WHENCE_SET; break; + } + + uvwasi_filesize_t uvpos; + uvwasi_errno_t ret = uvwasi_fd_seek(wp->uvwasi, fd, offset, whence, &uvpos); + MEM_WRITE64(pos, uvpos); + return ret; +}); + +IMPORT_IMPL_WASI_PREVIEW1(u32, Z_fd_seek, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u32 wasi_whence, wasm_ptr pos), +{ + uvwasi_whence_t whence = -1; + switch (wasi_whence) { + case 0: whence = UVWASI_WHENCE_SET; break; + case 1: whence = UVWASI_WHENCE_CUR; break; + case 2: whence = UVWASI_WHENCE_END; break; + } + + uvwasi_filesize_t uvpos; + uvwasi_errno_t ret = uvwasi_fd_seek(wp->uvwasi, fd, offset, whence, &uvpos); + MEM_WRITE64(pos, uvpos); + return ret; +}); + + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_tell, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr pos), +{ + uvwasi_filesize_t uvpos; + uvwasi_errno_t ret = uvwasi_fd_tell(wp->uvwasi, fd, &uvpos); + MEM_WRITE64(pos, uvpos); + return ret; +}); + + + + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_filestat_set_size, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 filesize), +{ + uvwasi_errno_t ret = uvwasi_fd_filestat_set_size(wp->uvwasi, fd, filesize); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_filestat_set_times, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 atim, u64 mtim, u32 fst_flags), +{ + uvwasi_errno_t ret = uvwasi_fd_filestat_set_times(wp->uvwasi, fd, atim, mtim, fst_flags); + return ret; +}); + + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_sync, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd), +{ + uvwasi_errno_t ret = uvwasi_fd_sync(wp->uvwasi, fd); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_datasync, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd), +{ + uvwasi_errno_t ret = uvwasi_fd_datasync(wp->uvwasi, fd); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_renumber, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd_from, u32 fd_to), +{ + uvwasi_errno_t ret = uvwasi_fd_renumber(wp->uvwasi, fd_from, fd_to); + return ret; +}); + + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_allocate, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len), +{ + uvwasi_errno_t ret = uvwasi_fd_allocate(wp->uvwasi, fd, offset, len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_advise, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len, u32 advice), +{ + uvwasi_errno_t ret = uvwasi_fd_advise(wp->uvwasi, fd, offset, len, advice); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_open, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 dirfd, u32 dirflags, + wasm_ptr path, u32 path_len, + u32 oflags, u64 fs_rights_base, u64 fs_rights_inheriting, + u32 fs_flags, wasm_ptr fd), +{ + uvwasi_fd_t uvfd; + uvwasi_errno_t ret = uvwasi_path_open(wp->uvwasi, + dirfd, + dirflags, + (char*)MEMACCESS(path), + path_len, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + &uvfd); + MEM_WRITE32(fd, uvfd); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_close, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd), { + uvwasi_errno_t ret = uvwasi_fd_close(wp->uvwasi, fd); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_symlink, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr old_path, u32 old_path_len, u32 fd, + wasm_ptr new_path, u32 new_path_len), +{ + uvwasi_errno_t ret = uvwasi_path_symlink(wp->uvwasi, (char*)MEMACCESS(old_path), old_path_len, + fd, (char*)MEMACCESS(new_path), new_path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_rename, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, wasm_ptr old_path, u32 old_path_len, + u32 new_fd, wasm_ptr new_path, u32 new_path_len), +{ + uvwasi_errno_t ret = uvwasi_path_rename(wp->uvwasi, old_fd, (char*)MEMACCESS(old_path), old_path_len, + new_fd, (char*)MEMACCESS(new_path), new_path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_link, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, u32 old_flags, wasm_ptr old_path, u32 old_path_len, + u32 new_fd, wasm_ptr new_path, u32 new_path_len), +{ + uvwasi_errno_t ret = uvwasi_path_link(wp->uvwasi, old_fd, old_flags, (char*)MEMACCESS(old_path), old_path_len, + new_fd, (char*)MEMACCESS(new_path), new_path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_unlink_file, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +{ + uvwasi_errno_t ret = uvwasi_path_unlink_file(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_readlink, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len, + wasm_ptr buf, u32 buf_len, wasm_ptr bufused), +{ + uvwasi_size_t uvbufused; + uvwasi_errno_t ret = uvwasi_path_readlink(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len, MEMACCESS(buf), buf_len, &uvbufused); + + MEM_WRITE32(bufused, uvbufused); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_create_directory, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +{ + uvwasi_errno_t ret = uvwasi_path_create_directory(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_path_remove_directory, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +{ + uvwasi_errno_t ret = uvwasi_path_remove_directory(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_readdir, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf, u32 buf_len, u64 cookie, wasm_ptr bufused), +{ + uvwasi_size_t uvbufused; + uvwasi_errno_t ret = uvwasi_fd_readdir(wp->uvwasi, fd, MEMACCESS(buf), buf_len, cookie, &uvbufused); + MEM_WRITE32(bufused, uvbufused); + return ret; +}); + +typedef struct wasi_iovec_t +{ + uvwasi_size_t buf; + uvwasi_size_t buf_len; +} wasi_iovec_t; + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_write, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nwritten), +{ + wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); + +#if defined(_MSC_VER) + if (iovs_len > 32) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[32]; +#else + if (iovs_len > 128) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[iovs_len]; +#endif + for (uvwasi_size_t i = 0; i < iovs_len; ++i) { + iovs[i].buf = MEMACCESS(READ32(&wasi_iovs[i].buf)); + iovs[i].buf_len = READ32(&wasi_iovs[i].buf_len); + } + + uvwasi_size_t num_written; + uvwasi_errno_t ret = uvwasi_fd_write(wp->uvwasi, fd, iovs, iovs_len, &num_written); + MEM_WRITE32(nwritten, num_written); + return ret; +}); + + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_pwrite, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nwritten), +{ + wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); + +#if defined(_MSC_VER) + if (iovs_len > 32) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[32]; +#else + if (iovs_len > 128) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[iovs_len]; +#endif + for (uvwasi_size_t i = 0; i < iovs_len; ++i) { + iovs[i].buf = MEMACCESS(READ32(&wasi_iovs[i].buf)); + iovs[i].buf_len = READ32(&wasi_iovs[i].buf_len); + } + + uvwasi_size_t num_written; + uvwasi_errno_t ret = uvwasi_fd_pwrite(wp->uvwasi, fd, iovs, iovs_len, offset, &num_written); + MEM_WRITE32(nwritten, num_written); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_read, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nread), +{ + wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); + +#if defined(_MSC_VER) + if (iovs_len > 32) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[32]; +#else + if (iovs_len > 128) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[iovs_len]; +#endif + + for (uvwasi_size_t i = 0; i < iovs_len; ++i) { + iovs[i].buf = MEMACCESS(READ32(&wasi_iovs[i].buf)); + iovs[i].buf_len = READ32(&wasi_iovs[i].buf_len); + } + + uvwasi_size_t num_read; + uvwasi_errno_t ret = uvwasi_fd_read(wp->uvwasi, fd, (const uvwasi_iovec_t *)iovs, iovs_len, &num_read); + MEM_WRITE32(nread, num_read); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_fd_pread, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nread), +{ + wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); + +#if defined(_MSC_VER) + if (iovs_len > 32) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[32]; +#else + if (iovs_len > 128) return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[iovs_len]; +#endif + + for (uvwasi_size_t i = 0; i < iovs_len; ++i) { + iovs[i].buf = MEMACCESS(READ32(&wasi_iovs[i].buf)); + iovs[i].buf_len = READ32(&wasi_iovs[i].buf_len); + } + + uvwasi_size_t num_read; + uvwasi_errno_t ret = uvwasi_fd_pread(wp->uvwasi, fd, (const uvwasi_iovec_t *)iovs, iovs_len, offset, &num_read); + MEM_WRITE32(nread, num_read); + return ret; +}); + +// TODO XXX: unstable/snapshot_preview1 compatibility +IMPORT_IMPL_WASI_ALL(u32, Z_poll_oneoff, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr in, wasm_ptr out, u32 nsubscriptions, wasm_ptr nevents), +{ + uvwasi_size_t uvnevents; + uvwasi_errno_t ret = uvwasi_poll_oneoff(wp->uvwasi, MEMACCESS(in), MEMACCESS(out), nsubscriptions, &uvnevents); + MEM_WRITE32(nevents, uvnevents); + return ret; +}); + + +IMPORT_IMPL_WASI_ALL(u32, Z_clock_res_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, wasm_ptr result), +{ + uvwasi_timestamp_t t; + uvwasi_errno_t ret = uvwasi_clock_res_get(wp->uvwasi, clk_id, &t); + MEM_WRITE64(result, t); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_clock_time_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, u64 precision, wasm_ptr result), +{ + uvwasi_timestamp_t t; + uvwasi_errno_t ret = uvwasi_clock_time_get(wp->uvwasi, clk_id, precision, &t); + MEM_WRITE64(result, t); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_random_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr buf, u32 buf_len), +{ + uvwasi_errno_t ret = uvwasi_random_get(wp->uvwasi, MEMACCESS(buf), buf_len); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_sched_yield, (struct Z_wasi_snapshot_preview1_instance_t* wp), +{ + uvwasi_errno_t ret = uvwasi_sched_yield(wp->uvwasi); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(u32, Z_proc_raise, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 sig), +{ + uvwasi_errno_t ret = uvwasi_proc_raise(wp->uvwasi, sig); + return ret; +}); + +IMPORT_IMPL_WASI_ALL(void, Z_proc_exit, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 code), +{ + uvwasi_destroy(wp->uvwasi); + exit(code); +}); diff --git a/wasm2c/uvwasi-rt.h b/wasm2c/uvwasi-rt.h new file mode 100644 index 000000000..652cfe3ca --- /dev/null +++ b/wasm2c/uvwasi-rt.h @@ -0,0 +1,15 @@ +#ifndef UVWASI_RT_H +#define UVWASI_RT_H + +#include "uvwasi.h" +#include "wasm-rt.h" + +struct Z_wasi_snapshot_preview1_instance_t { + uvwasi_t * uvwasi; + wasm_rt_memory_t * instance_memory; +}; + +#endif + + + From 716760c782eabedcd6d301a86843e7ff7e9370d9 Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Wed, 21 Sep 2022 15:43:52 -0700 Subject: [PATCH 03/10] Simple example that exercises uvwasi functionality. --- wasm2c/examples/hello-wasi/Makefile | 37 ++++++++++ wasm2c/examples/hello-wasi/TODO | 2 + wasm2c/examples/hello-wasi/hello.c | 34 +++++++++ wasm2c/examples/hello-wasi/uvwasi-rt-main.c | 76 +++++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 wasm2c/examples/hello-wasi/Makefile create mode 100644 wasm2c/examples/hello-wasi/TODO create mode 100644 wasm2c/examples/hello-wasi/hello.c create mode 100644 wasm2c/examples/hello-wasi/uvwasi-rt-main.c diff --git a/wasm2c/examples/hello-wasi/Makefile b/wasm2c/examples/hello-wasi/Makefile new file mode 100644 index 000000000..d4e6e23ef --- /dev/null +++ b/wasm2c/examples/hello-wasi/Makefile @@ -0,0 +1,37 @@ +#assumes wasi-sdk installed system wide in default location +WASI_SDK_ROOT=/opt/wasi-sdk +WABT_ROOT=../../.. + +WASI_CLANG=$(WASI_SDK_ROOT)/bin/clang +WASI_SYSROOT=$(WASI_SDK_ROOT)/share/wasi-sysroot + +#CFLAGS for compiling files to place nice with wasm2c +WASM_CFLAGS=-Wl,--export-all -Wl,--no-entry -Wl,--growable-table -Wl,--stack-first -Wl,-z,stack-size=1048576 + + +WASM2C=$(WABT_ROOT)/bin/wasm2c + +WASM2C_RUNTIME_PATH=$(WABT_ROOT)/wasm2c/ +WASM2C_RUNTIME_FILES=$(addprefix $(WASM2C_RUNTIME_PATH), wasm-rt-impl.c uvwasi-rt.c) + +UVWASI_PATH=$(WABT_ROOT)/third_party/uvwasi + +DEPS=-I$(UVWASI_PATH)/include -L$(WABT_ROOT)/build/_deps/libuv-build -L$(WABT_ROOT)/build/third_party/uvwasi + +LIBS=-luvwasi_a -luv_a -lpthread -ldl -lm + +ALL_RESULTS=hello.wasm hello.wasm.c hello.elf + +all: $(ALL_RESULTS) + +clean: + rm -rf $(ALL_RESULTS) hello.wasm.h *.o + +hello.wasm: hello.c + $(WASI_CLANG) --sysroot $(WASI_SYSROOT) $(WASM_CFLAGS) hello.c -o hello.wasm + +hello.wasm.c: hello.wasm + $(WASM2C) hello.wasm -o hello.wasm.c + +hello.elf: hello.wasm.c uvwasi-rt-main.c $(WASM2C_RUNTIME_FILES) + $(CC) -g hello.wasm.c uvwasi-rt-main.c -o hello.elf -I$(WASM2C_RUNTIME_PATH) $(WASM2C_RUNTIME_FILES) $(DEPS) $(LIBS) diff --git a/wasm2c/examples/hello-wasi/TODO b/wasm2c/examples/hello-wasi/TODO new file mode 100644 index 000000000..4fe06a748 --- /dev/null +++ b/wasm2c/examples/hello-wasi/TODO @@ -0,0 +1,2 @@ +-address any XXX or TODO lines +-make sure linear memory accesses are bounded checked diff --git a/wasm2c/examples/hello-wasi/hello.c b/wasm2c/examples/hello-wasi/hello.c new file mode 100644 index 000000000..4781fd3f5 --- /dev/null +++ b/wasm2c/examples/hello-wasi/hello.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +int main(int argc, char * argv[]) { + + printf("printing args\n"); + for (int i = 0; i < argc ; i++) { + printf("[%d] %s \n", i, argv[i]); + } + + printf("Writing to stdout\n"); + char * hello_str = strdup("hello world!"); + puts(hello_str); + + printf("writing test.out\n"); + FILE * fp = fopen("test.out", "w+"); + assert(fp != NULL); + fprintf(fp,"hello filesystem\n"); + fclose(fp); + printf("removing test.out\n"); + assert(!unlink("test.out")); + + printf("writing /tmp/test.out\n"); + fp = fopen("/tmp/test.out", "w+"); + assert(fp != NULL); + fprintf(fp,"hello filesystem\n"); + fclose(fp); + printf("removing /tmp/test.out\n"); + assert(!unlink("/tmp/test.out")); + + return 0; +} diff --git a/wasm2c/examples/hello-wasi/uvwasi-rt-main.c b/wasm2c/examples/hello-wasi/uvwasi-rt-main.c new file mode 100644 index 000000000..d62b475c1 --- /dev/null +++ b/wasm2c/examples/hello-wasi/uvwasi-rt-main.c @@ -0,0 +1,76 @@ +/* Link this with wasm2c output and uvwasi runtime to build a standalone app */ +#include +#include +#include "uvwasi.h" +#include "uvwasi-rt.h" + +#define MODULE_NAME hello +#define MODULE_HEADER "hello.wasm.h" +#include MODULE_HEADER + +//force pre-processor expansion of m_name +#define __module_init(m_name) Z_## m_name ##_init_module() +#define module_init(m_name) __module_init(m_name) + +#define __module_instantiate(m_name, instance_p, wasi_p) Z_## m_name ##_instantiate(instance_p, wasi_p) +#define module_instantiate(m_name ,instance_p, wasi_p) __module_instantiate(m_name ,instance_p, wasi_p) + +#define __module_free(m_name, instance_p) Z_## m_name ##_free(instance_p) +#define module_free(m_name, instance_p) __module_free(m_name, instance_p) + +#define __module_start(m_name, instance_p) Z_ ## m_name ## Z__start(instance_p) +#define module_start(m_name, instance_p) __module_start(m_name, instance_p) + +int main(int argc, const char** argv) +{ + Z_hello_instance_t local_instance; + uvwasi_t local_uvwasi_state; + + struct Z_wasi_snapshot_preview1_instance_t wasi_state = { + .uvwasi = &local_uvwasi_state, + .instance_memory = &local_instance.w2c_memory + }; + + uvwasi_options_t init_options; + + //pass in standard descriptors + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; + init_options.fd_table_size = 3; + + //pass in args and environement + extern const char ** environ; + init_options.argc = argc; + init_options.argv = argv; + init_options.envp = (const char **) environ; + + //no sandboxing enforced, binary has access to everything user does + init_options.preopenc = 2; + init_options.preopens = calloc(2, sizeof(uvwasi_preopen_t)); + + init_options.preopens[0].mapped_path = "/"; + init_options.preopens[0].real_path = "/"; + init_options.preopens[1].mapped_path = "./"; + init_options.preopens[1].real_path = "."; + + init_options.allocator = NULL; + + wasm_rt_init(); + uvwasi_errno_t ret = uvwasi_init(&local_uvwasi_state, &init_options); + + if (ret != UVWASI_ESUCCESS) { + printf("uvwasi_init failed with error %d\n", ret); + exit(1); + } + + module_init(MODULE_NAME); + module_instantiate(MODULE_NAME, &local_instance, (struct Z_wasi_snapshot_preview1_instance_t *) &wasi_state); + module_start(MODULE_NAME, &local_instance); + module_free(MODULE_NAME, &local_instance); + + uvwasi_destroy(&local_uvwasi_state); + wasm_rt_free(); + + return 0; +} From f22d786aff6b5b0397216bd3f0240de330b238ce Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Wed, 21 Sep 2022 16:00:09 -0700 Subject: [PATCH 04/10] script to build aribitrary wasm file into stand-alone application. --- wasm2c/examples/build-standlone/Makefile | 27 +++++++ wasm2c/examples/build-standlone/build.sh | 24 ++++++ .../build-standlone/examples/hello.wasm | Bin 0 -> 57634 bytes .../examples/build-standlone/uvwasi-rt-main.c | 76 ++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 wasm2c/examples/build-standlone/Makefile create mode 100755 wasm2c/examples/build-standlone/build.sh create mode 100755 wasm2c/examples/build-standlone/examples/hello.wasm create mode 100644 wasm2c/examples/build-standlone/uvwasi-rt-main.c diff --git a/wasm2c/examples/build-standlone/Makefile b/wasm2c/examples/build-standlone/Makefile new file mode 100644 index 000000000..44e6ed5b0 --- /dev/null +++ b/wasm2c/examples/build-standlone/Makefile @@ -0,0 +1,27 @@ +WABT_ROOT=../../.. +WASM2C=$(WABT_ROOT)/bin/wasm2c + +WASM2C_RUNTIME_PATH=$(WABT_ROOT)/wasm2c/ +WASM2C_RUNTIME_FILES=$(addprefix $(WASM2C_RUNTIME_PATH), wasm-rt-impl.c uvwasi-rt.c) + +UVWASI_PATH=$(WABT_ROOT)/third_party/uvwasi + +DEPS=-I$(UVWASI_PATH)/include -L$(WABT_ROOT)/build/_deps/libuv-build -L$(WABT_ROOT)/build/third_party/uvwasi + +LIBS=-luvwasi_a -luv_a -lpthread -ldl -lm + +DBG_FLAGS=-g +REL_FLAGS=-O3 -flto -fomit-frame-pointer -fno-stack-protector + +CFLAGS=$(REL_FLAGS) + +all: input.elf + +clean: + rm -rf $(ALL_RESULTS) input.* + +input.c: + $(WASM2C) input.wasm -o input.c + +input.elf: input.c uvwasi-rt-main.c $(WASM2C_RUNTIME_FILES) + $(CC) $(CFLAGS) input.c uvwasi-rt-main.c -o input.elf -I$(WASM2C_RUNTIME_PATH) $(WASM2C_RUNTIME_FILES) $(DEPS) $(LIBS) diff --git a/wasm2c/examples/build-standlone/build.sh b/wasm2c/examples/build-standlone/build.sh new file mode 100755 index 000000000..af64b5f86 --- /dev/null +++ b/wasm2c/examples/build-standlone/build.sh @@ -0,0 +1,24 @@ +#!/usr/bin/bash +if [ -z "$1" ] + then + echo "Compiles wasm file into standalone binary" + echo "usage: build.sh foo.wasm" + echo "outputs: foo.elf" + exit +fi + +ORIGIN_DIR=$(pwd) +SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +output_file=$(basename -- "$1") +output_file="${output_file%%.*}.elf" + +set -v + +cd $SCRIPT_DIR +make clean + +cp ${ORIGIN_DIR}/$1 ./input.wasm +make input.c + +make input.elf +cp -f input.elf ${ORIGIN_DIR}/${output_file} diff --git a/wasm2c/examples/build-standlone/examples/hello.wasm b/wasm2c/examples/build-standlone/examples/hello.wasm new file mode 100755 index 0000000000000000000000000000000000000000..65c9441963a36d786fceaf58ab31ad217aa9297a GIT binary patch literal 57634 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%0A(gBEcs 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 +#include +#include "uvwasi.h" +#include "uvwasi-rt.h" + +#define MODULE_NAME input +#define MODULE_HEADER "input.h" +#include MODULE_HEADER + +//force pre-processor expansion of m_name +#define __module_init(m_name) Z_## m_name ##_init_module() +#define module_init(m_name) __module_init(m_name) + +#define __module_instantiate(m_name, instance_p, wasi_p) Z_## m_name ##_instantiate(instance_p, wasi_p) +#define module_instantiate(m_name ,instance_p, wasi_p) __module_instantiate(m_name ,instance_p, wasi_p) + +#define __module_free(m_name, instance_p) Z_## m_name ##_free(instance_p) +#define module_free(m_name, instance_p) __module_free(m_name, instance_p) + +#define __module_start(m_name, instance_p) Z_ ## m_name ## Z__start(instance_p) +#define module_start(m_name, instance_p) __module_start(m_name, instance_p) + +int main(int argc, const char** argv) +{ + Z_input_instance_t local_instance; + uvwasi_t local_uvwasi_state; + + struct Z_wasi_snapshot_preview1_instance_t wasi_state = { + .uvwasi = &local_uvwasi_state, + .instance_memory = &local_instance.w2c_memory + }; + + uvwasi_options_t init_options; + + //pass in standard descriptors + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; + init_options.fd_table_size = 3; + + //pass in args and environement + extern const char ** environ; + init_options.argc = argc; + init_options.argv = argv; + init_options.envp = (const char **) environ; + + //no sandboxing enforced, binary has access to everything user does + init_options.preopenc = 2; + init_options.preopens = calloc(2, sizeof(uvwasi_preopen_t)); + + init_options.preopens[0].mapped_path = "/"; + init_options.preopens[0].real_path = "/"; + init_options.preopens[1].mapped_path = "./"; + init_options.preopens[1].real_path = "."; + + init_options.allocator = NULL; + + wasm_rt_init(); + uvwasi_errno_t ret = uvwasi_init(&local_uvwasi_state, &init_options); + + if (ret != UVWASI_ESUCCESS) { + printf("uvwasi_init failed with error %d\n", ret); + exit(1); + } + + module_init(MODULE_NAME); + module_instantiate(MODULE_NAME, &local_instance, (struct Z_wasi_snapshot_preview1_instance_t *) &wasi_state); + module_start(MODULE_NAME, &local_instance); + module_free(MODULE_NAME, &local_instance); + + uvwasi_destroy(&local_uvwasi_state); + wasm_rt_free(); + + return 0; +} From a03de93f124e1b06b6b38bbb2eaa0f050d0748d8 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Tue, 20 Sep 2022 22:59:47 -0700 Subject: [PATCH 05/10] wasm2c: implement the bulk memory operations proposal (#1877) Co-authored-by: Yuhan Deng --- README.md | 2 +- scripts/gen-wasm2c-templates.cmake | 3 +- src/c-writer.cc | 297 ++- src/template/wasm2c.declarations.c | 81 + src/template/wasm2c.includes.c | 1 + src/tools/wasm2c.cc | 1 - test/run-spec-wasm2c.py | 4 + .../bulk-memory-operations/imports.txt | 607 ++++++ .../bulk-memory-operations/linking.txt | 399 ++++ .../bulk-memory-operations/table_copy.txt | 1599 +++++++++++++++ .../bulk-memory-operations/table_init.txt | 1780 +++++++++++++++++ test/wasm2c/old-spec/elem.txt | 447 ----- test/wasm2c/spec/bulk.txt | 5 + test/wasm2c/spec/elem.txt | 5 + test/wasm2c/spec/memory_copy.txt | 5 + test/wasm2c/spec/memory_fill.txt | 5 + test/wasm2c/spec/memory_init.txt | 5 + test/wasm2c/spec/multi-memory/load.txt | 6 + test/wasm2c/spec/multi-memory/store.txt | 6 + wasm2c/examples/fac/fac.c | 109 +- wasm2c/wasm-rt.h | 4 +- 21 files changed, 4844 insertions(+), 527 deletions(-) create mode 100644 test/wasm2c/old-spec/bulk-memory-operations/imports.txt create mode 100644 test/wasm2c/old-spec/bulk-memory-operations/linking.txt create mode 100644 test/wasm2c/old-spec/bulk-memory-operations/table_copy.txt create mode 100644 test/wasm2c/old-spec/bulk-memory-operations/table_init.txt delete mode 100644 test/wasm2c/old-spec/elem.txt create mode 100644 test/wasm2c/spec/bulk.txt create mode 100644 test/wasm2c/spec/elem.txt create mode 100644 test/wasm2c/spec/memory_copy.txt create mode 100644 test/wasm2c/spec/memory_fill.txt create mode 100644 test/wasm2c/spec/memory_init.txt create mode 100644 test/wasm2c/spec/multi-memory/load.txt create mode 100644 test/wasm2c/spec/multi-memory/store.txt diff --git a/README.md b/README.md index 7a1aa00ad..b616a2c30 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Wabt has been compiled to JavaScript via emscripten. Some of the functionality i | [threads][] | `--enable-threads` | | ✓ | ✓ | ✓ | ✓ | | | [multi-value][] | `--disable-multi-value` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [tail-call][] | `--enable-tail-call` | | ✓ | ✓ | ✓ | ✓ | | -| [bulk memory][] | `--disable-bulk-memory` | ✓ | ✓ | ✓ | ✓ | ✓ | | +| [bulk memory][] | `--disable-bulk-memory` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [reference types][] | `--disable-reference-types` | ✓ | ✓ | ✓ | ✓ | ✓ | | | [annotations][] | `--enable-annotations` | | | ✓ | | | | | [memory64][] | `--enable-memory64` | | ✓ | ✓ | ✓ | ✓ | | diff --git a/scripts/gen-wasm2c-templates.cmake b/scripts/gen-wasm2c-templates.cmake index 99a61d039..3fc387f95 100644 --- a/scripts/gen-wasm2c-templates.cmake +++ b/scripts/gen-wasm2c-templates.cmake @@ -1,4 +1,5 @@ # https://stackoverflow.com/a/47801116 file(READ ${in} content) -set(content "const char* ${symbol} = R\"w2c_template(${content})w2c_template\";") +string(REGEX REPLACE "(.[^\n]*\n)" "R\"w2c_template(\\1)w2c_template\"\n" content "${content}") +set(content "const char* ${symbol} = ${content};") file(WRITE ${out} "${content}") diff --git a/src/c-writer.cc b/src/c-writer.cc index 0c201b12f..1270b716b 100644 --- a/src/c-writer.cc +++ b/src/c-writer.cc @@ -278,6 +278,8 @@ class CWriter { void WriteTables(); void WriteTable(const std::string&); void WriteTablePtr(const std::string&); + void WriteDataInstances(); + void WriteElemInstances(); void WriteGlobalInitializers(); void WriteDataInitializers(); void WriteElemInitializers(); @@ -996,6 +998,7 @@ void CWriter::WriteFuncTypes() { Writef("static u32 func_types[%" PRIzd "];", module_->types.size()); Write(Newline()); } + Write(Newline()); Write("static void init_func_types(void) ", OpenBrace()); if (!module_->types.size()) { Write(CloseBrace(), Newline()); @@ -1285,6 +1288,8 @@ void CWriter::WriteModuleInstance() { WriteGlobals(); WriteMemories(); WriteTables(); + WriteDataInstances(); + WriteElemInstances(); // C forbids an empty struct if (module_->globals.empty() && module_->memories.empty() && @@ -1382,24 +1387,38 @@ void CWriter::WriteGlobalInitializers() { } ++global_index; } - Write(CloseBrace(), Newline()); + Write(CloseBrace(), Newline(), Newline()); } -void CWriter::WriteDataInitializers() { - const Memory* memory = nullptr; - Index data_segment_index = 0; +static inline bool is_droppable(const DataSegment* data_segment) { + return (data_segment->kind == SegmentKind::Passive) && + (!data_segment->data.empty()); +} + +static inline bool is_droppable(const ElemSegment* elem_segment) { + return (elem_segment->kind == SegmentKind::Passive) && + (!elem_segment->elem_exprs.empty()); +} +void CWriter::WriteDataInstances() { + for (const DataSegment* data_segment : module_->data_segments) { + DefineGlobalScopeName(data_segment->name); + if (is_droppable(data_segment)) { + Write("bool ", "data_segment_dropped_", GetGlobalName(data_segment->name), + " : 1;", Newline()); + } + } +} + +void CWriter::WriteDataInitializers() { if (!module_->memories.empty()) { if (module_->data_segments.empty()) { Write(Newline()); } else { for (const DataSegment* data_segment : module_->data_segments) { - if (!data_segment->data.size()) { - Write(Newline(), "static const u8* data_segment_data_", - data_segment_index, " = NULL;", Newline()); - } else { + if (data_segment->data.size()) { Write(Newline(), "static const u8 data_segment_data_", - data_segment_index, "[] = ", OpenBrace()); + GetGlobalName(data_segment->name), "[] = ", OpenBrace()); size_t i = 0; for (uint8_t x : data_segment->data) { Writef("0x%02x, ", x); @@ -1410,11 +1429,8 @@ void CWriter::WriteDataInitializers() { Write(Newline()); Write(CloseBrace(), ";", Newline()); } - ++data_segment_index; } } - - memory = module_->memories[0]; } Write("static void init_memory(", ModuleInstanceTypeName(), "* instance) ", @@ -1422,83 +1438,140 @@ void CWriter::WriteDataInitializers() { if (module_->memories.size() > module_->num_memory_imports) { Index memory_idx = module_->num_memory_imports; for (Index i = memory_idx; i < module_->memories.size(); i++) { - memory = module_->memories[i]; + const Memory* memory = module_->memories[i]; uint32_t max = memory->page_limits.has_max ? memory->page_limits.max : 65536; Write("wasm_rt_allocate_memory(", ExternalInstancePtr(memory->name), ", ", memory->page_limits.initial, ", ", max, ");", Newline()); } } - data_segment_index = 0; for (const DataSegment* data_segment : module_->data_segments) { + if (data_segment->kind != SegmentKind::Active) { + continue; + } + const Memory* memory = + module_->memories[module_->GetMemoryIndex(data_segment->memory_var)]; Write("LOAD_DATA(", ExternalInstanceRef(memory->name), ", "); WriteInitExpr(data_segment->offset); - Write(", data_segment_data_", data_segment_index, ", ", - data_segment->data.size()); + if (data_segment->data.empty()) { + Write(", NULL, 0"); + } else { + Write(", data_segment_data_", GetGlobalName(data_segment->name), ", ", + data_segment->data.size()); + } Write(");", Newline()); - ++data_segment_index; } Write(CloseBrace(), Newline()); + + Write(Newline(), "static void init_data_instances(", ModuleInstanceTypeName(), + " *instance) ", OpenBrace()); + + for (const DataSegment* data_segment : module_->data_segments) { + if (is_droppable(data_segment)) { + Write("instance->data_segment_dropped_", + GetGlobalName(data_segment->name), " = false;", Newline()); + } + } + + Write(CloseBrace(), Newline()); +} + +void CWriter::WriteElemInstances() { + for (const ElemSegment* elem_segment : module_->elem_segments) { + DefineGlobalScopeName(elem_segment->name); + if (is_droppable(elem_segment)) { + Write("bool ", "elem_segment_dropped_", GetGlobalName(elem_segment->name), + " : 1;", Newline()); + } + } } void CWriter::WriteElemInitializers() { - Write(Newline(), "static void init_table(", ModuleInstanceTypeName(), - "* instance) ", OpenBrace()); + for (const ElemSegment* elem_segment : module_->elem_segments) { + if (elem_segment->elem_exprs.empty()) { + continue; + } - if (!module_->types.size()) { - // If there are no types there cannot be any table entries either. - for (const ElemSegment* elem_segment : module_->elem_segments) { - assert(elem_segment->elem_exprs.size() == 0); + Write(Newline(), + "static const wasm_elem_segment_expr_t elem_segment_exprs_", + GetGlobalName(elem_segment->name), "[] = ", OpenBrace()); + + for (const ExprList& elem_expr : elem_segment->elem_exprs) { + assert(elem_expr.size() == 1); + const Expr& expr = elem_expr.front(); + switch (expr.type()) { + case ExprType::RefFunc: { + const Func* func = module_->GetFunc(cast(&expr)->var); + const Index func_type_index = + module_->GetFuncTypeIndex(func->decl.type_var); + Write("{", func_type_index, ", "); + Write("(wasm_rt_funcref_t)", ExternalPtr(func->name), ", "); + const bool is_import = import_module_sym_map_.count(func->name) != 0; + if (is_import) { + Write("offsetof(", ModuleInstanceTypeName(), ", ", + MangleModuleInstanceName(import_module_sym_map_[func->name]), + ")"); + } else { + Write("0"); + } + Write("}, ", Newline()); + } break; + case ExprType::RefNull: + Write("{0, NULL, 0}, ", Newline()); + break; + default: + WABT_UNREACHABLE; + } } - Write(CloseBrace(), Newline()); - return; + Write(CloseBrace(), ";", Newline()); } + + Write(Newline(), "static void init_table(", ModuleInstanceTypeName(), + "* instance) ", OpenBrace()); + const Table* table = module_->tables.empty() ? nullptr : module_->tables[0]; - Write("uint32_t offset;", Newline()); if (table && module_->num_table_imports == 0) { uint32_t max = table->elem_limits.has_max ? table->elem_limits.max : UINT32_MAX; Write("wasm_rt_allocate_table(", ExternalInstancePtr(table->name), ", ", table->elem_limits.initial, ", ", max, ");", Newline()); } - Index elem_segment_index = 0; for (const ElemSegment* elem_segment : module_->elem_segments) { - if (elem_segment->kind == SegmentKind::Passive) { + if (elem_segment->kind != SegmentKind::Active) { continue; } - Write("offset = "); + + Write("table_init(", ExternalInstancePtr(table->name), ", "); + if (elem_segment->elem_exprs.empty()) { + Write("NULL, 0, "); + } else { + Write("elem_segment_exprs_", GetGlobalName(elem_segment->name), ", ", + elem_segment->elem_exprs.size(), ", "); + } WriteInitExpr(elem_segment->offset); - Write(";", Newline()); + if (elem_segment->elem_exprs.empty()) { + // It's mandatory to handle the case of a zero-length elem segment + // (even in a module with no types). This must trap if the offset + // is out of bounds. + Write(", 0, 0, instance, NULL);", Newline()); + } else { + Write(", 0, ", elem_segment->elem_exprs.size(), + ", instance, func_types);", Newline()); + } + } - size_t i = 0; - for (const ExprList& elem_expr : elem_segment->elem_exprs) { - // We don't support the bulk-memory proposal here, so we know that we - // don't have any passive segments (where ref.null can be used). - assert(elem_expr.size() == 1); - const Expr* expr = &elem_expr.front(); - assert(expr->type() == ExprType::RefFunc); - const Func* func = module_->GetFunc(cast(expr)->var); - Index func_type_index = module_->GetFuncTypeIndex(func->decl.type_var); - - bool is_import = import_module_sym_map_.count(func->name) != 0; - if (is_import) { - Write(ExternalInstanceRef(table->name), ".data[offset + ", i, - "] = (wasm_rt_elem_t){func_types[", func_type_index, - "], (wasm_rt_funcref_t)", ExternalPtr(func->name), - ", (void*)(instance->", - MangleModuleInstanceName(import_module_sym_map_[func->name]), - ")};", Newline()); - } else { - Write(ExternalInstanceRef(table->name), ".data[offset + ", i, - "] = (wasm_rt_elem_t){func_types[", func_type_index, - "], (wasm_rt_funcref_t)", ExternalPtr(func->name), - ", (void*)instance};", Newline()); - } - ++i; + Write(CloseBrace(), Newline()); + + Write(Newline(), "static void init_elem_instances(", ModuleInstanceTypeName(), + " *instance) ", OpenBrace()); + + for (const ElemSegment* elem_segment : module_->elem_segments) { + if (is_droppable(elem_segment)) { + Write("instance->elem_segment_dropped_", + GetGlobalName(elem_segment->name), " = false;", Newline()); } - ++elem_segment_index; } Write(CloseBrace(), Newline()); @@ -1652,6 +1725,8 @@ void CWriter::WriteInit() { Write("init_globals(instance);", Newline()); Write("init_memory(instance);", Newline()); Write("init_table(instance);", Newline()); + Write("init_data_instances(instance);", Newline()); + Write("init_elem_instances(instance);", Newline()); for (Var* var : module_->starts) { Write(ExternalRef(module_->GetFunc(*var)->name)); bool is_import = @@ -1715,8 +1790,7 @@ void CWriter::WriteFree() { Write(Newline(), "void " + module_prefix_ + "_free(", ModuleInstanceTypeName(), "* instance) ", OpenBrace()); - if (module_->types.size()) { - // If there are no types there cannot be any table entries either. + { assert(module_->tables.size() <= 1); Index table_index = 0; for (const Table* table : module_->tables) { @@ -2340,13 +2414,104 @@ void CWriter::Write(const ExprList& exprs) { break; } - case ExprType::MemoryCopy: - case ExprType::DataDrop: - case ExprType::MemoryInit: - case ExprType::MemoryFill: - case ExprType::TableCopy: - case ExprType::ElemDrop: - case ExprType::TableInit: + case ExprType::MemoryFill: { + const auto inst = cast(&expr); + Memory* memory = + module_->memories[module_->GetMemoryIndex(inst->memidx)]; + Write("memory_fill(", ExternalInstancePtr(memory->name), ", ", + StackVar(2), ", ", StackVar(1), ", ", StackVar(0), ");", + Newline()); + DropTypes(3); + } break; + + case ExprType::MemoryCopy: { + const auto inst = cast(&expr); + Memory* dest_memory = + module_->memories[module_->GetMemoryIndex(inst->destmemidx)]; + const Memory* src_memory = module_->GetMemory(inst->srcmemidx); + Write("memory_copy(", ExternalInstancePtr(dest_memory->name), ", ", + ExternalInstancePtr(src_memory->name), ", ", StackVar(2), ", ", + StackVar(1), ", ", StackVar(0), ");", Newline()); + DropTypes(3); + } break; + + case ExprType::MemoryInit: { + const auto inst = cast(&expr); + Memory* dest_memory = + module_->memories[module_->GetMemoryIndex(inst->memidx)]; + const DataSegment* src_data = module_->GetDataSegment(inst->var); + Write("memory_init(", ExternalInstancePtr(dest_memory->name), ", "); + if (src_data->data.empty()) { + Write("NULL, 0"); + } else { + Write("data_segment_data_", GetGlobalName(src_data->name), ", "); + if (is_droppable(src_data)) { + Write("(", "instance->data_segment_dropped_", + GetGlobalName(src_data->name), + " ? 0 : ", src_data->data.size(), ")"); + } else { + Write("0"); + } + } + + Write(", ", StackVar(2), ", ", StackVar(1), ", ", StackVar(0), ");", + Newline()); + DropTypes(3); + } break; + + case ExprType::TableInit: { + const auto inst = cast(&expr); + Table* dest_table = + module_->tables[module_->GetTableIndex(inst->table_index)]; + const ElemSegment* src_segment = + module_->GetElemSegment(inst->segment_index); + Write("table_init(", ExternalInstancePtr(dest_table->name), ", "); + if (src_segment->elem_exprs.empty()) { + Write("NULL, 0"); + } else { + Write("elem_segment_exprs_", GetGlobalName(src_segment->name), ", "); + if (is_droppable(src_segment)) { + Write("(instance->elem_segment_dropped_", + GetGlobalName(src_segment->name), + " ? 0 : ", src_segment->elem_exprs.size(), ")"); + } else { + Write("0"); + } + } + + Write(", ", StackVar(2), ", ", StackVar(1), ", ", StackVar(0)); + Write(", instance, func_types);", Newline()); + DropTypes(3); + } break; + + case ExprType::DataDrop: { + const auto inst = cast(&expr); + const DataSegment* data = module_->GetDataSegment(inst->var); + if (is_droppable(data)) { + Write("instance->data_segment_dropped_", GetGlobalName(data->name), + " = true;", Newline()); + } + } break; + + case ExprType::ElemDrop: { + const auto inst = cast(&expr); + const ElemSegment* seg = module_->GetElemSegment(inst->var); + if (is_droppable(seg)) { + Write("instance->elem_segment_dropped_", GetGlobalName(seg->name), + " = true;", Newline()); + } + } break; + + case ExprType::TableCopy: { + const auto inst = cast(&expr); + Table* dest_table = + module_->tables[module_->GetTableIndex(inst->dst_table)]; + const Table* src_table = module_->GetTable(inst->src_table); + Write("table_copy(", ExternalInstancePtr(dest_table->name), ", ", + ExternalInstancePtr(src_table->name), ", ", StackVar(2), ", ", + StackVar(1), ", ", StackVar(0), ");", Newline()); + } break; + case ExprType::TableGet: case ExprType::TableSet: case ExprType::TableGrow: @@ -3180,10 +3345,10 @@ void CWriter::WriteCSource() { WriteTagTypes(); WriteTags(); WriteFuncDeclarations(); - WriteFuncs(); WriteGlobalInitializers(); WriteDataInitializers(); WriteElemInitializers(); + WriteFuncs(); WriteExports(WriteExportsKind::Definitions); WriteInitInstanceImport(); WriteInit(); diff --git a/src/template/wasm2c.declarations.c b/src/template/wasm2c.declarations.c index 4459790f7..8e1e1d3cb 100644 --- a/src/template/wasm2c.declarations.c +++ b/src/template/wasm2c.declarations.c @@ -444,4 +444,85 @@ static float wasm_sqrtf(float x) { return sqrtf(x); } +static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { + RANGE_CHECK(mem, d, n); + memset(mem->data + d, val, n); +} + +static inline void memory_copy(wasm_rt_memory_t* dest, + const wasm_rt_memory_t* src, + u32 dest_addr, + u32 src_addr, + u32 n) { + RANGE_CHECK(dest, dest_addr, n); + RANGE_CHECK(src, src_addr, n); + memmove(dest->data + dest_addr, src->data + src_addr, n); +} + +static inline void memory_init(wasm_rt_memory_t* dest, + const u8* src, + u32 src_size, + u32 dest_addr, + u32 src_addr, + u32 n) { + if (UNLIKELY(src_addr + (uint64_t)n > src_size)) + TRAP(OOB); + LOAD_DATA((*dest), dest_addr, src + src_addr, n); +} + +typedef struct { + uint32_t func_type_index; + wasm_rt_funcref_t func; + size_t module_offset; +} wasm_elem_segment_expr_t; + +static inline void table_init(wasm_rt_table_t* dest, + const wasm_elem_segment_expr_t* src, + u32 src_size, + u32 dest_addr, + u32 src_addr, + u32 n, + void* module_instance, + const u32* func_types) { + if (UNLIKELY(src_addr + (uint64_t)n > src_size)) + TRAP(OOB); + if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) + TRAP(OOB); + for (u32 i = 0; i < n; i++) { + const wasm_elem_segment_expr_t* src_expr = &src[src_addr + i]; + dest->data[dest_addr + i] = + (wasm_rt_elem_t){func_types[src_expr->func_type_index], src_expr->func, + (char*)module_instance + src_expr->module_offset}; + } +} + +static inline void table_copy(wasm_rt_table_t* dest, + const wasm_rt_table_t* src, + u32 dest_addr, + u32 src_addr, + u32 n) { + if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) + TRAP(OOB); + if (UNLIKELY(src_addr + (uint64_t)n > src->size)) + TRAP(OOB); + + if (n == 0) { + return; + } + + if (dest->data + dest_addr == src->data + src_addr) { + return; + } + + if (dest->data + dest_addr < src->data + src_addr) { + for (u32 i = 0; i < n; i++) { + dest->data[dest_addr + i] = src->data[src_addr + i]; + } + } else { + for (u32 i = n; i > 0; i--) { + dest->data[dest_addr + i - 1] = src->data[src_addr + i - 1]; + } + } +} + static bool s_module_initialized = false; diff --git a/src/template/wasm2c.includes.c b/src/template/wasm2c.includes.c index 59def29c8..d89a94752 100644 --- a/src/template/wasm2c.includes.c +++ b/src/template/wasm2c.includes.c @@ -1,5 +1,6 @@ #include #include +#include #include #if defined(_MSC_VER) #include diff --git a/src/tools/wasm2c.cc b/src/tools/wasm2c.cc index 7ed745f49..3dd144834 100644 --- a/src/tools/wasm2c.cc +++ b/src/tools/wasm2c.cc @@ -109,7 +109,6 @@ static void ParseOptions(int argc, char** argv) { "wasm2c currently only supports a limited set of features.\n"); exit(1); } - s_features.disable_bulk_memory(); } // TODO(binji): copied from binary-writer-spec.cc, probably should share. diff --git a/test/run-spec-wasm2c.py b/test/run-spec-wasm2c.py index e32c90781..59c50ed98 100755 --- a/test/run-spec-wasm2c.py +++ b/test/run-spec-wasm2c.py @@ -122,6 +122,7 @@ def __init__(self, spec_json, prefix, out_file, out_dir): self.module_name_to_idx = {} self.module_prefix_map = {} self.unmangled_names = {} + self.idx_to_module_name = {} self._MaybeWriteDummyModule() self._CacheModulePrefixes() @@ -162,6 +163,7 @@ def _CacheModulePrefixes(self): if 'name' in command: self.module_name_to_idx[command['name']] = idx + self.idx_to_module_name[idx] = command['name'] self.module_prefix_map[command['name']] = name idx += 1 @@ -173,6 +175,8 @@ def _CacheModulePrefixes(self): else: name_idx = idx - 1 + if name_idx in self.idx_to_module_name: + self.module_prefix_map[self.idx_to_module_name[name_idx]] = name self.module_prefix_map[name_idx] = name self.unmangled_names[name_idx] = command['as'] diff --git a/test/wasm2c/old-spec/bulk-memory-operations/imports.txt b/test/wasm2c/old-spec/bulk-memory-operations/imports.txt new file mode 100644 index 000000000..3084f0597 --- /dev/null +++ b/test/wasm2c/old-spec/bulk-memory-operations/imports.txt @@ -0,0 +1,607 @@ +;;; TOOL: run-spec-wasm2c +;; Auxiliary module to import from + +(module + (func (export "func")) + (func (export "func-i32") (param i32)) + (func (export "func-f32") (param f32)) + (func (export "func->i32") (result i32) (i32.const 22)) + (func (export "func->f32") (result f32) (f32.const 11)) + (func (export "func-i32->i32") (param i32) (result i32) (local.get 0)) + (func (export "func-i64->i64") (param i64) (result i64) (local.get 0)) + (global (export "global-i32") i32 (i32.const 55)) + (global (export "global-f32") f32 (f32.const 44)) + (table (export "table-10-inf") 10 funcref) + ;; (table (export "table-10-20") 10 20 funcref) + (memory (export "memory-2-inf") 2) + ;; (memory (export "memory-2-4") 2 4) +) + +(register "test") + + +;; Functions + +(module + (type $func_i32 (func (param i32))) + (type $func_i64 (func (param i64))) + (type $func_f32 (func (param f32))) + (type $func_f64 (func (param f64))) + + (import "spectest" "print_i32" (func (param i32))) + ;; JavaScript can't handle i64 yet. + ;; (func (import "spectest" "print_i64") (param i64)) + (import "spectest" "print_i32" (func $print_i32 (param i32))) + ;; JavaScript can't handle i64 yet. + ;; (import "spectest" "print_i64" (func $print_i64 (param i64))) + (import "spectest" "print_f32" (func $print_f32 (param f32))) + (import "spectest" "print_f64" (func $print_f64 (param f64))) + (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) + (import "spectest" "print_f64_f64" (func $print_f64_f64 (param f64 f64))) + (func $print_i32-2 (import "spectest" "print_i32") (param i32)) + (func $print_f64-2 (import "spectest" "print_f64") (param f64)) + (import "test" "func-i64->i64" (func $i64->i64 (param i64) (result i64))) + + (func (export "p1") (import "spectest" "print_i32") (param i32)) + (func $p (export "p2") (import "spectest" "print_i32") (param i32)) + (func (export "p3") (export "p4") (import "spectest" "print_i32") (param i32)) + (func (export "p5") (import "spectest" "print_i32") (type 0)) + (func (export "p6") (import "spectest" "print_i32") (type 0) (param i32) (result)) + + (import "spectest" "print_i32" (func (type $forward))) + (func (import "spectest" "print_i32") (type $forward)) + (type $forward (func (param i32))) + + (table funcref (elem $print_i32 $print_f64)) + + (func (export "print32") (param $i i32) + (local $x f32) + (local.set $x (f32.convert_i32_s (local.get $i))) + (call 0 (local.get $i)) + (call $print_i32_f32 + (i32.add (local.get $i) (i32.const 1)) + (f32.const 42) + ) + (call $print_i32 (local.get $i)) + (call $print_i32-2 (local.get $i)) + (call $print_f32 (local.get $x)) + (call_indirect (type $func_i32) (local.get $i) (i32.const 0)) + ) + + (func (export "print64") (param $i i64) + (local $x f64) + (local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i)))) + ;; JavaScript can't handle i64 yet. + ;; (call 1 (local.get $i)) + (call $print_f64_f64 + (f64.add (local.get $x) (f64.const 1)) + (f64.const 53) + ) + ;; JavaScript can't handle i64 yet. + ;; (call $print_i64 (local.get $i)) + (call $print_f64 (local.get $x)) + (call $print_f64-2 (local.get $x)) + (call_indirect (type $func_f64) (local.get $x) (i32.const 1)) + ) +) + +(assert_return (invoke "print32" (i32.const 13))) +(assert_return (invoke "print64" (i64.const 24))) + +(assert_invalid + (module + (type (func (result i32))) + (import "test" "func" (func (type 1))) + ) + "unknown type" +) + +(module (import "test" "func" (func))) +(module (import "test" "func-i32" (func (param i32)))) +(module (import "test" "func-f32" (func (param f32)))) +(module (import "test" "func->i32" (func (result i32)))) +(module (import "test" "func->f32" (func (result f32)))) +(module (import "test" "func-i32->i32" (func (param i32) (result i32)))) +(module (import "test" "func-i64->i64" (func (param i64) (result i64)))) + +(assert_unlinkable + (module (import "test" "unknown" (func))) + "unknown import" +) +(assert_unlinkable + (module (import "spectest" "unknown" (func))) + "unknown import" +) + +(assert_unlinkable + (module (import "test" "func" (func (param i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func" (func (result i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func" (func (param i32) (result i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32" (func (result i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32" (func (param f32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32" (func (param i64)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32" (func (param i32) (result i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func->i32" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func->i32" (func (param i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func->i32" (func (result f32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func->i32" (func (result i64)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func->i32" (func (param i32) (result i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32->i32" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32->i32" (func (param i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "func-i32->i32" (func (result i32)))) + "incompatible import type" +) + +(assert_unlinkable + (module (import "test" "global-i32" (func (result i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table-10-inf" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-inf" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "global_i32" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "table" (func))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "memory" (func))) + "incompatible import type" +) + + +;; Globals + +(module + (import "spectest" "global_i32" (global i32)) + (global (import "spectest" "global_i32") i32) + + (import "spectest" "global_i32" (global $x i32)) + (global $y (import "spectest" "global_i32") i32) + + ;; JavaScript can't handle i64 yet. + ;; (import "spectest" "global_i64" (global i64)) + (import "spectest" "global_f32" (global f32)) + (import "spectest" "global_f64" (global f64)) + + (func (export "get-0") (result i32) (global.get 0)) + (func (export "get-1") (result i32) (global.get 1)) + (func (export "get-x") (result i32) (global.get $x)) + (func (export "get-y") (result i32) (global.get $y)) +) + +(assert_return (invoke "get-0") (i32.const 666)) +(assert_return (invoke "get-1") (i32.const 666)) +(assert_return (invoke "get-x") (i32.const 666)) +(assert_return (invoke "get-y") (i32.const 666)) + +(module (import "test" "global-i32" (global i32))) +(module (import "test" "global-f32" (global f32))) + +(assert_unlinkable + (module (import "test" "unknown" (global i32))) + "unknown import" +) +(assert_unlinkable + (module (import "spectest" "unknown" (global i32))) + "unknown import" +) + +(assert_unlinkable + (module (import "test" "func" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table-10-inf" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-inf" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "print_i32" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "table" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "memory" (global i32))) + "incompatible import type" +) + + +;; Tables + +(module + (type (func (result i32))) + (import "spectest" "table" (table 10 20 funcref)) + (elem (table 0) (i32.const 1) func $f $g) + + (func (export "call") (param i32) (result i32) + (call_indirect (type 0) (local.get 0)) + ) + (func $f (result i32) (i32.const 11)) + (func $g (result i32) (i32.const 22)) +) + +(assert_trap (invoke "call" (i32.const 0)) "uninitialized element") +(assert_return (invoke "call" (i32.const 1)) (i32.const 11)) +(assert_return (invoke "call" (i32.const 2)) (i32.const 22)) +(assert_trap (invoke "call" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "call" (i32.const 100)) "undefined element") + + +(module + (type (func (result i32))) + (table (import "spectest" "table") 10 20 funcref) + (elem (table 0) (i32.const 1) func $f $g) + + (func (export "call") (param i32) (result i32) + (call_indirect (type 0) (local.get 0)) + ) + (func $f (result i32) (i32.const 11)) + (func $g (result i32) (i32.const 22)) +) + +(assert_trap (invoke "call" (i32.const 0)) "uninitialized element") +(assert_return (invoke "call" (i32.const 1)) (i32.const 11)) +(assert_return (invoke "call" (i32.const 2)) (i32.const 22)) +(assert_trap (invoke "call" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "call" (i32.const 100)) "undefined element") + + +(assert_invalid + (module (import "" "" (table 10 funcref)) (import "" "" (table 10 funcref))) + "multiple tables" +) +(assert_invalid + (module (import "" "" (table 10 funcref)) (table 10 funcref)) + "multiple tables" +) +(assert_invalid + (module (table 10 funcref) (table 10 funcref)) + "multiple tables" +) + +(module (import "test" "table-10-inf" (table 10 funcref))) +(module (import "test" "table-10-inf" (table 5 funcref))) +(module (import "test" "table-10-inf" (table 0 funcref))) +(module (import "spectest" "table" (table 10 funcref))) +(module (import "spectest" "table" (table 5 funcref))) +(module (import "spectest" "table" (table 0 funcref))) +(module (import "spectest" "table" (table 10 20 funcref))) +(module (import "spectest" "table" (table 5 20 funcref))) +(module (import "spectest" "table" (table 0 20 funcref))) +(module (import "spectest" "table" (table 10 25 funcref))) +(module (import "spectest" "table" (table 5 25 funcref))) + +(assert_unlinkable + (module (import "test" "unknown" (table 10 funcref))) + "unknown import" +) +(assert_unlinkable + (module (import "spectest" "unknown" (table 10 funcref))) + "unknown import" +) + +(assert_unlinkable + (module (import "test" "table-10-inf" (table 12 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table-10-inf" (table 10 20 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "table" (table 12 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "table" (table 10 15 funcref))) + "incompatible import type" +) + +(assert_unlinkable + (module (import "test" "func" (table 10 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-i32" (table 10 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-inf" (table 10 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "print_i32" (table 10 funcref))) + "incompatible import type" +) + + + +;; Memories + +(module + (import "spectest" "memory" (memory 1 2)) + (data (memory 0) (i32.const 10) "\10") + + (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) +) + +(assert_return (invoke "load" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "load" (i32.const 10)) (i32.const 16)) +(assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000)) +(assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access") + +(module + (memory (import "spectest" "memory") 1 2) + (data (memory 0) (i32.const 10) "\10") + + (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) +) +(assert_return (invoke "load" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "load" (i32.const 10)) (i32.const 16)) +(assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000)) +(assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access") + +(assert_invalid + (module (import "" "" (memory 1)) (import "" "" (memory 1))) + "multiple memories" +) +(assert_invalid + (module (import "" "" (memory 1)) (memory 0)) + "multiple memories" +) +(assert_invalid + (module (memory 0) (memory 0)) + "multiple memories" +) + +(module (import "test" "memory-2-inf" (memory 2))) +(module (import "test" "memory-2-inf" (memory 1))) +(module (import "test" "memory-2-inf" (memory 0))) +(module (import "spectest" "memory" (memory 1))) +(module (import "spectest" "memory" (memory 0))) +(module (import "spectest" "memory" (memory 1 2))) +(module (import "spectest" "memory" (memory 0 2))) +(module (import "spectest" "memory" (memory 1 3))) +(module (import "spectest" "memory" (memory 0 3))) + +(assert_unlinkable + (module (import "test" "unknown" (memory 1))) + "unknown import" +) +(assert_unlinkable + (module (import "spectest" "unknown" (memory 1))) + "unknown import" +) + +(assert_unlinkable + (module (import "test" "memory-2-inf" (memory 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-inf" (memory 2 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "memory" (memory 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "memory" (memory 1 1))) + "incompatible import type" +) + +(assert_unlinkable + (module (import "test" "func-i32" (memory 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-i32" (memory 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table-10-inf" (memory 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "print_i32" (memory 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "global_i32" (memory 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "table" (memory 1))) + "incompatible import type" +) + +(assert_unlinkable + (module (import "spectest" "memory" (memory 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "spectest" "memory" (memory 1 1))) + "incompatible import type" +) + +(module + (import "spectest" "memory" (memory 0 3)) ;; actual has max size 2 + (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0))) +) +(assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "grow" (i32.const 0)) (i32.const 2)) +(assert_return (invoke "grow" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "grow" (i32.const 0)) (i32.const 2)) + + +;; Syntax errors + +(assert_malformed + (module quote "(func) (import \"\" \"\" (func))") + "import after function" +) +(assert_malformed + (module quote "(func) (import \"\" \"\" (global i64))") + "import after function" +) +(assert_malformed + (module quote "(func) (import \"\" \"\" (table 0 funcref))") + "import after function" +) +(assert_malformed + (module quote "(func) (import \"\" \"\" (memory 0))") + "import after function" +) + +(assert_malformed + (module quote "(global i64 (i64.const 0)) (import \"\" \"\" (func))") + "import after global" +) +(assert_malformed + (module quote "(global i64 (i64.const 0)) (import \"\" \"\" (global f32))") + "import after global" +) +(assert_malformed + (module quote "(global i64 (i64.const 0)) (import \"\" \"\" (table 0 funcref))") + "import after global" +) +(assert_malformed + (module quote "(global i64 (i64.const 0)) (import \"\" \"\" (memory 0))") + "import after global" +) + +(assert_malformed + (module quote "(table 0 funcref) (import \"\" \"\" (func))") + "import after table" +) +(assert_malformed + (module quote "(table 0 funcref) (import \"\" \"\" (global i32))") + "import after table" +) +(assert_malformed + (module quote "(table 0 funcref) (import \"\" \"\" (table 0 funcref))") + "import after table" +) +(assert_malformed + (module quote "(table 0 funcref) (import \"\" \"\" (memory 0))") + "import after table" +) + +(assert_malformed + (module quote "(memory 0) (import \"\" \"\" (func))") + "import after memory" +) +(assert_malformed + (module quote "(memory 0) (import \"\" \"\" (global i32))") + "import after memory" +) +(assert_malformed + (module quote "(memory 0) (import \"\" \"\" (table 1 3 funcref))") + "import after memory" +) +(assert_malformed + (module quote "(memory 0) (import \"\" \"\" (memory 1 2))") + "import after memory" +) + +;; This module is required to validate, regardless of whether it can be +;; linked. Overloading is not possible in wasm itself, but it is possible +;; in modules from which wasm can import. +(module) +(register "not wasm") +(assert_unlinkable + (module + (import "not wasm" "overloaded" (func)) + (import "not wasm" "overloaded" (func (param i32))) + (import "not wasm" "overloaded" (func (param i32 i32))) + (import "not wasm" "overloaded" (func (param i64))) + (import "not wasm" "overloaded" (func (param f32))) + (import "not wasm" "overloaded" (func (param f64))) + (import "not wasm" "overloaded" (func (result i32))) + (import "not wasm" "overloaded" (func (result i64))) + (import "not wasm" "overloaded" (func (result f32))) + (import "not wasm" "overloaded" (func (result f64))) + (import "not wasm" "overloaded" (global i32)) + (import "not wasm" "overloaded" (global i64)) + (import "not wasm" "overloaded" (global f32)) + (import "not wasm" "overloaded" (global f64)) + (import "not wasm" "overloaded" (table 0 funcref)) + (import "not wasm" "overloaded" (memory 0)) + ) + "unknown import" +) +(;; STDOUT ;;; +spectest.print_i32(13) +spectest.print_i32_f32(14 42) +spectest.print_i32(13) +spectest.print_i32(13) +spectest.print_f32(13) +spectest.print_i32(13) +spectest.print_f64_f64(25 53) +spectest.print_f64(24) +spectest.print_f64(24) +spectest.print_f64(24) +29/29 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/old-spec/bulk-memory-operations/linking.txt b/test/wasm2c/old-spec/bulk-memory-operations/linking.txt new file mode 100644 index 000000000..d2a8bc755 --- /dev/null +++ b/test/wasm2c/old-spec/bulk-memory-operations/linking.txt @@ -0,0 +1,399 @@ +;;; TOOL: run-spec-wasm2c +;; Functions + +(module $Mf + (func (export "call") (result i32) (call $g)) + (func $g (result i32) (i32.const 2)) +) +(register "Mf" $Mf) + +(module $Nf + (func $f (import "Mf" "call") (result i32)) + (export "Mf.call" (func $f)) + (func (export "call Mf.call") (result i32) (call $f)) + (func (export "call") (result i32) (call $g)) + (func $g (result i32) (i32.const 3)) +) + +(assert_return (invoke $Mf "call") (i32.const 2)) +(assert_return (invoke $Nf "Mf.call") (i32.const 2)) +(assert_return (invoke $Nf "call") (i32.const 3)) +(assert_return (invoke $Nf "call Mf.call") (i32.const 2)) + +(module + (import "spectest" "print_i32" (func $f (param i32))) + (export "print" (func $f)) +) +(register "reexport_f") +(assert_unlinkable + (module (import "reexport_f" "print" (func (param i64)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "reexport_f" "print" (func (param i32) (result i32)))) + "incompatible import type" +) + + +;; Globals + +(module $Mg + (global $glob (export "glob") i32 (i32.const 42)) + (func (export "get") (result i32) (global.get $glob)) + + ;; export mutable globals + (global $mut_glob (export "mut_glob") (mut i32) (i32.const 142)) + (func (export "get_mut") (result i32) (global.get $mut_glob)) + (func (export "set_mut") (param i32) (global.set $mut_glob (local.get 0))) +) +(register "Mg" $Mg) + +(module $Ng + (global $x (import "Mg" "glob") i32) + (global $mut_glob (import "Mg" "mut_glob") (mut i32)) + (func $f (import "Mg" "get") (result i32)) + (func $get_mut (import "Mg" "get_mut") (result i32)) + (func $set_mut (import "Mg" "set_mut") (param i32)) + + (export "Mg.glob" (global $x)) + (export "Mg.get" (func $f)) + (global $glob (export "glob") i32 (i32.const 43)) + (func (export "get") (result i32) (global.get $glob)) + + (export "Mg.mut_glob" (global $mut_glob)) + (export "Mg.get_mut" (func $get_mut)) + (export "Mg.set_mut" (func $set_mut)) +) + +(assert_return (get $Mg "glob") (i32.const 42)) +(assert_return (get $Ng "Mg.glob") (i32.const 42)) +(assert_return (get $Ng "glob") (i32.const 43)) +(assert_return (invoke $Mg "get") (i32.const 42)) +(assert_return (invoke $Ng "Mg.get") (i32.const 42)) +(assert_return (invoke $Ng "get") (i32.const 43)) + +(assert_return (get $Mg "mut_glob") (i32.const 142)) +(assert_return (get $Ng "Mg.mut_glob") (i32.const 142)) +(assert_return (invoke $Mg "get_mut") (i32.const 142)) +(assert_return (invoke $Ng "Mg.get_mut") (i32.const 142)) + +(assert_return (invoke $Mg "set_mut" (i32.const 241))) +(assert_return (get $Mg "mut_glob") (i32.const 241)) +(assert_return (get $Ng "Mg.mut_glob") (i32.const 241)) +(assert_return (invoke $Mg "get_mut") (i32.const 241)) +(assert_return (invoke $Ng "Mg.get_mut") (i32.const 241)) + + +(assert_unlinkable + (module (import "Mg" "mut_glob" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "Mg" "glob" (global (mut i32)))) + "incompatible import type" +) + +;; Tables + +(module $Mt + (type (func (result i32))) + (type (func)) + + (table (export "tab") 10 funcref) + (elem (i32.const 2) $g $g $g $g) + (func $g (result i32) (i32.const 4)) + (func (export "h") (result i32) (i32.const -4)) + + (func (export "call") (param i32) (result i32) + (call_indirect (type 0) (local.get 0)) + ) +) +(register "Mt" $Mt) + +(module $Nt + (type (func)) + (type (func (result i32))) + + (func $f (import "Mt" "call") (param i32) (result i32)) + (func $h (import "Mt" "h") (result i32)) + + (table funcref (elem $g $g $g $h $f)) + (func $g (result i32) (i32.const 5)) + + (export "Mt.call" (func $f)) + (func (export "call Mt.call") (param i32) (result i32) + (call $f (local.get 0)) + ) + (func (export "call") (param i32) (result i32) + (call_indirect (type 1) (local.get 0)) + ) +) + +(assert_return (invoke $Mt "call" (i32.const 2)) (i32.const 4)) +(assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const 4)) +(assert_return (invoke $Nt "call" (i32.const 2)) (i32.const 5)) +(assert_return (invoke $Nt "call Mt.call" (i32.const 2)) (i32.const 4)) + +(assert_trap (invoke $Mt "call" (i32.const 1)) "uninitialized") +(assert_trap (invoke $Nt "Mt.call" (i32.const 1)) "uninitialized") +(assert_return (invoke $Nt "call" (i32.const 1)) (i32.const 5)) +(assert_trap (invoke $Nt "call Mt.call" (i32.const 1)) "uninitialized") + +(assert_trap (invoke $Mt "call" (i32.const 0)) "uninitialized") +(assert_trap (invoke $Nt "Mt.call" (i32.const 0)) "uninitialized") +(assert_return (invoke $Nt "call" (i32.const 0)) (i32.const 5)) +(assert_trap (invoke $Nt "call Mt.call" (i32.const 0)) "uninitialized") + +(assert_trap (invoke $Mt "call" (i32.const 20)) "undefined") +(assert_trap (invoke $Nt "Mt.call" (i32.const 20)) "undefined") +(assert_trap (invoke $Nt "call" (i32.const 7)) "undefined") +(assert_trap (invoke $Nt "call Mt.call" (i32.const 20)) "undefined") + +(assert_return (invoke $Nt "call" (i32.const 3)) (i32.const -4)) +(assert_trap (invoke $Nt "call" (i32.const 4)) "indirect call") + +(module $Ot + (type (func (result i32))) + + (func $h (import "Mt" "h") (result i32)) + (table (import "Mt" "tab") 5 funcref) + (elem (i32.const 1) $i $h) + (func $i (result i32) (i32.const 6)) + + (func (export "call") (param i32) (result i32) + (call_indirect (type 0) (local.get 0)) + ) +) + +(assert_return (invoke $Mt "call" (i32.const 3)) (i32.const 4)) +(assert_return (invoke $Nt "Mt.call" (i32.const 3)) (i32.const 4)) +(assert_return (invoke $Nt "call Mt.call" (i32.const 3)) (i32.const 4)) +(assert_return (invoke $Ot "call" (i32.const 3)) (i32.const 4)) + +(assert_return (invoke $Mt "call" (i32.const 2)) (i32.const -4)) +(assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const -4)) +(assert_return (invoke $Nt "call" (i32.const 2)) (i32.const 5)) +(assert_return (invoke $Nt "call Mt.call" (i32.const 2)) (i32.const -4)) +(assert_return (invoke $Ot "call" (i32.const 2)) (i32.const -4)) + +(assert_return (invoke $Mt "call" (i32.const 1)) (i32.const 6)) +(assert_return (invoke $Nt "Mt.call" (i32.const 1)) (i32.const 6)) +(assert_return (invoke $Nt "call" (i32.const 1)) (i32.const 5)) +(assert_return (invoke $Nt "call Mt.call" (i32.const 1)) (i32.const 6)) +(assert_return (invoke $Ot "call" (i32.const 1)) (i32.const 6)) + +(assert_trap (invoke $Mt "call" (i32.const 0)) "uninitialized") +(assert_trap (invoke $Nt "Mt.call" (i32.const 0)) "uninitialized") +(assert_return (invoke $Nt "call" (i32.const 0)) (i32.const 5)) +(assert_trap (invoke $Nt "call Mt.call" (i32.const 0)) "uninitialized") +(assert_trap (invoke $Ot "call" (i32.const 0)) "uninitialized") + +(assert_trap (invoke $Ot "call" (i32.const 20)) "undefined") + +(module + (table (import "Mt" "tab") 0 funcref) + (elem (i32.const 9) $f) + (func $f) +) + +(module $G1 (global (export "g") i32 (i32.const 5))) +(register "G1" $G1) +(module $G2 + (global (import "G1" "g") i32) + (global (export "g") i32 (global.get 0)) +) +(assert_return (get $G2 "g") (i32.const 5)) + +(assert_trap + (module + (table (import "Mt" "tab") 0 funcref) + (elem (i32.const 10) $f) + (func $f) + ) + "out of bounds" +) + +(assert_unlinkable + (module + (table (import "Mt" "tab") 10 funcref) + (memory (import "Mt" "mem") 1) ;; does not exist + (func $f (result i32) (i32.const 0)) + (elem (i32.const 7) $f) + (elem (i32.const 9) $f) + ) + "unknown import" +) +(assert_trap (invoke $Mt "call" (i32.const 7)) "uninitialized") + +;; Unlike in the v1 spec, the elements stored before an out-of-bounds access +;; persist after the instantiation failure. +(assert_trap + (module + (table (import "Mt" "tab") 10 funcref) + (func $f (result i32) (i32.const 0)) + (elem (i32.const 7) $f) + (elem (i32.const 8) $f $f $f $f $f) ;; (partially) out of bounds + ) + "out of bounds" +) +(assert_return (invoke $Mt "call" (i32.const 7)) (i32.const 0)) +(assert_trap (invoke $Mt "call" (i32.const 8)) "uninitialized") + +(assert_trap + (module + (table (import "Mt" "tab") 10 funcref) + (func $f (result i32) (i32.const 0)) + (elem (i32.const 7) $f) + (memory 1) + (data (i32.const 0x10000) "d") ;; out of bounds + ) + "out of bounds" +) +(assert_return (invoke $Mt "call" (i32.const 7)) (i32.const 0)) + + +;; Memories + +(module $Mm + (memory (export "mem") 1 5) + (data (i32.const 10) "\00\01\02\03\04\05\06\07\08\09") + + (func (export "load") (param $a i32) (result i32) + (i32.load8_u (local.get 0)) + ) +) +(register "Mm" $Mm) + +(module $Nm + (func $loadM (import "Mm" "load") (param i32) (result i32)) + + (memory 1) + (data (i32.const 10) "\f0\f1\f2\f3\f4\f5") + + (export "Mm.load" (func $loadM)) + (func (export "load") (param $a i32) (result i32) + (i32.load8_u (local.get 0)) + ) +) + +(assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 2)) +(assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 2)) +(assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2)) + +(module $Om + (memory (import "Mm" "mem") 1) + (data (i32.const 5) "\a0\a1\a2\a3\a4\a5\a6\a7") + + (func (export "load") (param $a i32) (result i32) + (i32.load8_u (local.get 0)) + ) +) + +(assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 0xa7)) +(assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 0xa7)) +(assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2)) +(assert_return (invoke $Om "load" (i32.const 12)) (i32.const 0xa7)) + +(module + (memory (import "Mm" "mem") 0) + (data (i32.const 0xffff) "a") +) + +(assert_trap + (module + (memory (import "Mm" "mem") 0) + (data (i32.const 0x10000) "a") + ) + "out of bounds" +) + +(module $Pm + (memory (import "Mm" "mem") 1 8) + + (func (export "grow") (param $a i32) (result i32) + (memory.grow (local.get 0)) + ) +) + +(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 1)) +(assert_return (invoke $Pm "grow" (i32.const 2)) (i32.const 1)) +(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 3)) +(assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const 3)) +(assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const 4)) +(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5)) +(assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const -1)) +(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5)) + +(assert_unlinkable + (module + (func $host (import "spectest" "print")) + (memory (import "Mm" "mem") 1) + (table (import "Mm" "tab") 0 funcref) ;; does not exist + (data (i32.const 0) "abc") + ) + "unknown import" +) +(assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 0)) + +;; Unlike in v1 spec, bytes written before an out-of-bounds access persist +;; after the instantiation failure. +(assert_trap + (module + ;; Note: the memory is 5 pages large by the time we get here. + (memory (import "Mm" "mem") 1) + (data (i32.const 0) "abc") + (data (i32.const 327670) "zzzzzzzzzzzzzzzzzz") ;; (partially) out of bounds + ) + "out of bounds" +) +(assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 97)) +(assert_return (invoke $Mm "load" (i32.const 327670)) (i32.const 0)) + +(assert_trap + (module + (memory (import "Mm" "mem") 1) + (data (i32.const 0) "abc") + (table 0 funcref) + (func) + (elem (i32.const 0) 0) ;; out of bounds + ) + "out of bounds" +) +(assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 97)) + +;; Store is modified if the start function traps. +(module $Ms + (type $t (func (result i32))) + (memory (export "memory") 1) + (table (export "table") 1 funcref) + (func (export "get memory[0]") (type $t) + (i32.load8_u (i32.const 0)) + ) + (func (export "get table[0]") (type $t) + (call_indirect (type $t) (i32.const 0)) + ) +) +(register "Ms" $Ms) + +(assert_trap + (module + (import "Ms" "memory" (memory 1)) + (import "Ms" "table" (table 1 funcref)) + (data (i32.const 0) "hello") + (elem (i32.const 0) $f) + (func $f (result i32) + (i32.const 0xdead) + ) + (func $main + (unreachable) + ) + (start $main) + ) + "unreachable" +) + +(assert_return (invoke $Ms "get memory[0]") (i32.const 104)) ;; 'h' +(assert_return (invoke $Ms "get table[0]") (i32.const 0xdead)) +(;; STDOUT ;;; +90/90 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/old-spec/bulk-memory-operations/table_copy.txt b/test/wasm2c/old-spec/bulk-memory-operations/table_copy.txt new file mode 100644 index 000000000..ab5fd9147 --- /dev/null +++ b/test/wasm2c/old-spec/bulk-memory-operations/table_copy.txt @@ -0,0 +1,1599 @@ +;;; TOOL: run-spec-wasm2c +;; +;; Generated by ../meta/generate_table_copy.js +;; + +(module + (func (export "ef0") (result i32) (i32.const 0)) + (func (export "ef1") (result i32) (i32.const 1)) + (func (export "ef2") (result i32) (i32.const 2)) + (func (export "ef3") (result i32) (i32.const 3)) + (func (export "ef4") (result i32) (i32.const 4)) +) +(register "a") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (nop)) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 13) (i32.const 2) (i32.const 3))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 25) (i32.const 15) (i32.const 2))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_return (invoke "check" (i32.const 25)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 26)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 13) (i32.const 25) (i32.const 3))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_trap (invoke "check" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 15)) "uninitialized element") +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 20) (i32.const 22) (i32.const 4))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 25) (i32.const 1) (i32.const 3))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_return (invoke "check" (i32.const 26)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 27)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 10) (i32.const 12) (i32.const 7))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_return (invoke "check" (i32.const 10)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 11)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 12)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.copy (i32.const 12) (i32.const 10) (i32.const 7))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 13)) "uninitialized element") +(assert_return (invoke "check" (i32.const 14)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 17)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 18)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 28) (i32.const 1) (i32.const 3)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 15) (i32.const 25) (i32.const 6)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 15) (i32.const 25) (i32.const 0)) + )) + +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 30) (i32.const 15) (i32.const 0)) + )) + +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 31) (i32.const 15) (i32.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 15) (i32.const 30) (i32.const 0)) + )) + +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 15) (i32.const 31) (i32.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 30) (i32.const 30) (i32.const 0)) + )) + +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy (i32.const 31) (i32.const 31) (i32.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 0) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 24) (i32.const 0) (i32.const 16)) + "out of bounds") +(assert_return (invoke "test" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 5)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 6)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 7)) (i32.const 7)) +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 0) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 23) (i32.const 0) (i32.const 15)) + "out of bounds") +(assert_return (invoke "test" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 5)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 6)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 7)) (i32.const 7)) +(assert_return (invoke "test" (i32.const 8)) (i32.const 8)) +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 24) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 0) (i32.const 24) (i32.const 16)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_return (invoke "test" (i32.const 24)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 25)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 26)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 27)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 28)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 29)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 30)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 31)) (i32.const 7)) + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 23) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 0) (i32.const 23) (i32.const 15)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_return (invoke "test" (i32.const 23)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 24)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 25)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 26)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 27)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 28)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 29)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 30)) (i32.const 7)) +(assert_return (invoke "test" (i32.const 31)) (i32.const 8)) + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 11) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 24) (i32.const 11) (i32.const 16)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_return (invoke "test" (i32.const 11)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 12)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 13)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 14)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 15)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 16)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 17)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 18)) (i32.const 7)) +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 24) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 11) (i32.const 24) (i32.const 16)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_return (invoke "test" (i32.const 24)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 25)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 26)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 27)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 28)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 29)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 30)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 31)) (i32.const 7)) + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 21) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 24) (i32.const 21) (i32.const 16)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_return (invoke "test" (i32.const 21)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 22)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 23)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 24)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 25)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 26)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 27)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 28)) (i32.const 7)) +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 24) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 21) (i32.const 24) (i32.const 16)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_return (invoke "test" (i32.const 24)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 25)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 26)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 27)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 28)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 29)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 30)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 31)) (i32.const 7)) + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem (i32.const 21) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $f10) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 21) (i32.const 21) (i32.const 16)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_return (invoke "test" (i32.const 21)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 22)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 23)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 24)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 25)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 26)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 27)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 28)) (i32.const 7)) +(assert_return (invoke "test" (i32.const 29)) (i32.const 8)) +(assert_return (invoke "test" (i32.const 30)) (i32.const 9)) +(assert_return (invoke "test" (i32.const 31)) (i32.const 10)) + +(module + (type (func (result i32))) + (table 128 128 funcref) + (elem (i32.const 112) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 0) (i32.const 112) (i32.const 4294967264)) + "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 32)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 33)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 34)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 35)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 36)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 37)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 38)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 39)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 40)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 41)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 42)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 43)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 44)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 45)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 46)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 47)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 48)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 49)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 50)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 51)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 52)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 53)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 54)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 55)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 56)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 57)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 58)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 59)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 60)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 61)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 62)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 63)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 64)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 65)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 66)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 67)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 68)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 69)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 70)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 71)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 72)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 73)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 74)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 75)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 76)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 77)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 78)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 79)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 80)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 81)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 82)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 83)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 84)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 85)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 86)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 87)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 88)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 89)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 90)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 91)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 92)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 93)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 94)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 95)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 96)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 97)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 98)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 99)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 100)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 101)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 102)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 103)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 104)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 105)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 106)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 107)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 108)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 109)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 110)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 111)) "uninitialized element") +(assert_return (invoke "test" (i32.const 112)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 113)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 114)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 115)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 116)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 117)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 118)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 119)) (i32.const 7)) +(assert_return (invoke "test" (i32.const 120)) (i32.const 8)) +(assert_return (invoke "test" (i32.const 121)) (i32.const 9)) +(assert_return (invoke "test" (i32.const 122)) (i32.const 10)) +(assert_return (invoke "test" (i32.const 123)) (i32.const 11)) +(assert_return (invoke "test" (i32.const 124)) (i32.const 12)) +(assert_return (invoke "test" (i32.const 125)) (i32.const 13)) +(assert_return (invoke "test" (i32.const 126)) (i32.const 14)) +(assert_return (invoke "test" (i32.const 127)) (i32.const 15)) + +(module + (type (func (result i32))) + (table 128 128 funcref) + (elem (i32.const 0) + $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (table.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len)))) + +(assert_trap (invoke "run" (i32.const 112) (i32.const 0) (i32.const 4294967264)) + "out of bounds") +(assert_return (invoke "test" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "test" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "test" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "test" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "test" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "test" (i32.const 5)) (i32.const 5)) +(assert_return (invoke "test" (i32.const 6)) (i32.const 6)) +(assert_return (invoke "test" (i32.const 7)) (i32.const 7)) +(assert_return (invoke "test" (i32.const 8)) (i32.const 8)) +(assert_return (invoke "test" (i32.const 9)) (i32.const 9)) +(assert_return (invoke "test" (i32.const 10)) (i32.const 10)) +(assert_return (invoke "test" (i32.const 11)) (i32.const 11)) +(assert_return (invoke "test" (i32.const 12)) (i32.const 12)) +(assert_return (invoke "test" (i32.const 13)) (i32.const 13)) +(assert_return (invoke "test" (i32.const 14)) (i32.const 14)) +(assert_return (invoke "test" (i32.const 15)) (i32.const 15)) +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 32)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 33)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 34)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 35)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 36)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 37)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 38)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 39)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 40)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 41)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 42)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 43)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 44)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 45)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 46)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 47)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 48)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 49)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 50)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 51)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 52)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 53)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 54)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 55)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 56)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 57)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 58)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 59)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 60)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 61)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 62)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 63)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 64)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 65)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 66)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 67)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 68)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 69)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 70)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 71)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 72)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 73)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 74)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 75)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 76)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 77)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 78)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 79)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 80)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 81)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 82)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 83)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 84)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 85)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 86)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 87)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 88)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 89)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 90)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 91)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 92)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 93)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 94)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 95)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 96)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 97)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 98)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 99)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 100)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 101)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 102)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 103)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 104)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 105)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 106)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 107)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 108)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 109)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 110)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 111)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 112)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 113)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 114)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 115)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 116)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 117)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 118)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 119)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 120)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 121)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 122)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 123)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 124)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 125)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 126)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 127)) "uninitialized element") +(;; STDOUT ;;; +802/802 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/old-spec/bulk-memory-operations/table_init.txt b/test/wasm2c/old-spec/bulk-memory-operations/table_init.txt new file mode 100644 index 000000000..0c69a894d --- /dev/null +++ b/test/wasm2c/old-spec/bulk-memory-operations/table_init.txt @@ -0,0 +1,1780 @@ +;;; TOOL: run-spec-wasm2c +;; +;; Generated by ../meta/generate_table_init.js +;; + +(module + (func (export "ef0") (result i32) (i32.const 0)) + (func (export "ef1") (result i32) (i32.const 1)) + (func (export "ef2") (result i32) (i32.const 2)) + (func (export "ef3") (result i32) (i32.const 3)) + (func (export "ef4") (result i32) (i32.const 4)) +) +(register "a") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init 1 (i32.const 7) (i32.const 0) (i32.const 4))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_return (invoke "check" (i32.const 7)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 8)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 9)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 10)) (i32.const 8)) +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init 3 (i32.const 15) (i32.const 1) (i32.const 3))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 9)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 17)) (i32.const 7)) +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init 1 (i32.const 7) (i32.const 0) (i32.const 4)) + (elem.drop 1) + (table.init 3 (i32.const 15) (i32.const 1) (i32.const 3)) + (elem.drop 3) + (table.copy (i32.const 20) (i32.const 15) (i32.const 5)) + (table.copy (i32.const 21) (i32.const 29) (i32.const 1)) + (table.copy (i32.const 24) (i32.const 10) (i32.const 1)) + (table.copy (i32.const 13) (i32.const 11) (i32.const 4)) + (table.copy (i32.const 19) (i32.const 20) (i32.const 5))) + (func (export "check") (param i32) (result i32) + (call_indirect (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 1)) "uninitialized element") +(assert_return (invoke "check" (i32.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i32.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i32.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i32.const 6)) "uninitialized element") +(assert_return (invoke "check" (i32.const 7)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 8)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 9)) (i32.const 1)) +(assert_return (invoke "check" (i32.const 10)) (i32.const 8)) +(assert_trap (invoke "check" (i32.const 11)) "uninitialized element") +(assert_return (invoke "check" (i32.const 12)) (i32.const 7)) +(assert_trap (invoke "check" (i32.const 13)) "uninitialized element") +(assert_return (invoke "check" (i32.const 14)) (i32.const 7)) +(assert_return (invoke "check" (i32.const 15)) (i32.const 5)) +(assert_return (invoke "check" (i32.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i32.const 17)) (i32.const 7)) +(assert_trap (invoke "check" (i32.const 18)) "uninitialized element") +(assert_return (invoke "check" (i32.const 19)) (i32.const 9)) +(assert_trap (invoke "check" (i32.const 20)) "uninitialized element") +(assert_return (invoke "check" (i32.const 21)) (i32.const 7)) +(assert_trap (invoke "check" (i32.const 22)) "uninitialized element") +(assert_return (invoke "check" (i32.const 23)) (i32.const 8)) +(assert_return (invoke "check" (i32.const 24)) (i32.const 8)) +(assert_trap (invoke "check" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i32.const 29)) "uninitialized element") +(assert_invalid + (module + (func (export "test") + (elem.drop 0))) + "unknown elem segment 0") + +(assert_invalid + (module + (func (export "test") + (table.init 0 (i32.const 12) (i32.const 1) (i32.const 1)))) + "unknown table 0") + +(assert_invalid + (module + (elem funcref (ref.func 0)) + (func (result i32) (i32.const 0)) + (func (export "test") + (elem.drop 4))) + "unknown elem segment 4") + +(assert_invalid + (module + (elem funcref (ref.func 0)) + (func (result i32) (i32.const 0)) + (func (export "test") + (table.init 4 (i32.const 12) (i32.const 1) (i32.const 1)))) + "unknown table 0") + + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (elem.drop 2) + )) +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 2 (i32.const 12) (i32.const 1) (i32.const 1)) + )) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 12) (i32.const 1) (i32.const 1)) + (table.init 1 (i32.const 21) (i32.const 1) (i32.const 1)))) +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (elem.drop 1) + (elem.drop 1))) +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (elem.drop 1) + (table.init 1 (i32.const 12) (i32.const 1) (i32.const 1)))) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 12) (i32.const 0) (i32.const 5)) + )) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 12) (i32.const 2) (i32.const 3)) + )) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 28) (i32.const 1) (i32.const 3)) + )) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 12) (i32.const 4) (i32.const 0)) + )) +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 12) (i32.const 5) (i32.const 0)) + )) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 30) (i32.const 2) (i32.const 0)) + )) +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 31) (i32.const 2) (i32.const 0)) + )) +(assert_trap (invoke "test") "out of bounds") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 30) (i32.const 4) (i32.const 0)) + )) +(invoke "test") + +(module + (table 30 30 funcref) + (elem (i32.const 2) 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (i32.const 12) 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.init 1 (i32.const 31) (i32.const 5) (i32.const 0)) + )) +(assert_trap (invoke "test") "out of bounds") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i32.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f32.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (i64.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (table 10 funcref) + (elem funcref (ref.func $f0) (ref.func $f0) (ref.func $f0)) + (func $f0) + (func (export "test") + (table.init 0 (f64.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem funcref + (ref.func $f0) (ref.func $f1) (ref.func $f2) (ref.func $f3) + (ref.func $f4) (ref.func $f5) (ref.func $f6) (ref.func $f7) + (ref.func $f8) (ref.func $f9) (ref.func $f10) (ref.func $f11) + (ref.func $f12) (ref.func $f13) (ref.func $f14) (ref.func $f15)) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $offs i32) (param $len i32) + (table.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) +(assert_trap (invoke "run" (i32.const 24) (i32.const 16)) "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") + +(module + (type (func (result i32))) + (table 32 64 funcref) + (elem funcref + (ref.func $f0) (ref.func $f1) (ref.func $f2) (ref.func $f3) + (ref.func $f4) (ref.func $f5) (ref.func $f6) (ref.func $f7) + (ref.func $f8) (ref.func $f9) (ref.func $f10) (ref.func $f11) + (ref.func $f12) (ref.func $f13) (ref.func $f14) (ref.func $f15)) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $offs i32) (param $len i32) + (table.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) +(assert_trap (invoke "run" (i32.const 25) (i32.const 16)) "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") + +(module + (type (func (result i32))) + (table 160 320 funcref) + (elem funcref + (ref.func $f0) (ref.func $f1) (ref.func $f2) (ref.func $f3) + (ref.func $f4) (ref.func $f5) (ref.func $f6) (ref.func $f7) + (ref.func $f8) (ref.func $f9) (ref.func $f10) (ref.func $f11) + (ref.func $f12) (ref.func $f13) (ref.func $f14) (ref.func $f15)) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $offs i32) (param $len i32) + (table.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) +(assert_trap (invoke "run" (i32.const 96) (i32.const 32)) "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 32)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 33)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 34)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 35)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 36)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 37)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 38)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 39)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 40)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 41)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 42)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 43)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 44)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 45)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 46)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 47)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 48)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 49)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 50)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 51)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 52)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 53)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 54)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 55)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 56)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 57)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 58)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 59)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 60)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 61)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 62)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 63)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 64)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 65)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 66)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 67)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 68)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 69)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 70)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 71)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 72)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 73)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 74)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 75)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 76)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 77)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 78)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 79)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 80)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 81)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 82)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 83)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 84)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 85)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 86)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 87)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 88)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 89)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 90)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 91)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 92)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 93)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 94)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 95)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 96)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 97)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 98)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 99)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 100)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 101)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 102)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 103)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 104)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 105)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 106)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 107)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 108)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 109)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 110)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 111)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 112)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 113)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 114)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 115)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 116)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 117)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 118)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 119)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 120)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 121)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 122)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 123)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 124)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 125)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 126)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 127)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 128)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 129)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 130)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 131)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 132)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 133)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 134)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 135)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 136)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 137)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 138)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 139)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 140)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 141)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 142)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 143)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 144)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 145)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 146)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 147)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 148)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 149)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 150)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 151)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 152)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 153)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 154)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 155)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 156)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 157)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 158)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 159)) "uninitialized element") + +(module + (type (func (result i32))) + (table 160 320 funcref) + (elem funcref + (ref.func $f0) (ref.func $f1) (ref.func $f2) (ref.func $f3) + (ref.func $f4) (ref.func $f5) (ref.func $f6) (ref.func $f7) + (ref.func $f8) (ref.func $f9) (ref.func $f10) (ref.func $f11) + (ref.func $f12) (ref.func $f13) (ref.func $f14) (ref.func $f15)) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $offs i32) (param $len i32) + (table.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) +(assert_trap (invoke "run" (i32.const 97) (i32.const 31)) "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 32)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 33)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 34)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 35)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 36)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 37)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 38)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 39)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 40)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 41)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 42)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 43)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 44)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 45)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 46)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 47)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 48)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 49)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 50)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 51)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 52)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 53)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 54)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 55)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 56)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 57)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 58)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 59)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 60)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 61)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 62)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 63)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 64)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 65)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 66)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 67)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 68)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 69)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 70)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 71)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 72)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 73)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 74)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 75)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 76)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 77)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 78)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 79)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 80)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 81)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 82)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 83)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 84)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 85)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 86)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 87)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 88)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 89)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 90)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 91)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 92)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 93)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 94)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 95)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 96)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 97)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 98)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 99)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 100)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 101)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 102)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 103)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 104)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 105)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 106)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 107)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 108)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 109)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 110)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 111)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 112)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 113)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 114)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 115)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 116)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 117)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 118)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 119)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 120)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 121)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 122)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 123)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 124)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 125)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 126)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 127)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 128)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 129)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 130)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 131)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 132)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 133)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 134)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 135)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 136)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 137)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 138)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 139)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 140)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 141)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 142)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 143)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 144)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 145)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 146)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 147)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 148)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 149)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 150)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 151)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 152)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 153)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 154)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 155)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 156)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 157)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 158)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 159)) "uninitialized element") + +(module + (type (func (result i32))) + (table 64 64 funcref) + (elem funcref + (ref.func $f0) (ref.func $f1) (ref.func $f2) (ref.func $f3) + (ref.func $f4) (ref.func $f5) (ref.func $f6) (ref.func $f7) + (ref.func $f8) (ref.func $f9) (ref.func $f10) (ref.func $f11) + (ref.func $f12) (ref.func $f13) (ref.func $f14) (ref.func $f15)) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $offs i32) (param $len i32) + (table.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) +(assert_trap (invoke "run" (i32.const 48) (i32.const 4294967280)) "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 16)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 17)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 18)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 19)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 20)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 21)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 22)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 23)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 24)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 25)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 26)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 27)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 28)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 29)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 30)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 31)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 32)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 33)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 34)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 35)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 36)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 37)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 38)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 39)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 40)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 41)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 42)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 43)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 44)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 45)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 46)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 47)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 48)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 49)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 50)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 51)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 52)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 53)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 54)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 55)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 56)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 57)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 58)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 59)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 60)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 61)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 62)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 63)) "uninitialized element") + +(module + (type (func (result i32))) + (table 16 16 funcref) + (elem funcref + (ref.func $f0) (ref.func $f1) (ref.func $f2) (ref.func $f3) + (ref.func $f4) (ref.func $f5) (ref.func $f6) (ref.func $f7) + (ref.func $f8) (ref.func $f9) (ref.func $f10) (ref.func $f11) + (ref.func $f12) (ref.func $f13) (ref.func $f14) (ref.func $f15)) + (func $f0 (export "f0") (result i32) (i32.const 0)) + (func $f1 (export "f1") (result i32) (i32.const 1)) + (func $f2 (export "f2") (result i32) (i32.const 2)) + (func $f3 (export "f3") (result i32) (i32.const 3)) + (func $f4 (export "f4") (result i32) (i32.const 4)) + (func $f5 (export "f5") (result i32) (i32.const 5)) + (func $f6 (export "f6") (result i32) (i32.const 6)) + (func $f7 (export "f7") (result i32) (i32.const 7)) + (func $f8 (export "f8") (result i32) (i32.const 8)) + (func $f9 (export "f9") (result i32) (i32.const 9)) + (func $f10 (export "f10") (result i32) (i32.const 10)) + (func $f11 (export "f11") (result i32) (i32.const 11)) + (func $f12 (export "f12") (result i32) (i32.const 12)) + (func $f13 (export "f13") (result i32) (i32.const 13)) + (func $f14 (export "f14") (result i32) (i32.const 14)) + (func $f15 (export "f15") (result i32) (i32.const 15)) + (func (export "test") (param $n i32) (result i32) + (call_indirect (type 0) (local.get $n))) + (func (export "run") (param $offs i32) (param $len i32) + (table.init 0 (local.get $offs) (i32.const 8) (local.get $len)))) +(assert_trap (invoke "run" (i32.const 0) (i32.const 4294967292)) "out of bounds") +(assert_trap (invoke "test" (i32.const 0)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 1)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 2)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 3)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 4)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 5)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 6)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 7)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 8)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 9)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 10)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 11)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 12)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 13)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 14)) "uninitialized element") +(assert_trap (invoke "test" (i32.const 15)) "uninitialized element") + +(module + (table 1 funcref) + ;; 65 elem segments. 64 is the smallest positive number that is encoded + ;; differently as a signed LEB. + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) (elem funcref) (elem funcref) (elem funcref) + (elem funcref) + (func (table.init 64 (i32.const 0) (i32.const 0) (i32.const 0)))) + +(;; STDOUT ;;; +568/568 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/old-spec/elem.txt b/test/wasm2c/old-spec/elem.txt deleted file mode 100644 index 982f07479..000000000 --- a/test/wasm2c/old-spec/elem.txt +++ /dev/null @@ -1,447 +0,0 @@ -;;; TOOL: run-spec-wasm2c -;;; ARGS*: --disable-bulk-memory --disable-reference-types -;; Test the element section - -;; Syntax -(module - (table $t 10 funcref) - (func $f) - (elem (i32.const 0)) - (elem (i32.const 0) $f $f) - (elem (offset (i32.const 0))) - (elem (offset (i32.const 0)) $f $f) - (elem 0 (i32.const 0)) - (elem 0x0 (i32.const 0) $f $f) - (elem 0x000 (offset (i32.const 0))) - (elem 0 (offset (i32.const 0)) $f $f) - (elem $t (i32.const 0)) - (elem $t (i32.const 0) $f $f) - (elem $t (offset (i32.const 0))) - (elem $t (offset (i32.const 0)) $f $f) -) - -;; Basic use - -(module - (table 10 funcref) - (func $f) - (elem (i32.const 0) $f) -) -(module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const 0) $f) -) - -(module - (table 10 funcref) - (func $f) - (elem (i32.const 0) $f) - (elem (i32.const 3) $f) - (elem (i32.const 7) $f) - (elem (i32.const 5) $f) - (elem (i32.const 3) $f) -) -(module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const 9) $f) - (elem (i32.const 3) $f) - (elem (i32.const 7) $f) - (elem (i32.const 3) $f) - (elem (i32.const 5) $f) -) - -(module - (global (import "spectest" "global_i32") i32) - (table 1000 funcref) - (func $f) - (elem (global.get 0) $f) -) - -(module - (global $g (import "spectest" "global_i32") i32) - (table 1000 funcref) - (func $f) - (elem (global.get $g) $f) -) - -(module - (type $out-i32 (func (result i32))) - (table 10 funcref) - (elem (i32.const 7) $const-i32-a) - (elem (i32.const 9) $const-i32-b) - (func $const-i32-a (type $out-i32) (i32.const 65)) - (func $const-i32-b (type $out-i32) (i32.const 66)) - (func (export "call-7") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 7)) - ) - (func (export "call-9") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 9)) - ) -) -(assert_return (invoke "call-7") (i32.const 65)) -(assert_return (invoke "call-9") (i32.const 66)) - -;; Corner cases - -(module - (table 10 funcref) - (func $f) - (elem (i32.const 9) $f) -) -(module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const 9) $f) -) - -(module - (table 0 funcref) - (elem (i32.const 0)) -) -(module - (import "spectest" "table" (table 0 funcref)) - (elem (i32.const 0)) -) - -(module - (table 0 0 funcref) - (elem (i32.const 0)) -) - -(module - (table 20 funcref) - (elem (i32.const 20)) -) - -(module - (import "spectest" "table" (table 0 funcref)) - (func $f) - (elem (i32.const 0) $f) -) - -(module - (import "spectest" "table" (table 0 100 funcref)) - (func $f) - (elem (i32.const 0) $f) -) - -(module - (import "spectest" "table" (table 0 funcref)) - (func $f) - (elem (i32.const 1) $f) -) - -(module - (import "spectest" "table" (table 0 30 funcref)) - (func $f) - (elem (i32.const 1) $f) -) - -;; Invalid bounds for elements - -(assert_unlinkable - (module - (table 0 funcref) - (func $f) - (elem (i32.const 0) $f) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 0 0 funcref) - (func $f) - (elem (i32.const 0) $f) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 0 1 funcref) - (func $f) - (elem (i32.const 0) $f) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 0 funcref) - (elem (i32.const 1)) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 10 funcref) - (func $f) - (elem (i32.const 10) $f) - ) - "elements segment does not fit" -) -(assert_unlinkable - (module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const 10) $f) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 10 20 funcref) - (func $f) - (elem (i32.const 10) $f) - ) - "elements segment does not fit" -) -(assert_unlinkable - (module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const 10) $f) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 10 funcref) - (func $f) - (elem (i32.const -1) $f) - ) - "elements segment does not fit" -) -(assert_unlinkable - (module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const -1) $f) - ) - "elements segment does not fit" -) - -(assert_unlinkable - (module - (table 10 funcref) - (func $f) - (elem (i32.const -10) $f) - ) - "elements segment does not fit" -) -(assert_unlinkable - (module - (import "spectest" "table" (table 10 funcref)) - (func $f) - (elem (i32.const -10) $f) - ) - "elements segment does not fit" -) - -;; Element without table - -(assert_invalid - (module - (func $f) - (elem (i32.const 0) $f) - ) - "unknown table" -) - -;; Invalid offsets - -(assert_invalid - (module - (table 1 funcref) - (elem (i64.const 0)) - ) - "type mismatch" -) - -(assert_invalid - (module - (table 1 funcref) - (elem (offset (;empty instruction sequence;))) - ) - "type mismatch" -) - -(assert_invalid - (module - (table 1 funcref) - (elem (offset (i32.const 0) (i32.const 0))) - ) - "type mismatch" -) - -(assert_invalid - (module - (global (import "test" "global-i32") i32) - (table 1 funcref) - (elem (offset (global.get 0) (global.get 0))) - ) - "type mismatch" -) - -(assert_invalid - (module - (global (import "test" "global-i32") i32) - (table 1 funcref) - (elem (offset (global.get 0) (i32.const 0))) - ) - "type mismatch" -) - - -(assert_invalid - (module - (table 1 funcref) - (elem (i32.ctz (i32.const 0))) - ) - "constant expression required" -) - -(assert_invalid - (module - (table 1 funcref) - (elem (nop)) - ) - "constant expression required" -) - -(assert_invalid - (module - (table 1 funcref) - (elem (offset (nop) (i32.const 0))) - ) - "constant expression required" -) - -(assert_invalid - (module - (table 1 funcref) - (elem (offset (i32.const 0) (nop))) - ) - "constant expression required" -) - -;; Use of internal globals in constant expressions is not allowed in MVP. -;; (assert_invalid -;; (module (memory 1) (data (global.get $g)) (global $g (mut i32) (i32.const 0))) -;; "constant expression required" -;; ) - -(assert_invalid - (module - (table 1 funcref) - (elem (global.get 0)) - ) - "unknown global 0" -) - -(assert_invalid - (module - (global (import "test" "global-i32") i32) - (table 1 funcref) - (elem (global.get 1)) - ) - "unknown global 1" -) - -(assert_invalid - (module - (global (import "test" "global-mut-i32") (mut i32)) - (table 1 funcref) - (elem (global.get 0)) - ) - "constant expression required" -) - -;; Two elements target the same slot - -(module - (type $out-i32 (func (result i32))) - (table 10 funcref) - (elem (i32.const 9) $const-i32-a) - (elem (i32.const 9) $const-i32-b) - (func $const-i32-a (type $out-i32) (i32.const 65)) - (func $const-i32-b (type $out-i32) (i32.const 66)) - (func (export "call-overwritten") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 9)) - ) -) -(assert_return (invoke "call-overwritten") (i32.const 66)) - -(module - (type $out-i32 (func (result i32))) - (import "spectest" "table" (table 10 funcref)) - (elem (i32.const 9) $const-i32-a) - (elem (i32.const 9) $const-i32-b) - (func $const-i32-a (type $out-i32) (i32.const 65)) - (func $const-i32-b (type $out-i32) (i32.const 66)) - (func (export "call-overwritten-element") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 9)) - ) -) -(assert_return (invoke "call-overwritten-element") (i32.const 66)) - -;; Element sections across multiple modules change the same table - -(module $module1 - (type $out-i32 (func (result i32))) - (table (export "shared-table") 10 funcref) - (elem (i32.const 8) $const-i32-a) - (elem (i32.const 9) $const-i32-b) - (func $const-i32-a (type $out-i32) (i32.const 65)) - (func $const-i32-b (type $out-i32) (i32.const 66)) - (func (export "call-7") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 7)) - ) - (func (export "call-8") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 8)) - ) - (func (export "call-9") (type $out-i32) - (call_indirect (type $out-i32) (i32.const 9)) - ) -) - -(register "module1" $module1) - -(assert_trap (invoke $module1 "call-7") "uninitialized element") -(assert_return (invoke $module1 "call-8") (i32.const 65)) -(assert_return (invoke $module1 "call-9") (i32.const 66)) - -(module $module2 - (type $out-i32 (func (result i32))) - (import "module1" "shared-table" (table 10 funcref)) - (elem (i32.const 7) $const-i32-c) - (elem (i32.const 8) $const-i32-d) - (func $const-i32-c (type $out-i32) (i32.const 67)) - (func $const-i32-d (type $out-i32) (i32.const 68)) -) - -(assert_return (invoke $module1 "call-7") (i32.const 67)) -(assert_return (invoke $module1 "call-8") (i32.const 68)) -(assert_return (invoke $module1 "call-9") (i32.const 66)) - -(module $module3 - (type $out-i32 (func (result i32))) - (import "module1" "shared-table" (table 10 funcref)) - (elem (i32.const 8) $const-i32-e) - (elem (i32.const 9) $const-i32-f) - (func $const-i32-e (type $out-i32) (i32.const 69)) - (func $const-i32-f (type $out-i32) (i32.const 70)) -) - -(assert_return (invoke $module1 "call-7") (i32.const 67)) -(assert_return (invoke $module1 "call-8") (i32.const 69)) -(assert_return (invoke $module1 "call-9") (i32.const 70)) -(;; STDOUT ;;; -13/13 tests passed. -;;; STDOUT ;;) diff --git a/test/wasm2c/spec/bulk.txt b/test/wasm2c/spec/bulk.txt new file mode 100644 index 000000000..f5a3891b3 --- /dev/null +++ b/test/wasm2c/spec/bulk.txt @@ -0,0 +1,5 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/bulk.wast +(;; STDOUT ;;; +66/66 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/spec/elem.txt b/test/wasm2c/spec/elem.txt new file mode 100644 index 000000000..498990d35 --- /dev/null +++ b/test/wasm2c/spec/elem.txt @@ -0,0 +1,5 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/elem.wast +(;; STDOUT ;;; +27/27 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/spec/memory_copy.txt b/test/wasm2c/spec/memory_copy.txt new file mode 100644 index 000000000..a585f5454 --- /dev/null +++ b/test/wasm2c/spec/memory_copy.txt @@ -0,0 +1,5 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/memory_copy.wast +(;; STDOUT ;;; +4338/4338 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/spec/memory_fill.txt b/test/wasm2c/spec/memory_fill.txt new file mode 100644 index 000000000..fb5998021 --- /dev/null +++ b/test/wasm2c/spec/memory_fill.txt @@ -0,0 +1,5 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/memory_fill.wast +(;; STDOUT ;;; +20/20 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/spec/memory_init.txt b/test/wasm2c/spec/memory_init.txt new file mode 100644 index 000000000..cd79f1584 --- /dev/null +++ b/test/wasm2c/spec/memory_init.txt @@ -0,0 +1,5 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/memory_init.wast +(;; STDOUT ;;; +140/140 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/spec/multi-memory/load.txt b/test/wasm2c/spec/multi-memory/load.txt new file mode 100644 index 000000000..7618e6b07 --- /dev/null +++ b/test/wasm2c/spec/multi-memory/load.txt @@ -0,0 +1,6 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/load.wast +;;; ARGS*: --enable-multi-memory +(;; STDOUT ;;; +54/54 tests passed. +;;; STDOUT ;;) diff --git a/test/wasm2c/spec/multi-memory/store.txt b/test/wasm2c/spec/multi-memory/store.txt new file mode 100644 index 000000000..a0af00422 --- /dev/null +++ b/test/wasm2c/spec/multi-memory/store.txt @@ -0,0 +1,6 @@ +;;; TOOL: run-spec-wasm2c +;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/store.wast +;;; ARGS*: --enable-multi-memory +(;; STDOUT ;;; +35/35 tests passed. +;;; STDOUT ;;) diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c index 303790f24..24d4e177c 100644 --- a/wasm2c/examples/fac/fac.c +++ b/wasm2c/examples/fac/fac.c @@ -1,6 +1,7 @@ /* Automatically generated by wasm2c */ #include #include +#include #include #if defined(_MSC_VER) #include @@ -456,9 +457,91 @@ static float wasm_sqrtf(float x) { return sqrtf(x); } +static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { + RANGE_CHECK(mem, d, n); + memset(mem->data + d, val, n); +} + +static inline void memory_copy(wasm_rt_memory_t* dest, + const wasm_rt_memory_t* src, + u32 dest_addr, + u32 src_addr, + u32 n) { + RANGE_CHECK(dest, dest_addr, n); + RANGE_CHECK(src, src_addr, n); + memmove(dest->data + dest_addr, src->data + src_addr, n); +} + +static inline void memory_init(wasm_rt_memory_t* dest, + const u8* src, + u32 src_size, + u32 dest_addr, + u32 src_addr, + u32 n) { + if (UNLIKELY(src_addr + (uint64_t)n > src_size)) + TRAP(OOB); + LOAD_DATA((*dest), dest_addr, src + src_addr, n); +} + +typedef struct { + uint32_t func_type_index; + wasm_rt_funcref_t func; + size_t module_offset; +} wasm_elem_segment_expr_t; + +static inline void table_init(wasm_rt_table_t* dest, + const wasm_elem_segment_expr_t* src, + u32 src_size, + u32 dest_addr, + u32 src_addr, + u32 n, + void* module_instance, + const u32* func_types) { + if (UNLIKELY(src_addr + (uint64_t)n > src_size)) + TRAP(OOB); + if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) + TRAP(OOB); + for (u32 i = 0; i < n; i++) { + const wasm_elem_segment_expr_t* src_expr = &src[src_addr + i]; + dest->data[dest_addr + i] = + (wasm_rt_elem_t){func_types[src_expr->func_type_index], src_expr->func, + (char*)module_instance + src_expr->module_offset}; + } +} + +static inline void table_copy(wasm_rt_table_t* dest, + const wasm_rt_table_t* src, + u32 dest_addr, + u32 src_addr, + u32 n) { + if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) + TRAP(OOB); + if (UNLIKELY(src_addr + (uint64_t)n > src->size)) + TRAP(OOB); + + if (n == 0) { + return; + } + + if (dest->data + dest_addr == src->data + src_addr) { + return; + } + + if (dest->data + dest_addr < src->data + src_addr) { + for (u32 i = 0; i < n; i++) { + dest->data[dest_addr + i] = src->data[src_addr + i]; + } + } else { + for (u32 i = n; i > 0; i--) { + dest->data[dest_addr + i - 1] = src->data[src_addr + i - 1]; + } + } +} + static bool s_module_initialized = false; static u32 func_types[1]; + static void init_func_types(void) { func_types[0] = wasm_rt_register_func_type(1, 1, WASM_RT_I32, WASM_RT_I32); } @@ -468,6 +551,21 @@ static void init_tags(void) { static u32 w2c_fac(Z_fac_instance_t*, u32); +static void init_globals(Z_fac_instance_t* instance) { +} + +static void init_memory(Z_fac_instance_t* instance) { +} + +static void init_data_instances(Z_fac_instance_t *instance) { +} + +static void init_table(Z_fac_instance_t* instance) { +} + +static void init_elem_instances(Z_fac_instance_t *instance) { +} + static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) { FUNC_PROLOGUE; u32 w2c_i0, w2c_i1, w2c_i2; @@ -488,15 +586,6 @@ static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) { return w2c_i0; } -static void init_globals(Z_fac_instance_t* instance) { -} -static void init_memory(Z_fac_instance_t* instance) { -} - -static void init_table(Z_fac_instance_t* instance) { - uint32_t offset; -} - /* export: 'fac' */ u32 Z_facZ_fac(Z_fac_instance_t* instance, u32 w2c_p0) { return w2c_fac(instance, w2c_p0); @@ -515,6 +604,8 @@ void Z_fac_instantiate(Z_fac_instance_t* instance) { init_globals(instance); init_memory(instance); init_table(instance); + init_data_instances(instance); + init_elem_instances(instance); } void Z_fac_free(Z_fac_instance_t* instance) { diff --git a/wasm2c/wasm-rt.h b/wasm2c/wasm-rt.h index 7b8ec1f4a..c27905fc5 100644 --- a/wasm2c/wasm-rt.h +++ b/wasm2c/wasm-rt.h @@ -109,8 +109,8 @@ extern uint32_t wasm_rt_call_stack_depth; /** Reason a trap occurred. Provide this to `wasm_rt_trap`. */ typedef enum { - WASM_RT_TRAP_NONE, /** No error. */ - WASM_RT_TRAP_OOB, /** Out-of-bounds access in linear memory. */ + WASM_RT_TRAP_NONE, /** No error. */ + WASM_RT_TRAP_OOB, /** Out-of-bounds access in linear memory or a table. */ WASM_RT_TRAP_INT_OVERFLOW, /** Integer overflow on divide or truncation. */ WASM_RT_TRAP_DIV_BY_ZERO, /** Integer divide by zero. */ WASM_RT_TRAP_INVALID_CONVERSION, /** Conversion from NaN to integer. */ From e9cd029ba39c7be87f79122cf85e369af5f5074a Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Wed, 21 Sep 2022 01:21:37 -0700 Subject: [PATCH 06/10] wasm2c cleanup: eliminate unused initialization functions in output (#1999) also: - cleanup handling of newlines - "init_memory"/"init_table" -> "init_memories"/"init_tables" --- src/c-writer.cc | 142 ++++++++++++++++++++++---------------- wasm2c/examples/fac/fac.c | 24 ------- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/src/c-writer.cc b/src/c-writer.cc index 1270b716b..c38a3c7a3 100644 --- a/src/c-writer.cc +++ b/src/c-writer.cc @@ -945,7 +945,6 @@ void CWriter::WriteSourceTop() { Write(s_source_includes); Write(Newline(), "#include \"", header_name_, "\"", Newline()); Write(s_source_declarations); - Write(Newline()); } void CWriter::WriteMultivalueTypes() { @@ -994,16 +993,15 @@ void CWriter::WriteTagTypes() { } void CWriter::WriteFuncTypes() { - if (module_->types.size()) { - Writef("static u32 func_types[%" PRIzd "];", module_->types.size()); - Write(Newline()); - } - Write(Newline()); - Write("static void init_func_types(void) ", OpenBrace()); - if (!module_->types.size()) { - Write(CloseBrace(), Newline()); + if (module_->types.empty()) { return; } + + Write(Newline()); + Writef("static u32 func_types[%" PRIzd "];", module_->types.size()); + Write(Newline()); + + Write(Newline(), "static void init_func_types(void) ", OpenBrace()); Index func_type_index = 0; for (TypeEntry* type : module_->types) { FuncType* func_type = cast(type); @@ -1035,9 +1033,11 @@ void CWriter::WriteTags() { tag_index++; } - Write(Newline()); + if (module_->tags.empty()) { + return; + } - Write("static void init_tags(void) ", OpenBrace()); + Write(Newline(), "static void init_tags(void) ", OpenBrace()); tag_index = 0; for (const Tag* tag : module_->tags) { @@ -1374,6 +1374,9 @@ void CWriter::WriteTablePtr(const std::string& name) { } void CWriter::WriteGlobalInitializers() { + if (module_->globals.empty()) + return; + Write(Newline(), "static void init_globals(", ModuleInstanceTypeName(), "* instance) ", OpenBrace()); Index global_index = 0; @@ -1411,30 +1414,28 @@ void CWriter::WriteDataInstances() { } void CWriter::WriteDataInitializers() { - if (!module_->memories.empty()) { - if (module_->data_segments.empty()) { - Write(Newline()); - } else { - for (const DataSegment* data_segment : module_->data_segments) { - if (data_segment->data.size()) { - Write(Newline(), "static const u8 data_segment_data_", - GetGlobalName(data_segment->name), "[] = ", OpenBrace()); - size_t i = 0; - for (uint8_t x : data_segment->data) { - Writef("0x%02x, ", x); - if ((++i % 12) == 0) - Write(Newline()); - } - if (i > 0) - Write(Newline()); - Write(CloseBrace(), ";", Newline()); - } + if (module_->memories.empty()) { + return; + } + + for (const DataSegment* data_segment : module_->data_segments) { + if (data_segment->data.size()) { + Write(Newline(), "static const u8 data_segment_data_", + GetGlobalName(data_segment->name), "[] = ", OpenBrace()); + size_t i = 0; + for (uint8_t x : data_segment->data) { + Writef("0x%02x, ", x); + if ((++i % 12) == 0) + Write(Newline()); } + if (i > 0) + Write(Newline()); + Write(CloseBrace(), ";", Newline()); } } - Write("static void init_memory(", ModuleInstanceTypeName(), "* instance) ", - OpenBrace()); + Write(Newline(), "static void init_memories(", ModuleInstanceTypeName(), + "* instance) ", OpenBrace()); if (module_->memories.size() > module_->num_memory_imports) { Index memory_idx = module_->num_memory_imports; for (Index i = memory_idx; i < module_->memories.size(); i++) { @@ -1445,6 +1446,7 @@ void CWriter::WriteDataInitializers() { memory->page_limits.initial, ", ", max, ");", Newline()); } } + for (const DataSegment* data_segment : module_->data_segments) { if (data_segment->kind != SegmentKind::Active) { continue; @@ -1464,17 +1466,19 @@ void CWriter::WriteDataInitializers() { Write(CloseBrace(), Newline()); - Write(Newline(), "static void init_data_instances(", ModuleInstanceTypeName(), - " *instance) ", OpenBrace()); + if (!module_->data_segments.empty()) { + Write(Newline(), "static void init_data_instances(", + ModuleInstanceTypeName(), " *instance) ", OpenBrace()); - for (const DataSegment* data_segment : module_->data_segments) { - if (is_droppable(data_segment)) { - Write("instance->data_segment_dropped_", - GetGlobalName(data_segment->name), " = false;", Newline()); + for (const DataSegment* data_segment : module_->data_segments) { + if (is_droppable(data_segment)) { + Write("instance->data_segment_dropped_", + GetGlobalName(data_segment->name), " = false;", Newline()); + } } - } - Write(CloseBrace(), Newline()); + Write(CloseBrace(), Newline()); + } } void CWriter::WriteElemInstances() { @@ -1488,13 +1492,16 @@ void CWriter::WriteElemInstances() { } void CWriter::WriteElemInitializers() { + if (module_->tables.empty()) { + return; + } + for (const ElemSegment* elem_segment : module_->elem_segments) { if (elem_segment->elem_exprs.empty()) { continue; } - Write(Newline(), - "static const wasm_elem_segment_expr_t elem_segment_exprs_", + Write("static const wasm_elem_segment_expr_t elem_segment_exprs_", GetGlobalName(elem_segment->name), "[] = ", OpenBrace()); for (const ExprList& elem_expr : elem_segment->elem_exprs) { @@ -1527,7 +1534,7 @@ void CWriter::WriteElemInitializers() { Write(CloseBrace(), ";", Newline()); } - Write(Newline(), "static void init_table(", ModuleInstanceTypeName(), + Write(Newline(), "static void init_tables(", ModuleInstanceTypeName(), "* instance) ", OpenBrace()); const Table* table = module_->tables.empty() ? nullptr : module_->tables[0]; @@ -1564,17 +1571,19 @@ void CWriter::WriteElemInitializers() { Write(CloseBrace(), Newline()); - Write(Newline(), "static void init_elem_instances(", ModuleInstanceTypeName(), - " *instance) ", OpenBrace()); + if (!module_->elem_segments.empty()) { + Write(Newline(), "static void init_elem_instances(", + ModuleInstanceTypeName(), " *instance) ", OpenBrace()); - for (const ElemSegment* elem_segment : module_->elem_segments) { - if (is_droppable(elem_segment)) { - Write("instance->elem_segment_dropped_", - GetGlobalName(elem_segment->name), " = false;", Newline()); + for (const ElemSegment* elem_segment : module_->elem_segments) { + if (is_droppable(elem_segment)) { + Write("instance->elem_segment_dropped_", + GetGlobalName(elem_segment->name), " = false;", Newline()); + } } - } - Write(CloseBrace(), Newline()); + Write(CloseBrace(), Newline()); + } } void CWriter::WriteExports(WriteExportsKind kind) { @@ -1649,7 +1658,7 @@ void CWriter::WriteExports(WriteExportsKind kind) { } if (kind == WriteExportsKind::Declarations) { - Write(";"); + Write(";", Newline()); continue; } @@ -1699,8 +1708,12 @@ void CWriter::WriteInit() { OpenBrace()); Write("assert(wasm_rt_is_initialized());", Newline()); Write("s_module_initialized = true;", Newline()); - Write("init_func_types();", Newline()); - Write("init_tags();", Newline()); + if (!module_->types.empty()) { + Write("init_func_types();", Newline()); + } + if (!module_->tags.empty()) { + Write("init_tags();", Newline()); + } Write(CloseBrace(), Newline()); Write(Newline(), "void " + module_prefix_ + "_instantiate(", @@ -1722,11 +1735,22 @@ void CWriter::WriteInit() { Write(");", Newline()); } - Write("init_globals(instance);", Newline()); - Write("init_memory(instance);", Newline()); - Write("init_table(instance);", Newline()); - Write("init_data_instances(instance);", Newline()); - Write("init_elem_instances(instance);", Newline()); + if (!module_->globals.empty()) { + Write("init_globals(instance);", Newline()); + } + if (!module_->memories.empty()) { + Write("init_memories(instance);", Newline()); + } + if (!module_->tables.empty()) { + Write("init_tables(instance);", Newline()); + } + if (!module_->memories.empty() && !module_->data_segments.empty()) { + Write("init_data_instances(instance);", Newline()); + } + if (!module_->tables.empty() && !module_->elem_segments.empty()) { + Write("init_elem_instances(instance);", Newline()); + } + for (Var* var : module_->starts) { Write(ExternalRef(module_->GetFunc(*var)->name)); bool is_import = @@ -3333,7 +3357,7 @@ void CWriter::WriteCHeader() { WriteMultivalueTypes(); WriteImports(); WriteExports(WriteExportsKind::Declarations); - Write(Newline(), s_header_bottom); + Write(s_header_bottom); Write(Newline(), "#endif /* ", guard, " */", Newline()); } diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c index 24d4e177c..8685c40f5 100644 --- a/wasm2c/examples/fac/fac.c +++ b/wasm2c/examples/fac/fac.c @@ -546,26 +546,8 @@ static void init_func_types(void) { func_types[0] = wasm_rt_register_func_type(1, 1, WASM_RT_I32, WASM_RT_I32); } -static void init_tags(void) { -} - static u32 w2c_fac(Z_fac_instance_t*, u32); -static void init_globals(Z_fac_instance_t* instance) { -} - -static void init_memory(Z_fac_instance_t* instance) { -} - -static void init_data_instances(Z_fac_instance_t *instance) { -} - -static void init_table(Z_fac_instance_t* instance) { -} - -static void init_elem_instances(Z_fac_instance_t *instance) { -} - static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) { FUNC_PROLOGUE; u32 w2c_i0, w2c_i1, w2c_i2; @@ -595,17 +577,11 @@ void Z_fac_init_module(void) { assert(wasm_rt_is_initialized()); s_module_initialized = true; init_func_types(); - init_tags(); } void Z_fac_instantiate(Z_fac_instance_t* instance) { assert(wasm_rt_is_initialized()); assert(s_module_initialized); - init_globals(instance); - init_memory(instance); - init_table(instance); - init_data_instances(instance); - init_elem_instances(instance); } void Z_fac_free(Z_fac_instance_t* instance) { From 9703be965ffd275d8e4cebda5e8f3c873ec7054f Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Mon, 26 Sep 2022 12:00:59 -0700 Subject: [PATCH 07/10] code and makefile cleanup of build-standalone example. --- wasm2c/examples/build-standlone/Makefile | 16 +++++----- wasm2c/examples/build-standlone/build.sh | 10 +++---- .../{uvwasi-rt-main.c => wasi-main.c} | 30 +++++-------------- 3 files changed, 20 insertions(+), 36 deletions(-) rename wasm2c/examples/build-standlone/{uvwasi-rt-main.c => wasi-main.c} (56%) diff --git a/wasm2c/examples/build-standlone/Makefile b/wasm2c/examples/build-standlone/Makefile index 44e6ed5b0..bb3333621 100644 --- a/wasm2c/examples/build-standlone/Makefile +++ b/wasm2c/examples/build-standlone/Makefile @@ -8,20 +8,20 @@ UVWASI_PATH=$(WABT_ROOT)/third_party/uvwasi DEPS=-I$(UVWASI_PATH)/include -L$(WABT_ROOT)/build/_deps/libuv-build -L$(WABT_ROOT)/build/third_party/uvwasi -LIBS=-luvwasi_a -luv_a -lpthread -ldl -lm +LIBS=-luvwasi_a -luv_a DBG_FLAGS=-g -REL_FLAGS=-O3 -flto -fomit-frame-pointer -fno-stack-protector +REL_FLAGS=-O3 CFLAGS=$(REL_FLAGS) -all: input.elf +all: main.elf clean: - rm -rf $(ALL_RESULTS) input.* + rm -rf $(ALL_RESULTS) main.* *.elf -input.c: - $(WASM2C) input.wasm -o input.c +main.c: + $(WASM2C) main.wasm -o main.c -input.elf: input.c uvwasi-rt-main.c $(WASM2C_RUNTIME_FILES) - $(CC) $(CFLAGS) input.c uvwasi-rt-main.c -o input.elf -I$(WASM2C_RUNTIME_PATH) $(WASM2C_RUNTIME_FILES) $(DEPS) $(LIBS) +main.elf: main.c wasi-main.c $(WASM2C_RUNTIME_FILES) + $(CC) $(CFLAGS) main.c wasi-main.c -o main.elf -I$(WASM2C_RUNTIME_PATH) $(WASM2C_RUNTIME_FILES) $(DEPS) $(LIBS) diff --git a/wasm2c/examples/build-standlone/build.sh b/wasm2c/examples/build-standlone/build.sh index af64b5f86..cadb98b3b 100755 --- a/wasm2c/examples/build-standlone/build.sh +++ b/wasm2c/examples/build-standlone/build.sh @@ -12,13 +12,13 @@ SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) output_file=$(basename -- "$1") output_file="${output_file%%.*}.elf" -set -v +set -x cd $SCRIPT_DIR make clean -cp ${ORIGIN_DIR}/$1 ./input.wasm -make input.c +cp ${ORIGIN_DIR}/$1 ./main.wasm +make main.c -make input.elf -cp -f input.elf ${ORIGIN_DIR}/${output_file} +make main.elf +cp -f main.elf ${ORIGIN_DIR}/${output_file} diff --git a/wasm2c/examples/build-standlone/uvwasi-rt-main.c b/wasm2c/examples/build-standlone/wasi-main.c similarity index 56% rename from wasm2c/examples/build-standlone/uvwasi-rt-main.c rename to wasm2c/examples/build-standlone/wasi-main.c index c7e2fccd0..d3e60d798 100644 --- a/wasm2c/examples/build-standlone/uvwasi-rt-main.c +++ b/wasm2c/examples/build-standlone/wasi-main.c @@ -3,32 +3,16 @@ #include #include "uvwasi.h" #include "uvwasi-rt.h" - -#define MODULE_NAME input -#define MODULE_HEADER "input.h" -#include MODULE_HEADER - -//force pre-processor expansion of m_name -#define __module_init(m_name) Z_## m_name ##_init_module() -#define module_init(m_name) __module_init(m_name) - -#define __module_instantiate(m_name, instance_p, wasi_p) Z_## m_name ##_instantiate(instance_p, wasi_p) -#define module_instantiate(m_name ,instance_p, wasi_p) __module_instantiate(m_name ,instance_p, wasi_p) - -#define __module_free(m_name, instance_p) Z_## m_name ##_free(instance_p) -#define module_free(m_name, instance_p) __module_free(m_name, instance_p) - -#define __module_start(m_name, instance_p) Z_ ## m_name ## Z__start(instance_p) -#define module_start(m_name, instance_p) __module_start(m_name, instance_p) +#include "main.h" int main(int argc, const char** argv) { - Z_input_instance_t local_instance; + Z_main_instance_t local_instance; uvwasi_t local_uvwasi_state; struct Z_wasi_snapshot_preview1_instance_t wasi_state = { .uvwasi = &local_uvwasi_state, - .instance_memory = &local_instance.w2c_memory + .instance_memory = Z_mainZ_memory(&local_instance), }; uvwasi_options_t init_options; @@ -64,10 +48,10 @@ int main(int argc, const char** argv) exit(1); } - module_init(MODULE_NAME); - module_instantiate(MODULE_NAME, &local_instance, (struct Z_wasi_snapshot_preview1_instance_t *) &wasi_state); - module_start(MODULE_NAME, &local_instance); - module_free(MODULE_NAME, &local_instance); + Z_main_init_module(); + Z_main_instantiate(&local_instance, (struct Z_wasi_snapshot_preview1_instance_t *) &wasi_state); + Z_mainZ__start(&local_instance); + Z_main_free(&local_instance); uvwasi_destroy(&local_uvwasi_state); wasm_rt_free(); From 9e91a3a975753e2df7c28b0fa39e2bd2b7aa99e0 Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Mon, 26 Sep 2022 12:39:42 -0700 Subject: [PATCH 08/10] Preprocessor mess removal. --- wasm2c/uvwasi-rt.c | 258 ++++++++++++++++----------------------------- 1 file changed, 92 insertions(+), 166 deletions(-) diff --git a/wasm2c/uvwasi-rt.c b/wasm2c/uvwasi-rt.c index 162fd03ff..045fc1969 100644 --- a/wasm2c/uvwasi-rt.c +++ b/wasm2c/uvwasi-rt.c @@ -18,24 +18,7 @@ typedef int64_t s64; typedef float f32; typedef double f64; -#ifndef WASM_RT_MODULE_PREFIX -#define WASM_RT_MODULE_PREFIX -#endif - -#define WASM_RT_PASTE_(x, y) x ## y -#define WASM_RT_PASTE(x, y) WASM_RT_PASTE_(x, y) -#define WASM_RT_ADD_PREFIX(x) WASM_RT_PASTE(WASM_RT_MODULE_PREFIX, x) - -#define IMPORT_IMPL(ret, name, params, body) ret name params body - -#define IMPORT_IMPL_WASI_UNSTABLE(ret, name, params, body) IMPORT_IMPL(ret, Z_wasi_unstable##name, params, body) -#define IMPORT_IMPL_WASI_PREVIEW1(ret, name, params, body) IMPORT_IMPL(ret, Z_wasi_snapshot_preview1##name, params, body) - -#define IMPORT_IMPL_WASI_ALL(ret, name, params, body) \ - IMPORT_IMPL_WASI_UNSTABLE(ret, name, params, body) \ - IMPORT_IMPL_WASI_PREVIEW1(ret, name, params, body) - -#define MEMACCESS(addr) ((void*)&WASM_RT_ADD_PREFIX(wp->instance_memory->data[(addr)])) +#define MEMACCESS(addr) ((void*)&wp->instance_memory->data[(addr)]) #define MEM_SET(addr, value, len) memset(MEMACCESS(addr), value, len) #define MEM_WRITE8(addr, value) (*(u8*) MEMACCESS(addr)) = value @@ -52,7 +35,7 @@ typedef double f64; typedef u32 wasm_ptr; -IMPORT_IMPL_WASI_ALL(u32, Z_fd_prestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf), +u32 Z_wasi_snapshot_preview1Z_fd_prestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf) { uvwasi_prestat_t prestat; uvwasi_errno_t ret = uvwasi_fd_prestat_get(wp->uvwasi, fd, &prestat); @@ -61,16 +44,16 @@ IMPORT_IMPL_WASI_ALL(u32, Z_fd_prestat_get, (struct Z_wasi_snapshot_preview1_ins MEM_WRITE32(buf+4, prestat.u.dir.pr_name_len); } return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_prestat_dir_name, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +u32 Z_wasi_snapshot_preview1Z_fd_prestat_dir_name(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) { uvwasi_errno_t ret = uvwasi_fd_prestat_dir_name(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_environ_sizes_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env_count, wasm_ptr env_buf_size), +u32 Z_wasi_snapshot_preview1Z_environ_sizes_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env_count, wasm_ptr env_buf_size) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -80,9 +63,9 @@ IMPORT_IMPL_WASI_ALL(u32, Z_environ_sizes_get, (struct Z_wasi_snapshot_preview1_ MEM_WRITE32(env_buf_size, uvbufsize); } return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_environ_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env, wasm_ptr buf), +u32 Z_wasi_snapshot_preview1Z_environ_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env, wasm_ptr buf) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -114,9 +97,9 @@ IMPORT_IMPL_WASI_ALL(u32, Z_environ_get, (struct Z_wasi_snapshot_preview1_instan free(uvenv); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_args_sizes_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argc, wasm_ptr argv_buf_size), +u32 Z_wasi_snapshot_preview1Z_args_sizes_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argc, wasm_ptr argv_buf_size) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -126,9 +109,9 @@ IMPORT_IMPL_WASI_ALL(u32, Z_args_sizes_get, (struct Z_wasi_snapshot_preview1_ins MEM_WRITE32(argv_buf_size, uvbufsize); } return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_args_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argv, wasm_ptr buf), +u32 Z_wasi_snapshot_preview1Z_args_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argv, wasm_ptr buf) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -160,9 +143,9 @@ IMPORT_IMPL_WASI_ALL(u32, Z_args_get, (struct Z_wasi_snapshot_preview1_instance_ free(uvarg); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat), +u32 Z_wasi_snapshot_preview1Z_fd_fdstat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat) { uvwasi_fdstat_t uvstat; uvwasi_errno_t ret = uvwasi_fd_fdstat_get(wp->uvwasi, fd, &uvstat); @@ -174,47 +157,27 @@ IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_get, (struct Z_wasi_snapshot_preview1_inst MEM_WRITE64(stat+16, uvstat.fs_rights_inheriting); } return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_set_flags, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags), +u32 Z_wasi_snapshot_preview1Z_fd_fdstat_set_flags(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags) { uvwasi_errno_t ret = uvwasi_fd_fdstat_set_flags(wp->uvwasi, fd, flags); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_fdstat_set_rights, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 fs_rights_base, u64 fs_rights_inheriting), +u32 Z_wasi_snapshot_preview1Z_fd_fdstat_set_rights(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 fs_rights_base, u64 fs_rights_inheriting) { uvwasi_errno_t ret = uvwasi_fd_fdstat_set_rights(wp->uvwasi, fd, fs_rights_base, fs_rights_inheriting); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_filestat_set_times, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, u64 atim, u64 mtim, u32 fst_flags), +u32 Z_wasi_snapshot_preview1Z_path_filestat_set_times(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, u64 atim, u64 mtim, u32 fst_flags) { uvwasi_errno_t ret = uvwasi_path_filestat_set_times(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, atim, mtim, fst_flags); return ret; -}); - - - -IMPORT_IMPL_WASI_UNSTABLE(u32, Z_path_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, wasm_ptr stat), -{ - uvwasi_filestat_t uvstat; - uvwasi_errno_t ret = uvwasi_path_filestat_get(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, &uvstat); - if (ret == UVWASI_ESUCCESS) { - MEM_SET(stat, 0, 56); - MEM_WRITE64(stat+0, uvstat.st_dev); - MEM_WRITE64(stat+8, uvstat.st_ino); - MEM_WRITE8 (stat+16, uvstat.st_filetype); - MEM_WRITE32(stat+20, uvstat.st_nlink); - MEM_WRITE64(stat+24, uvstat.st_size); - MEM_WRITE64(stat+32, uvstat.st_atim); - MEM_WRITE64(stat+40, uvstat.st_mtim); - MEM_WRITE64(stat+48, uvstat.st_ctim); - } - return ret; -}); +} -IMPORT_IMPL_WASI_PREVIEW1(u32, Z_path_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, wasm_ptr stat), +u32 Z_wasi_snapshot_preview1Z_path_filestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, wasm_ptr stat) { uvwasi_filestat_t uvstat; uvwasi_errno_t ret = uvwasi_path_filestat_get(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, &uvstat); @@ -230,27 +193,9 @@ IMPORT_IMPL_WASI_PREVIEW1(u32, Z_path_filestat_get, (struct Z_wasi_snapshot_prev MEM_WRITE64(stat+56, uvstat.st_ctim); } return ret; -}); - -IMPORT_IMPL_WASI_UNSTABLE(u32, Z_fd_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat), -{ - uvwasi_filestat_t uvstat; - uvwasi_errno_t ret = uvwasi_fd_filestat_get(wp->uvwasi, fd, &uvstat); - if (ret == UVWASI_ESUCCESS) { - MEM_SET(stat, 0, 56); - MEM_WRITE64(stat+0, uvstat.st_dev); - MEM_WRITE64(stat+8, uvstat.st_ino); - MEM_WRITE8 (stat+16, uvstat.st_filetype); - MEM_WRITE32(stat+20, uvstat.st_nlink); - MEM_WRITE64(stat+24, uvstat.st_size); - MEM_WRITE64(stat+32, uvstat.st_atim); - MEM_WRITE64(stat+40, uvstat.st_mtim); - MEM_WRITE64(stat+48, uvstat.st_ctim); - } - return ret; -}); +} -IMPORT_IMPL_WASI_PREVIEW1(u32, Z_fd_filestat_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat), +u32 Z_wasi_snapshot_preview1Z_fd_filestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat) { uvwasi_filestat_t uvstat; uvwasi_errno_t ret = uvwasi_fd_filestat_get(wp->uvwasi, fd, &uvstat); @@ -266,25 +211,9 @@ IMPORT_IMPL_WASI_PREVIEW1(u32, Z_fd_filestat_get, (struct Z_wasi_snapshot_previe MEM_WRITE64(stat+56, uvstat.st_ctim); } return ret; -}); - - -IMPORT_IMPL_WASI_UNSTABLE(u32, Z_fd_seek, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u32 wasi_whence, wasm_ptr pos), -{ - uvwasi_whence_t whence = -1; - switch (wasi_whence) { - case 0: whence = UVWASI_WHENCE_CUR; break; - case 1: whence = UVWASI_WHENCE_END; break; - case 2: whence = UVWASI_WHENCE_SET; break; - } - - uvwasi_filesize_t uvpos; - uvwasi_errno_t ret = uvwasi_fd_seek(wp->uvwasi, fd, offset, whence, &uvpos); - MEM_WRITE64(pos, uvpos); - return ret; -}); +} -IMPORT_IMPL_WASI_PREVIEW1(u32, Z_fd_seek, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u32 wasi_whence, wasm_ptr pos), +u32 Z_wasi_snapshot_preview1Z_fd_seek(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u32 wasi_whence, wasm_ptr pos) { uvwasi_whence_t whence = -1; switch (wasi_whence) { @@ -297,68 +226,65 @@ IMPORT_IMPL_WASI_PREVIEW1(u32, Z_fd_seek, (struct Z_wasi_snapshot_preview1_insta uvwasi_errno_t ret = uvwasi_fd_seek(wp->uvwasi, fd, offset, whence, &uvpos); MEM_WRITE64(pos, uvpos); return ret; -}); +} - -IMPORT_IMPL_WASI_ALL(u32, Z_fd_tell, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr pos), +u32 Z_wasi_snapshot_preview1Z_fd_tell(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr pos) { uvwasi_filesize_t uvpos; uvwasi_errno_t ret = uvwasi_fd_tell(wp->uvwasi, fd, &uvpos); MEM_WRITE64(pos, uvpos); return ret; -}); - - +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_filestat_set_size, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 filesize), +u32 Z_wasi_snapshot_preview1Z_fd_filestat_set_size(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 filesize) { uvwasi_errno_t ret = uvwasi_fd_filestat_set_size(wp->uvwasi, fd, filesize); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_filestat_set_times, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 atim, u64 mtim, u32 fst_flags), +u32 Z_wasi_snapshot_preview1Z_fd_filestat_set_times(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 atim, u64 mtim, u32 fst_flags) { uvwasi_errno_t ret = uvwasi_fd_filestat_set_times(wp->uvwasi, fd, atim, mtim, fst_flags); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_sync, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd), +u32 Z_wasi_snapshot_preview1Z_fd_sync(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd) { uvwasi_errno_t ret = uvwasi_fd_sync(wp->uvwasi, fd); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_datasync, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd), +u32 Z_wasi_snapshot_preview1Z_fd_datasync(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd) { uvwasi_errno_t ret = uvwasi_fd_datasync(wp->uvwasi, fd); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_renumber, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd_from, u32 fd_to), +u32 Z_wasi_snapshot_preview1Z_fd_renumber(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd_from, u32 fd_to) { uvwasi_errno_t ret = uvwasi_fd_renumber(wp->uvwasi, fd_from, fd_to); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_allocate, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len), +u32 Z_wasi_snapshot_preview1Z_fd_allocate(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len) { uvwasi_errno_t ret = uvwasi_fd_allocate(wp->uvwasi, fd, offset, len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_advise, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len, u32 advice), +u32 Z_wasi_snapshot_preview1Z_fd_advise(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len, u32 advice) { uvwasi_errno_t ret = uvwasi_fd_advise(wp->uvwasi, fd, offset, len, advice); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_open, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 dirfd, u32 dirflags, +u32 Z_wasi_snapshot_preview1Z_path_open(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 dirfd, u32 dirflags, wasm_ptr path, u32 path_len, u32 oflags, u64 fs_rights_base, u64 fs_rights_inheriting, - u32 fs_flags, wasm_ptr fd), + u32 fs_flags, wasm_ptr fd) { uvwasi_fd_t uvfd; uvwasi_errno_t ret = uvwasi_path_open(wp->uvwasi, @@ -373,72 +299,72 @@ IMPORT_IMPL_WASI_ALL(u32, Z_path_open, (struct Z_wasi_snapshot_preview1_instance &uvfd); MEM_WRITE32(fd, uvfd); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_close, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd), { +u32 Z_wasi_snapshot_preview1Z_fd_close(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd) +{ uvwasi_errno_t ret = uvwasi_fd_close(wp->uvwasi, fd); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_symlink, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr old_path, u32 old_path_len, u32 fd, - wasm_ptr new_path, u32 new_path_len), +u32 Z_wasi_snapshot_preview1Z_path_symlink(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr old_path, u32 old_path_len, + u32 fd, wasm_ptr new_path, u32 new_path_len) { uvwasi_errno_t ret = uvwasi_path_symlink(wp->uvwasi, (char*)MEMACCESS(old_path), old_path_len, fd, (char*)MEMACCESS(new_path), new_path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_rename, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, wasm_ptr old_path, u32 old_path_len, - u32 new_fd, wasm_ptr new_path, u32 new_path_len), +u32 Z_wasi_snapshot_preview1Z_path_rename(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, wasm_ptr old_path, + u32 old_path_len, u32 new_fd, wasm_ptr new_path, u32 new_path_len) { uvwasi_errno_t ret = uvwasi_path_rename(wp->uvwasi, old_fd, (char*)MEMACCESS(old_path), old_path_len, new_fd, (char*)MEMACCESS(new_path), new_path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_link, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, u32 old_flags, wasm_ptr old_path, u32 old_path_len, - u32 new_fd, wasm_ptr new_path, u32 new_path_len), +u32 Z_wasi_snapshot_preview1Z_path_link(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, u32 old_flags, + wasm_ptr old_path, u32 old_path_len, u32 new_fd, wasm_ptr new_path, u32 new_path_len) { uvwasi_errno_t ret = uvwasi_path_link(wp->uvwasi, old_fd, old_flags, (char*)MEMACCESS(old_path), old_path_len, new_fd, (char*)MEMACCESS(new_path), new_path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_unlink_file, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +u32 Z_wasi_snapshot_preview1Z_path_unlink_file(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) { uvwasi_errno_t ret = uvwasi_path_unlink_file(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_readlink, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len, - wasm_ptr buf, u32 buf_len, wasm_ptr bufused), +u32 Z_wasi_snapshot_preview1Z_path_readlink(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len, wasm_ptr buf, u32 buf_len, wasm_ptr bufused) { uvwasi_size_t uvbufused; uvwasi_errno_t ret = uvwasi_path_readlink(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len, MEMACCESS(buf), buf_len, &uvbufused); MEM_WRITE32(bufused, uvbufused); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_create_directory, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +u32 Z_wasi_snapshot_preview1Z_path_create_directory(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) { uvwasi_errno_t ret = uvwasi_path_create_directory(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_path_remove_directory, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len), +u32 Z_wasi_snapshot_preview1Z_path_remove_directory(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) { uvwasi_errno_t ret = uvwasi_path_remove_directory(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_readdir, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf, u32 buf_len, u64 cookie, wasm_ptr bufused), +u32 Z_wasi_snapshot_preview1Z_fd_readdir(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf, u32 buf_len, u64 cookie, wasm_ptr bufused) { uvwasi_size_t uvbufused; uvwasi_errno_t ret = uvwasi_fd_readdir(wp->uvwasi, fd, MEMACCESS(buf), buf_len, cookie, &uvbufused); MEM_WRITE32(bufused, uvbufused); return ret; -}); +} typedef struct wasi_iovec_t { @@ -446,7 +372,7 @@ typedef struct wasi_iovec_t uvwasi_size_t buf_len; } wasi_iovec_t; -IMPORT_IMPL_WASI_ALL(u32, Z_fd_write, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nwritten), +u32 Z_wasi_snapshot_preview1Z_fd_write(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nwritten) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -461,15 +387,15 @@ IMPORT_IMPL_WASI_ALL(u32, Z_fd_write, (struct Z_wasi_snapshot_preview1_instance_ iovs[i].buf = MEMACCESS(READ32(&wasi_iovs[i].buf)); iovs[i].buf_len = READ32(&wasi_iovs[i].buf_len); } - + uvwasi_size_t num_written; uvwasi_errno_t ret = uvwasi_fd_write(wp->uvwasi, fd, iovs, iovs_len, &num_written); MEM_WRITE32(nwritten, num_written); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_pwrite, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nwritten), +u32 Z_wasi_snapshot_preview1Z_fd_pwrite(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nwritten) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -489,9 +415,9 @@ IMPORT_IMPL_WASI_ALL(u32, Z_fd_pwrite, (struct Z_wasi_snapshot_preview1_instance uvwasi_errno_t ret = uvwasi_fd_pwrite(wp->uvwasi, fd, iovs, iovs_len, offset, &num_written); MEM_WRITE32(nwritten, num_written); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_read, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nread), +u32 Z_wasi_snapshot_preview1Z_fd_read(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nread) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -512,9 +438,9 @@ IMPORT_IMPL_WASI_ALL(u32, Z_fd_read, (struct Z_wasi_snapshot_preview1_instance_t uvwasi_errno_t ret = uvwasi_fd_read(wp->uvwasi, fd, (const uvwasi_iovec_t *)iovs, iovs_len, &num_read); MEM_WRITE32(nread, num_read); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_fd_pread, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nread), +u32 Z_wasi_snapshot_preview1Z_fd_pread(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nread) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -535,54 +461,54 @@ IMPORT_IMPL_WASI_ALL(u32, Z_fd_pread, (struct Z_wasi_snapshot_preview1_instance_ uvwasi_errno_t ret = uvwasi_fd_pread(wp->uvwasi, fd, (const uvwasi_iovec_t *)iovs, iovs_len, offset, &num_read); MEM_WRITE32(nread, num_read); return ret; -}); +} -// TODO XXX: unstable/snapshot_preview1 compatibility -IMPORT_IMPL_WASI_ALL(u32, Z_poll_oneoff, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr in, wasm_ptr out, u32 nsubscriptions, wasm_ptr nevents), +// TODO XXX: audit, compare with spec +u32 Z_wasi_snapshot_preview1Z_poll_oneoff(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr in, wasm_ptr out, u32 nsubscriptions, wasm_ptr nevents) { uvwasi_size_t uvnevents; uvwasi_errno_t ret = uvwasi_poll_oneoff(wp->uvwasi, MEMACCESS(in), MEMACCESS(out), nsubscriptions, &uvnevents); MEM_WRITE32(nevents, uvnevents); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_clock_res_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, wasm_ptr result), +u32 Z_wasi_snapshot_preview1Z_clock_res_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, wasm_ptr result) { uvwasi_timestamp_t t; uvwasi_errno_t ret = uvwasi_clock_res_get(wp->uvwasi, clk_id, &t); MEM_WRITE64(result, t); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_clock_time_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, u64 precision, wasm_ptr result), +u32 Z_wasi_snapshot_preview1Z_clock_time_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, u64 precision, wasm_ptr result) { uvwasi_timestamp_t t; uvwasi_errno_t ret = uvwasi_clock_time_get(wp->uvwasi, clk_id, precision, &t); MEM_WRITE64(result, t); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_random_get, (struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr buf, u32 buf_len), +u32 Z_wasi_snapshot_preview1Z_random_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr buf, u32 buf_len) { uvwasi_errno_t ret = uvwasi_random_get(wp->uvwasi, MEMACCESS(buf), buf_len); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_sched_yield, (struct Z_wasi_snapshot_preview1_instance_t* wp), +u32 Z_wasi_snapshot_preview1Z_sched_yield(struct Z_wasi_snapshot_preview1_instance_t* wp) { uvwasi_errno_t ret = uvwasi_sched_yield(wp->uvwasi); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(u32, Z_proc_raise, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 sig), +u32 Z_wasi_snapshot_preview1Z_proc_raise(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 sig) { uvwasi_errno_t ret = uvwasi_proc_raise(wp->uvwasi, sig); return ret; -}); +} -IMPORT_IMPL_WASI_ALL(void, Z_proc_exit, (struct Z_wasi_snapshot_preview1_instance_t* wp, u32 code), +void Z_wasi_snapshot_preview1Z_proc_exit(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 code) { uvwasi_destroy(wp->uvwasi); exit(code); -}); +} From 5509923ea24e38e673270c1a3ff2f0eef7fa7336 Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Mon, 26 Sep 2022 13:15:14 -0700 Subject: [PATCH 09/10] replace wasm types with std c types --- wasm2c/uvwasi-rt.c | 126 ++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 69 deletions(-) diff --git a/wasm2c/uvwasi-rt.c b/wasm2c/uvwasi-rt.c index 045fc1969..d1f0cf363 100644 --- a/wasm2c/uvwasi-rt.c +++ b/wasm2c/uvwasi-rt.c @@ -7,35 +7,23 @@ #include "uvwasi.h" #include "uvwasi-rt.h" -typedef uint8_t u8; -typedef int8_t s8; -typedef uint16_t u16; -typedef int16_t s16; -typedef uint32_t u32; -typedef int32_t s32; -typedef uint64_t u64; -typedef int64_t s64; -typedef float f32; -typedef double f64; - #define MEMACCESS(addr) ((void*)&wp->instance_memory->data[(addr)]) #define MEM_SET(addr, value, len) memset(MEMACCESS(addr), value, len) -#define MEM_WRITE8(addr, value) (*(u8*) MEMACCESS(addr)) = value -#define MEM_WRITE16(addr, value) (*(u16*)MEMACCESS(addr)) = value -#define MEM_WRITE32(addr, value) (*(u32*)MEMACCESS(addr)) = value -#define MEM_WRITE64(addr, value) (*(u64*)MEMACCESS(addr)) = value +#define MEM_WRITE8(addr, value) (*(uint8_t*) MEMACCESS(addr)) = value +#define MEM_WRITE16(addr, value) (*(uint16_t*)MEMACCESS(addr)) = value +#define MEM_WRITE32(addr, value) (*(uint32_t*)MEMACCESS(addr)) = value +#define MEM_WRITE64(addr, value) (*(uint64_t*)MEMACCESS(addr)) = value -#define MEM_READ32(addr) (*(u32*)MEMACCESS(addr)) -#define READ32(x) (*(u32*)(x)) +#define MEM_READ32(addr) (*(uint32_t*)MEMACCESS(addr)) +#define READ32(x) (*(uint32_t*)(x)) // XXX TODO: Add linear memory boundary checks +typedef uint32_t wasm_ptr; -typedef u32 wasm_ptr; - -u32 Z_wasi_snapshot_preview1Z_fd_prestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf) +uint32_t Z_wasi_snapshot_preview1Z_fd_prestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr buf) { uvwasi_prestat_t prestat; uvwasi_errno_t ret = uvwasi_fd_prestat_get(wp->uvwasi, fd, &prestat); @@ -47,13 +35,13 @@ u32 Z_wasi_snapshot_preview1Z_fd_prestat_get(struct Z_wasi_snapshot_preview1_ins } -u32 Z_wasi_snapshot_preview1Z_fd_prestat_dir_name(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) +uint32_t Z_wasi_snapshot_preview1Z_fd_prestat_dir_name(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr path, uint32_t path_len) { uvwasi_errno_t ret = uvwasi_fd_prestat_dir_name(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_environ_sizes_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env_count, wasm_ptr env_buf_size) +uint32_t Z_wasi_snapshot_preview1Z_environ_sizes_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env_count, wasm_ptr env_buf_size) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -65,7 +53,7 @@ u32 Z_wasi_snapshot_preview1Z_environ_sizes_get(struct Z_wasi_snapshot_preview1_ return ret; } -u32 Z_wasi_snapshot_preview1Z_environ_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env, wasm_ptr buf) +uint32_t Z_wasi_snapshot_preview1Z_environ_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr env, wasm_ptr buf) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -88,7 +76,7 @@ u32 Z_wasi_snapshot_preview1Z_environ_get(struct Z_wasi_snapshot_preview1_instan return ret; } - for (u32 i = 0; i < uvcount; ++i) + for (uint32_t i = 0; i < uvcount; ++i) { uint32_t offset = buf + (uvenv[i] - uvenv[0]); MEM_WRITE32(env+(i*sizeof(wasm_ptr)), offset); @@ -99,7 +87,7 @@ u32 Z_wasi_snapshot_preview1Z_environ_get(struct Z_wasi_snapshot_preview1_instan return ret; } -u32 Z_wasi_snapshot_preview1Z_args_sizes_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argc, wasm_ptr argv_buf_size) +uint32_t Z_wasi_snapshot_preview1Z_args_sizes_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argc, wasm_ptr argv_buf_size) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -111,7 +99,7 @@ u32 Z_wasi_snapshot_preview1Z_args_sizes_get(struct Z_wasi_snapshot_preview1_ins return ret; } -u32 Z_wasi_snapshot_preview1Z_args_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argv, wasm_ptr buf) +uint32_t Z_wasi_snapshot_preview1Z_args_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr argv, wasm_ptr buf) { uvwasi_size_t uvcount; uvwasi_size_t uvbufsize; @@ -134,7 +122,7 @@ u32 Z_wasi_snapshot_preview1Z_args_get(struct Z_wasi_snapshot_preview1_instance_ return ret; } - for (u32 i = 0; i < uvcount; ++i) + for (uint32_t i = 0; i < uvcount; ++i) { uint32_t offset = buf + (uvarg[i] - uvarg[0]); MEM_WRITE32(argv+(i*sizeof(wasm_ptr)), offset); @@ -145,7 +133,7 @@ u32 Z_wasi_snapshot_preview1Z_args_get(struct Z_wasi_snapshot_preview1_instance_ return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_fdstat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat) +uint32_t Z_wasi_snapshot_preview1Z_fd_fdstat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr stat) { uvwasi_fdstat_t uvstat; uvwasi_errno_t ret = uvwasi_fd_fdstat_get(wp->uvwasi, fd, &uvstat); @@ -159,25 +147,25 @@ u32 Z_wasi_snapshot_preview1Z_fd_fdstat_get(struct Z_wasi_snapshot_preview1_inst return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_fdstat_set_flags(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags) +uint32_t Z_wasi_snapshot_preview1Z_fd_fdstat_set_flags(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint32_t flags) { uvwasi_errno_t ret = uvwasi_fd_fdstat_set_flags(wp->uvwasi, fd, flags); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_fdstat_set_rights(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 fs_rights_base, u64 fs_rights_inheriting) +uint32_t Z_wasi_snapshot_preview1Z_fd_fdstat_set_rights(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint64_t fs_rights_base, uint64_t fs_rights_inheriting) { uvwasi_errno_t ret = uvwasi_fd_fdstat_set_rights(wp->uvwasi, fd, fs_rights_base, fs_rights_inheriting); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_filestat_set_times(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, u64 atim, u64 mtim, u32 fst_flags) +uint32_t Z_wasi_snapshot_preview1Z_path_filestat_set_times(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint32_t flags, wasm_ptr path, uint32_t path_len, uint64_t atim, uint64_t mtim, uint32_t fst_flags) { uvwasi_errno_t ret = uvwasi_path_filestat_set_times(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, atim, mtim, fst_flags); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_filestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u32 flags, wasm_ptr path, u32 path_len, wasm_ptr stat) +uint32_t Z_wasi_snapshot_preview1Z_path_filestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint32_t flags, wasm_ptr path, uint32_t path_len, wasm_ptr stat) { uvwasi_filestat_t uvstat; uvwasi_errno_t ret = uvwasi_path_filestat_get(wp->uvwasi, fd, flags, (char*)MEMACCESS(path), path_len, &uvstat); @@ -195,7 +183,7 @@ u32 Z_wasi_snapshot_preview1Z_path_filestat_get(struct Z_wasi_snapshot_preview1_ return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_filestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr stat) +uint32_t Z_wasi_snapshot_preview1Z_fd_filestat_get(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr stat) { uvwasi_filestat_t uvstat; uvwasi_errno_t ret = uvwasi_fd_filestat_get(wp->uvwasi, fd, &uvstat); @@ -213,7 +201,7 @@ u32 Z_wasi_snapshot_preview1Z_fd_filestat_get(struct Z_wasi_snapshot_preview1_in return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_seek(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u32 wasi_whence, wasm_ptr pos) +uint32_t Z_wasi_snapshot_preview1Z_fd_seek(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint64_t offset, uint32_t wasi_whence, wasm_ptr pos) { uvwasi_whence_t whence = -1; switch (wasi_whence) { @@ -228,7 +216,7 @@ u32 Z_wasi_snapshot_preview1Z_fd_seek(struct Z_wasi_snapshot_preview1_instance_t return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_tell(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr pos) +uint32_t Z_wasi_snapshot_preview1Z_fd_tell(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr pos) { uvwasi_filesize_t uvpos; uvwasi_errno_t ret = uvwasi_fd_tell(wp->uvwasi, fd, &uvpos); @@ -237,54 +225,54 @@ u32 Z_wasi_snapshot_preview1Z_fd_tell(struct Z_wasi_snapshot_preview1_instance_t } -u32 Z_wasi_snapshot_preview1Z_fd_filestat_set_size(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 filesize) +uint32_t Z_wasi_snapshot_preview1Z_fd_filestat_set_size(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint64_t filesize) { uvwasi_errno_t ret = uvwasi_fd_filestat_set_size(wp->uvwasi, fd, filesize); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_filestat_set_times(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 atim, u64 mtim, u32 fst_flags) +uint32_t Z_wasi_snapshot_preview1Z_fd_filestat_set_times(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint64_t atim, uint64_t mtim, uint32_t fst_flags) { uvwasi_errno_t ret = uvwasi_fd_filestat_set_times(wp->uvwasi, fd, atim, mtim, fst_flags); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_sync(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd) +uint32_t Z_wasi_snapshot_preview1Z_fd_sync(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd) { uvwasi_errno_t ret = uvwasi_fd_sync(wp->uvwasi, fd); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_datasync(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd) +uint32_t Z_wasi_snapshot_preview1Z_fd_datasync(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd) { uvwasi_errno_t ret = uvwasi_fd_datasync(wp->uvwasi, fd); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_renumber(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd_from, u32 fd_to) +uint32_t Z_wasi_snapshot_preview1Z_fd_renumber(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd_from, uint32_t fd_to) { uvwasi_errno_t ret = uvwasi_fd_renumber(wp->uvwasi, fd_from, fd_to); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_allocate(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len) +uint32_t Z_wasi_snapshot_preview1Z_fd_allocate(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint64_t offset, uint64_t len) { uvwasi_errno_t ret = uvwasi_fd_allocate(wp->uvwasi, fd, offset, len); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_advise(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, u64 offset, u64 len, u32 advice) +uint32_t Z_wasi_snapshot_preview1Z_fd_advise(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, uint64_t offset, uint64_t len, uint32_t advice) { uvwasi_errno_t ret = uvwasi_fd_advise(wp->uvwasi, fd, offset, len, advice); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_open(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 dirfd, u32 dirflags, - wasm_ptr path, u32 path_len, - u32 oflags, u64 fs_rights_base, u64 fs_rights_inheriting, - u32 fs_flags, wasm_ptr fd) +uint32_t Z_wasi_snapshot_preview1Z_path_open(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t dirfd, uint32_t dirflags, + wasm_ptr path, uint32_t path_len, + uint32_t oflags, uint64_t fs_rights_base, uint64_t fs_rights_inheriting, + uint32_t fs_flags, wasm_ptr fd) { uvwasi_fd_t uvfd; uvwasi_errno_t ret = uvwasi_path_open(wp->uvwasi, @@ -301,43 +289,43 @@ u32 Z_wasi_snapshot_preview1Z_path_open(struct Z_wasi_snapshot_preview1_instance return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_close(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd) +uint32_t Z_wasi_snapshot_preview1Z_fd_close(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd) { uvwasi_errno_t ret = uvwasi_fd_close(wp->uvwasi, fd); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_symlink(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr old_path, u32 old_path_len, - u32 fd, wasm_ptr new_path, u32 new_path_len) +uint32_t Z_wasi_snapshot_preview1Z_path_symlink(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr old_path, uint32_t old_path_len, + uint32_t fd, wasm_ptr new_path, uint32_t new_path_len) { uvwasi_errno_t ret = uvwasi_path_symlink(wp->uvwasi, (char*)MEMACCESS(old_path), old_path_len, fd, (char*)MEMACCESS(new_path), new_path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_rename(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, wasm_ptr old_path, - u32 old_path_len, u32 new_fd, wasm_ptr new_path, u32 new_path_len) +uint32_t Z_wasi_snapshot_preview1Z_path_rename(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t old_fd, wasm_ptr old_path, + uint32_t old_path_len, uint32_t new_fd, wasm_ptr new_path, uint32_t new_path_len) { uvwasi_errno_t ret = uvwasi_path_rename(wp->uvwasi, old_fd, (char*)MEMACCESS(old_path), old_path_len, new_fd, (char*)MEMACCESS(new_path), new_path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_link(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 old_fd, u32 old_flags, - wasm_ptr old_path, u32 old_path_len, u32 new_fd, wasm_ptr new_path, u32 new_path_len) +uint32_t Z_wasi_snapshot_preview1Z_path_link(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t old_fd, uint32_t old_flags, + wasm_ptr old_path, uint32_t old_path_len, uint32_t new_fd, wasm_ptr new_path, uint32_t new_path_len) { uvwasi_errno_t ret = uvwasi_path_link(wp->uvwasi, old_fd, old_flags, (char*)MEMACCESS(old_path), old_path_len, new_fd, (char*)MEMACCESS(new_path), new_path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_unlink_file(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) +uint32_t Z_wasi_snapshot_preview1Z_path_unlink_file(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr path, uint32_t path_len) { uvwasi_errno_t ret = uvwasi_path_unlink_file(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_readlink(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len, wasm_ptr buf, u32 buf_len, wasm_ptr bufused) +uint32_t Z_wasi_snapshot_preview1Z_path_readlink(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr path, uint32_t path_len, wasm_ptr buf, uint32_t buf_len, wasm_ptr bufused) { uvwasi_size_t uvbufused; uvwasi_errno_t ret = uvwasi_path_readlink(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len, MEMACCESS(buf), buf_len, &uvbufused); @@ -346,19 +334,19 @@ u32 Z_wasi_snapshot_preview1Z_path_readlink(struct Z_wasi_snapshot_preview1_inst return ret; } -u32 Z_wasi_snapshot_preview1Z_path_create_directory(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) +uint32_t Z_wasi_snapshot_preview1Z_path_create_directory(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr path, uint32_t path_len) { uvwasi_errno_t ret = uvwasi_path_create_directory(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_path_remove_directory(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr path, u32 path_len) +uint32_t Z_wasi_snapshot_preview1Z_path_remove_directory(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr path, uint32_t path_len) { uvwasi_errno_t ret = uvwasi_path_remove_directory(wp->uvwasi, fd, (char*)MEMACCESS(path), path_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_readdir(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr buf, u32 buf_len, u64 cookie, wasm_ptr bufused) +uint32_t Z_wasi_snapshot_preview1Z_fd_readdir(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr buf, uint32_t buf_len, uint64_t cookie, wasm_ptr bufused) { uvwasi_size_t uvbufused; uvwasi_errno_t ret = uvwasi_fd_readdir(wp->uvwasi, fd, MEMACCESS(buf), buf_len, cookie, &uvbufused); @@ -372,7 +360,7 @@ typedef struct wasi_iovec_t uvwasi_size_t buf_len; } wasi_iovec_t; -u32 Z_wasi_snapshot_preview1Z_fd_write(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nwritten) +uint32_t Z_wasi_snapshot_preview1Z_fd_write(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr iovs_offset, uint32_t iovs_len, wasm_ptr nwritten) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -395,7 +383,7 @@ u32 Z_wasi_snapshot_preview1Z_fd_write(struct Z_wasi_snapshot_preview1_instance_ } -u32 Z_wasi_snapshot_preview1Z_fd_pwrite(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nwritten) +uint32_t Z_wasi_snapshot_preview1Z_fd_pwrite(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr iovs_offset, uint32_t iovs_len, uint64_t offset, wasm_ptr nwritten) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -417,7 +405,7 @@ u32 Z_wasi_snapshot_preview1Z_fd_pwrite(struct Z_wasi_snapshot_preview1_instance return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_read(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, wasm_ptr nread) +uint32_t Z_wasi_snapshot_preview1Z_fd_read(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr iovs_offset, uint32_t iovs_len, wasm_ptr nread) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -440,7 +428,7 @@ u32 Z_wasi_snapshot_preview1Z_fd_read(struct Z_wasi_snapshot_preview1_instance_t return ret; } -u32 Z_wasi_snapshot_preview1Z_fd_pread(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 fd, wasm_ptr iovs_offset, u32 iovs_len, u64 offset, wasm_ptr nread) +uint32_t Z_wasi_snapshot_preview1Z_fd_pread(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t fd, wasm_ptr iovs_offset, uint32_t iovs_len, uint64_t offset, wasm_ptr nread) { wasi_iovec_t * wasi_iovs = (wasi_iovec_t *)MEMACCESS(iovs_offset); @@ -464,7 +452,7 @@ u32 Z_wasi_snapshot_preview1Z_fd_pread(struct Z_wasi_snapshot_preview1_instance_ } // TODO XXX: audit, compare with spec -u32 Z_wasi_snapshot_preview1Z_poll_oneoff(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr in, wasm_ptr out, u32 nsubscriptions, wasm_ptr nevents) +uint32_t Z_wasi_snapshot_preview1Z_poll_oneoff(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr in, wasm_ptr out, uint32_t nsubscriptions, wasm_ptr nevents) { uvwasi_size_t uvnevents; uvwasi_errno_t ret = uvwasi_poll_oneoff(wp->uvwasi, MEMACCESS(in), MEMACCESS(out), nsubscriptions, &uvnevents); @@ -473,7 +461,7 @@ u32 Z_wasi_snapshot_preview1Z_poll_oneoff(struct Z_wasi_snapshot_preview1_instan } -u32 Z_wasi_snapshot_preview1Z_clock_res_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, wasm_ptr result) +uint32_t Z_wasi_snapshot_preview1Z_clock_res_get(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t clk_id, wasm_ptr result) { uvwasi_timestamp_t t; uvwasi_errno_t ret = uvwasi_clock_res_get(wp->uvwasi, clk_id, &t); @@ -481,7 +469,7 @@ u32 Z_wasi_snapshot_preview1Z_clock_res_get(struct Z_wasi_snapshot_preview1_inst return ret; } -u32 Z_wasi_snapshot_preview1Z_clock_time_get(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 clk_id, u64 precision, wasm_ptr result) +uint32_t Z_wasi_snapshot_preview1Z_clock_time_get(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t clk_id, uint64_t precision, wasm_ptr result) { uvwasi_timestamp_t t; uvwasi_errno_t ret = uvwasi_clock_time_get(wp->uvwasi, clk_id, precision, &t); @@ -489,25 +477,25 @@ u32 Z_wasi_snapshot_preview1Z_clock_time_get(struct Z_wasi_snapshot_preview1_ins return ret; } -u32 Z_wasi_snapshot_preview1Z_random_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr buf, u32 buf_len) +uint32_t Z_wasi_snapshot_preview1Z_random_get(struct Z_wasi_snapshot_preview1_instance_t* wp, wasm_ptr buf, uint32_t buf_len) { uvwasi_errno_t ret = uvwasi_random_get(wp->uvwasi, MEMACCESS(buf), buf_len); return ret; } -u32 Z_wasi_snapshot_preview1Z_sched_yield(struct Z_wasi_snapshot_preview1_instance_t* wp) +uint32_t Z_wasi_snapshot_preview1Z_sched_yield(struct Z_wasi_snapshot_preview1_instance_t* wp) { uvwasi_errno_t ret = uvwasi_sched_yield(wp->uvwasi); return ret; } -u32 Z_wasi_snapshot_preview1Z_proc_raise(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 sig) +uint32_t Z_wasi_snapshot_preview1Z_proc_raise(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t sig) { uvwasi_errno_t ret = uvwasi_proc_raise(wp->uvwasi, sig); return ret; } -void Z_wasi_snapshot_preview1Z_proc_exit(struct Z_wasi_snapshot_preview1_instance_t* wp, u32 code) +void Z_wasi_snapshot_preview1Z_proc_exit(struct Z_wasi_snapshot_preview1_instance_t* wp, uint32_t code) { uvwasi_destroy(wp->uvwasi); exit(code); From fe560a24feff1a9e553de75838502af9ddeb97d5 Mon Sep 17 00:00:00 2001 From: Tal Garfinkel Date: Mon, 10 Oct 2022 14:42:04 -0700 Subject: [PATCH 10/10] use absolute paths as input to build.sh --- wasm2c/examples/build-standlone/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm2c/examples/build-standlone/build.sh b/wasm2c/examples/build-standlone/build.sh index cadb98b3b..e3b2511af 100755 --- a/wasm2c/examples/build-standlone/build.sh +++ b/wasm2c/examples/build-standlone/build.sh @@ -17,7 +17,7 @@ set -x cd $SCRIPT_DIR make clean -cp ${ORIGIN_DIR}/$1 ./main.wasm +cp $1 ./main.wasm make main.c make main.elf