diff options
author | Shravan Narayan <shravanrn@gmail.com> | 2024-06-26 11:30:44 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-26 09:30:44 -0700 |
commit | 0e871afa4aaac9fe0b1f00cb42a59be666657a06 (patch) | |
tree | 22c449953033d0ea98200d9117c11419054a762e /wasm2c/benchmarks/dhrystone/main.c | |
parent | f820d171654de2dcb8cbf7078b4c98336c8e3c69 (diff) | |
download | wabt-0e871afa4aaac9fe0b1f00cb42a59be666657a06.tar.gz wabt-0e871afa4aaac9fe0b1f00cb42a59be666657a06.tar.bz2 wabt-0e871afa4aaac9fe0b1f00cb42a59be666657a06.zip |
wasm2c: Segue optimization for modules with a single unshared memory (#2395)
Diffstat (limited to 'wasm2c/benchmarks/dhrystone/main.c')
-rw-r--r-- | wasm2c/benchmarks/dhrystone/main.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/wasm2c/benchmarks/dhrystone/main.c b/wasm2c/benchmarks/dhrystone/main.c new file mode 100644 index 00000000..5f7350e4 --- /dev/null +++ b/wasm2c/benchmarks/dhrystone/main.c @@ -0,0 +1,265 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include "uvwasi.h" + +#include "dhrystone.h" + +struct w2c_wasi__snapshot__preview1 { + wasm_rt_memory_t* w2c_memory; + uvwasi_t* uvwasi; +}; + +#define WASI_SUCCESS 0 +#define WASI_BADF_ERROR 8 + +typedef uint32_t u32; +typedef uint64_t u64; + +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + +#define MEM_ADDR_MEMOP(mem, addr, n) MEM_ADDR(mem, addr, n) + +#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) + +#define RANGE_CHECK(mem, offset, len) \ + if (offset + (uint64_t)len > mem->size) \ + TRAP(OOB); + +static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { + RANGE_CHECK(mem, d, n); + memset(MEM_ADDR(mem, d, n), val, n); +} + +#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, sizeof(t)) + +#ifdef __GNUC__ +#define FORCE_READ_INT(var) __asm__("" ::"r"(var)); +#else +#define FORCE_READ_INT(var) +#endif + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR_MEMOP(mem, addr, sizeof(t1)), \ + sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ + } + +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR_MEMOP(mem, addr, sizeof(t1)), &wrapped, \ + sizeof(t1)); \ + } + +DEFINE_LOAD(i8_load, u8, u8, u8, FORCE_READ_INT) +DEFINE_LOAD(i16_load, u16, u16, u16, FORCE_READ_INT) +DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) +DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) +DEFINE_STORE(i8_store, u8, u8) +DEFINE_STORE(i16_store, u16, u16) +DEFINE_STORE(i32_store, u32, u32) +DEFINE_STORE(i64_store, u64, u64) + +u32 w2c_wasi__snapshot__preview1_args_get( + struct w2c_wasi__snapshot__preview1* a, + u32 b, + u32 c) { + return WASI_SUCCESS; +} +u32 w2c_wasi__snapshot__preview1_args_sizes_get( + struct w2c_wasi__snapshot__preview1* a, + u32 str_count, + u32 buff_size) { + i32_store(a->w2c_memory, str_count, 0); + i32_store(a->w2c_memory, buff_size, 0); + return WASI_SUCCESS; +} +u32 w2c_wasi__snapshot__preview1_fd_prestat_get( + struct w2c_wasi__snapshot__preview1* a, + u32 b, + u32 c) { + return WASI_BADF_ERROR; +} + +u32 w2c_wasi__snapshot__preview1_fd_write( + struct w2c_wasi__snapshot__preview1* a, + u32 fd, + u32 iovs_offset, + u32 iovs_len, + u32 nwritten) { + if (iovs_len > 32) + return UVWASI_EINVAL; + uvwasi_ciovec_t iovs[iovs_len]; + + for (uvwasi_size_t i = 0; i < iovs_len; ++i) { + u32 wasi_iovs_i = iovs_offset + i * sizeof(uvwasi_size_t[2]); + u32 buf_loc = i32_load(a->w2c_memory, wasi_iovs_i); + u32 buf_len = i32_load(a->w2c_memory, wasi_iovs_i + sizeof(uvwasi_size_t)); + iovs[i].buf = MEM_ADDR(a->w2c_memory, buf_loc, buf_len); + iovs[i].buf_len = buf_len; + } + + uvwasi_size_t num_written; + uvwasi_errno_t ret = + uvwasi_fd_write(a->uvwasi, fd, iovs, iovs_len, &num_written); + i32_store(a->w2c_memory, nwritten, num_written); + return ret; +} + +uint32_t w2c_wasi__snapshot__preview1_fd_fdstat_get( + struct w2c_wasi__snapshot__preview1* a, + u32 fd, + u32 stat) { + uvwasi_fdstat_t uvstat; + uvwasi_errno_t ret = uvwasi_fd_fdstat_get(a->uvwasi, fd, &uvstat); + if (ret == UVWASI_ESUCCESS) { + memory_fill(a->w2c_memory, stat, 0, 24); + i8_store(a->w2c_memory, stat, uvstat.fs_filetype); + i16_store(a->w2c_memory, stat + 2, uvstat.fs_flags); + i64_store(a->w2c_memory, stat + 8, uvstat.fs_rights_base); + i64_store(a->w2c_memory, stat + 16, uvstat.fs_rights_inheriting); + } + return ret; +} + +u32 w2c_wasi__snapshot__preview1_clock_time_get( + struct w2c_wasi__snapshot__preview1* a, + u32 clk_id, + u64 precision, + u32 result) { + uvwasi_timestamp_t t; + uvwasi_errno_t ret = uvwasi_clock_time_get(a->uvwasi, clk_id, precision, &t); + i64_store(a->w2c_memory, result, t); + return ret; +} + +u32 w2c_wasi__snapshot__preview1_clock_res_get( + struct w2c_wasi__snapshot__preview1* a, + u32 clk_id, + u32 result) { + uvwasi_timestamp_t t; + uvwasi_errno_t ret = uvwasi_clock_res_get(a->uvwasi, clk_id, &t); + i64_store(a->w2c_memory, result, t); + return ret; +} + +u32 w2c_wasi__snapshot__preview1_fd_seek(struct w2c_wasi__snapshot__preview1* a, + u32 b, + u64 c, + u32 d, + u32 e) { + printf("fd_seek not implemented\n"); + abort(); +} +u32 w2c_wasi__snapshot__preview1_fd_read(struct w2c_wasi__snapshot__preview1* a, + u32 b, + u32 c, + u32 d, + u32 e) { + printf("fd_read not implemented\n"); + abort(); +} +u32 w2c_wasi__snapshot__preview1_fd_close( + struct w2c_wasi__snapshot__preview1* a, + u32 b) { + printf("fd_close not implemented\n"); + abort(); +} +u32 w2c_wasi__snapshot__preview1_fd_fdstat_set_flags( + struct w2c_wasi__snapshot__preview1* a, + u32 b, + u32 c) { + printf("fd_fdstat_set_flags not implemented\n"); + abort(); +} +u32 w2c_wasi__snapshot__preview1_fd_prestat_dir_name( + struct w2c_wasi__snapshot__preview1* a, + u32 b, + u32 c, + u32 d) { + printf("fd_prestat_dir_name not implemented\n"); + abort(); +} +u32 w2c_wasi__snapshot__preview1_path_open( + struct w2c_wasi__snapshot__preview1* a, + u32 b, + u32 c, + u32 d, + u32 e, + u32 f, + u64 g, + u64 h, + u32 i, + u32 end) { + printf("path_open not implemented\n"); + abort(); +} +void w2c_wasi__snapshot__preview1_proc_exit( + struct w2c_wasi__snapshot__preview1* a, + u32 b) { + printf("proc_exit not implemented\n"); + abort(); +} + +int main(int argc, char const* argv[]) { + w2c_dhrystone dhrystone; + struct w2c_wasi__snapshot__preview1 wasi; + uvwasi_t local_uvwasi_state; + 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 = 10; + + // 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); + } + + wasi.w2c_memory = &dhrystone.w2c_memory; + wasi.uvwasi = &local_uvwasi_state, + + wasm2c_dhrystone_instantiate(&dhrystone, &wasi); + + w2c_dhrystone_0x5Fstart(&dhrystone); + + wasm2c_dhrystone_free(&dhrystone); + + uvwasi_destroy(&local_uvwasi_state); + wasm_rt_free(); + + return 0; +} |