summaryrefslogtreecommitdiff
path: root/wasm2c/benchmarks/dhrystone/main.c
diff options
context:
space:
mode:
authorShravan Narayan <shravanrn@gmail.com>2024-06-26 11:30:44 -0500
committerGitHub <noreply@github.com>2024-06-26 09:30:44 -0700
commit0e871afa4aaac9fe0b1f00cb42a59be666657a06 (patch)
tree22c449953033d0ea98200d9117c11419054a762e /wasm2c/benchmarks/dhrystone/main.c
parentf820d171654de2dcb8cbf7078b4c98336c8e3c69 (diff)
downloadwabt-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.c265
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;
+}