wasm_tool.c (3338B)
1 #include <fcntl.h> 2 #include <kit/core.h> 3 #include <stdarg.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <sys/stat.h> 8 #include <unistd.h> 9 10 #include "lang/wasm/wasm.h" 11 #include "lib/kit_test_target.h" 12 13 static void* h_alloc(KitHeap* h, size_t n, size_t a) { 14 (void)h; 15 (void)a; 16 return malloc(n); 17 } 18 static void* h_realloc(KitHeap* h, void* p, size_t o, size_t n, size_t a) { 19 (void)h; 20 (void)o; 21 (void)a; 22 return realloc(p, n); 23 } 24 static void h_free(KitHeap* h, void* p, size_t n) { 25 (void)h; 26 (void)n; 27 free(p); 28 } 29 static KitHeap g_heap = {h_alloc, h_realloc, h_free, NULL}; 30 31 static void diag_fn(KitDiagSink* s, KitDiagKind k, KitSrcLoc loc, 32 const char* fmt, va_list ap) { 33 static const char* names[] = {"note", "warning", "error", "fatal"}; 34 (void)s; 35 (void)loc; 36 fprintf(stderr, "%s: ", names[k]); 37 vfprintf(stderr, fmt, ap); 38 fputc('\n', stderr); 39 } 40 static KitDiagSink g_diag = {diag_fn, NULL, 0, 0}; 41 42 static int slurp(const char* path, uint8_t** out, size_t* len) { 43 int fd = open(path, O_RDONLY); 44 struct stat sb; 45 uint8_t* buf; 46 size_t got = 0; 47 if (fd < 0) return 1; 48 if (fstat(fd, &sb) != 0) { 49 close(fd); 50 return 1; 51 } 52 *len = (size_t)sb.st_size; 53 buf = (uint8_t*)malloc(*len ? *len : 1u); 54 if (!buf) { 55 close(fd); 56 return 1; 57 } 58 while (got < *len) { 59 ssize_t n = read(fd, buf + got, *len - got); 60 if (n <= 0) { 61 free(buf); 62 close(fd); 63 return 1; 64 } 65 got += (size_t)n; 66 } 67 close(fd); 68 *out = buf; 69 return 0; 70 } 71 72 static int write_file(const char* path, const uint8_t* data, size_t len) { 73 int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 74 size_t off = 0; 75 if (fd < 0) return 1; 76 while (off < len) { 77 ssize_t n = write(fd, data + off, len - off); 78 if (n <= 0) { 79 close(fd); 80 return 1; 81 } 82 off += (size_t)n; 83 } 84 close(fd); 85 return 0; 86 } 87 88 int main(int argc, char** argv) { 89 if (argc != 4 || strcmp(argv[1], "--wat2wasm") != 0) { 90 fprintf(stderr, "usage: wasm-tool --wat2wasm IN.wat OUT.wasm\n"); 91 return 2; 92 } 93 94 uint8_t* src = NULL; 95 size_t src_len = 0; 96 if (slurp(argv[2], &src, &src_len)) { 97 fprintf(stderr, "wasm-tool: cannot read %s\n", argv[2]); 98 return 2; 99 } 100 101 KitTargetSpec target; 102 if (kit_test_target_init(&target) != 0) { 103 free(src); 104 return 2; 105 } 106 KitContext ctx; 107 memset(&ctx, 0, sizeof ctx); 108 ctx.heap = &g_heap; 109 ctx.diag = &g_diag; 110 ctx.now = -1; 111 KitCompiler* c = NULL; 112 KitTargetOptions target_opts; 113 KitTarget* kt = NULL; 114 memset(&target_opts, 0, sizeof target_opts); 115 target_opts.spec = target; 116 if (kit_target_new(&ctx, &target_opts, &kt) != KIT_OK || !kt) { 117 free(src); 118 return 2; 119 } 120 if (kit_compiler_new(kt, &ctx, &c) != KIT_OK || !c) { 121 kit_target_free(kt); 122 free(src); 123 return 2; 124 } 125 126 KitWriter* w = NULL; 127 if (kit_writer_mem(&g_heap, &w) != KIT_OK || !w) { 128 kit_compiler_free(c); 129 kit_target_free(kt); 130 free(src); 131 return 2; 132 } 133 KitSlice in; 134 memset(&in, 0, sizeof in); 135 in.data = src; 136 in.len = src_len; 137 int rc = kit_wasm_wat_to_wasm(c, &in, w); 138 size_t out_len = 0; 139 const uint8_t* out = kit_writer_mem_bytes(w, &out_len); 140 if (!rc) rc = write_file(argv[3], out, out_len); 141 kit_writer_close(w); 142 kit_compiler_free(c); 143 kit_target_free(kt); 144 free(src); 145 return rc ? 1 : 0; 146 }