commit c6c4462700a581b82c916959e5b7e951105a7b01
parent 63382c476a5eec3ab2e00d7be713d0ad509bc53e
Author: William Casarin <jb55@jb55.com>
Date: Wed, 21 Jul 2021 13:58:15 -0700
C execution is working!
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
11 files changed, 746 insertions(+), 340 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -11,3 +11,4 @@ todo/done.txt
*.wasm
/tags
todo/todo.txt.bak
+*.txt
diff --git a/Makefile b/Makefile
@@ -34,6 +34,9 @@ wasm: $(WASMS)
%.wasm: %.wat
wat2wasm $^ -o $@
+%.c.wasm: %.wasm.c
+ emcc -g $< -s WASM=1 -o $@
+
wasm/hello-c.wasm: wasm/hello-c.c
emcc -g $< -s WASM=1 -o $@
diff --git a/src/cursor.h b/src/cursor.h
@@ -220,7 +220,9 @@ static inline int cursor_push(struct cursor *cursor, u8 *data, int len)
return 0;
}
- memcpy(cursor->p, data, len);
+ if (cursor->p != data)
+ memcpy(cursor->p, data, len);
+
cursor->p += len;
return 1;
diff --git a/src/parse.h b/src/parse.h
@@ -74,6 +74,7 @@ struct tok_str {
u8 *data;
int len;
};
+
union number {
int integer;
double fdouble;
diff --git a/src/wasm.c b/src/wasm.c
@@ -4,12 +4,14 @@
#include "debug.h"
#include "error.h"
+#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <inttypes.h>
#define interp_error(p, fmt, ...) note_error(&((p)->errors), interp_codeptr(p), fmt, ##__VA_ARGS__)
#define parse_err(p, fmt, ...) note_error(&((p)->errs), &(p)->cur, fmt, ##__VA_ARGS__)
@@ -76,7 +78,7 @@ static const char *valtype_literal(enum valtype valtype)
{
switch (valtype) {
case val_i32: return "";
- case val_i64: return "l";
+ case val_i64: return "L";
case val_f32: return "";
case val_f64: return "f";
case val_ref_null: return "null";
@@ -87,19 +89,19 @@ static const char *valtype_literal(enum valtype valtype)
return "?";
}
-static INLINE int is_valid_fn_index(struct module *module, int ind)
+static INLINE int is_valid_fn_index(struct module *module, u32 ind)
{
- return ind >= 0 && ind < module->num_funcs;
+ return ind < module->num_funcs;
}
-static INLINE struct func *get_function(struct module *module, int ind)
+static INLINE struct func *get_function(struct module *module, u32 ind)
{
if (unlikely(!is_valid_fn_index(module, ind)))
return NULL;
return &module->funcs[ind];
}
-static struct val *get_fn_local(struct wasm_interp *interp, int fn, int ind)
+static struct val *get_fn_local(struct wasm_interp *interp, int fn, u32 ind)
{
struct func *func;
@@ -117,7 +119,7 @@ static struct val *get_fn_local(struct wasm_interp *interp, int fn, int ind)
return &func->locals[ind].val;
}
-static struct val *get_local(struct wasm_interp *interp, int ind)
+static struct val *get_local(struct wasm_interp *interp, u32 ind)
{
struct callframe *frame;
@@ -155,6 +157,18 @@ static INLINE int cursor_pop_i32(struct cursor *stack, int *i)
return 1;
}
+static INLINE int cursor_pop_i64(struct cursor *stack, int64_t *i)
+{
+ struct val val;
+ if (unlikely(!cursor_popval(stack, &val)))
+ return 0;
+ if (unlikely(val.type != val_i64))
+ return 0;
+ *i = val.num.i64;
+ return 1;
+}
+
+
static int is_reftype(enum valtype type)
{
switch (type) {
@@ -201,6 +215,11 @@ static INLINE int stack_pop_i32(struct wasm_interp *interp, int *i)
return cursor_pop_i32(&interp->stack, i);
}
+static INLINE int stack_pop_i64(struct wasm_interp *interp, int64_t *i)
+{
+ return cursor_pop_i64(&interp->stack, i);
+}
+
static INLINE int cursor_pop_valtype(struct cursor *stack, enum valtype type,
struct val *val)
{
@@ -225,7 +244,7 @@ static void print_val(struct val *val)
{
switch (val->type) {
case val_i32: printf("%d", val->num.i32); break;
- case val_i64: printf("%lu", val->num.i64); break;
+ case val_i64: printf("%" PRId64, val->num.i64); break;
case val_f32: printf("%f", val->num.f32); break;
case val_f64: printf("%f", val->num.f64); break;
@@ -239,6 +258,7 @@ static void print_val(struct val *val)
printf("%s", valtype_literal(val->type));
}
+#ifdef DEBUG
static void print_refval(struct refval *ref, enum reftype reftype)
{
struct val val;
@@ -246,6 +266,7 @@ static void print_refval(struct refval *ref, enum reftype reftype)
val.ref = *ref;
print_val(&val);
}
+#endif
static void print_stack(struct cursor *stack)
{
@@ -318,9 +339,11 @@ static int builtin_proc_exit(struct wasm_interp *interp)
static int builtin_get_args_sizes(struct wasm_interp *interp);
static int builtin_get_args(struct wasm_interp *interp);
+static int builtin_fd_write(struct wasm_interp *interp);
static struct builtin BUILTINS[] = {
{ .name = "args_get", .fn = builtin_get_args },
+ { .name = "fd_write", .fn = builtin_fd_write },
{ .name = "args_sizes_get", .fn = builtin_get_args_sizes },
{ .name = "proc_exit", .fn = builtin_proc_exit },
};
@@ -604,7 +627,7 @@ void print_error_backtrace(struct errors *errors)
static void _functype_str(struct functype *ft, struct cursor *buf)
{
- int i;
+ u32 i;
cursor_push_str(buf, "(");
@@ -651,7 +674,7 @@ static void print_functype(struct functype *ft)
static void print_type_section(struct typesec *typesec)
{
- int i;
+ u32 i;
printf("%d functypes:\n", typesec->num_functypes);
for (i = 0; i < typesec->num_functypes; i++) {
printf(" ");
@@ -692,7 +715,7 @@ static void print_import(struct import *import)
static void print_import_section(struct importsec *importsec)
{
- int i;
+ u32 i;
printf("%d imports:\n", importsec->num_imports);
for (i = 0; i < importsec->num_imports; i++) {
printf(" ");
@@ -714,7 +737,7 @@ static void print_limits(struct limits *limits)
static void print_memory_section(struct memsec *memory)
{
- int i;
+ u32 i;
struct limits *mem;
printf("%d memory:\n", memory->num_mems);
@@ -728,7 +751,7 @@ static void print_memory_section(struct memsec *memory)
static void print_table_section(struct tablesec *section)
{
- int i;
+ u32 i;
struct table *table;
printf("%d tables:\n", section->num_tables);
@@ -743,7 +766,7 @@ static void print_table_section(struct tablesec *section)
static int count_imports(struct module *module, enum import_type *typ)
{
- int i, count = 0;
+ u32 i, count = 0;
struct import *import;
struct importsec *imports;
@@ -787,13 +810,13 @@ static void print_element_section(struct elemsec *section)
static void print_start_section(struct module *module)
{
- int fn = module->start_section.start_fn;
+ u32 fn = module->start_section.start_fn;
printf("start function: %d <%s>\n", fn, get_function_name(module, fn));
}
static void print_export_section(struct exportsec *exportsec)
{
- int i;
+ u32 i;
printf("%d exports:\n", exportsec->num_exports);
for (i = 0; i < exportsec->num_exports; i++) {
printf(" ");
@@ -898,7 +921,7 @@ static void print_section(struct module *module, enum section_tag section)
static void print_module(struct module *module)
{
- int i;
+ u32 i;
enum section_tag section;
for (i = 0; i < num_sections; i++) {
@@ -934,10 +957,9 @@ static int leb128_write(struct cursor *write, unsigned int value)
#define LEB128_4(type) (BYTE_AT(type, 3, 21) | LEB128_3(type))
#define LEB128_5(type) (BYTE_AT(type, 4, 28) | LEB128_4(type))
-static INLINE int leb128_read(struct cursor *read, unsigned int *val_)
+static INLINE int read_i64(struct cursor *read, int64_t *val)
{
- int *val = (signed int*)val_;
- int shift;
+ int64_t shift;
u8 byte;
*val = 0;
@@ -951,7 +973,7 @@ static INLINE int leb128_read(struct cursor *read, unsigned int *val_)
} while ((byte & 0x80) != 0);
/* sign bit of byte is second high-order bit (0x40) */
- if ((shift < (signed int)sizeof(*val)) && (byte & 0x40))
+ if ((shift < 64) && (byte & 0x40))
*val |= (~0 << shift);
return 1;
@@ -959,30 +981,57 @@ static INLINE int leb128_read(struct cursor *read, unsigned int *val_)
static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
{
- //unsigned char *start;
- int shift;
+ unsigned int shift = 0;
u8 byte;
-
- //start = read->p;
*val = 0;
- shift = 0;
for (;;) {
- if (!pull_byte(read, &byte)) {
+ if (!pull_byte(read, &byte))
return 0;
- }
- *val |= (byte & 0x7F) << shift;
- if ((byte & 0x80) == 0)
+
+ *val |= (0x7F & byte) << shift;
+
+ if ((0x80 & byte) == 0)
break;
+
shift += 7;
}
return 1;
}
+static INLINE int sleb128_read(struct cursor *read, signed int *val)
+{
+ int shift;
+ u8 byte;
+
+ *val = 0;
+ shift = 0;
+
+ do {
+ if (!pull_byte(read, &byte))
+ return 0;
+ *val |= ((byte & 0x7F) << shift);
+ shift += 7;
+ } while ((byte & 0x80) != 0);
+
+ /* sign bit of byte is second high-order bit (0x40) */
+ if ((shift < 32) && (byte & 0x40))
+ *val |= (0xFFFFFFFF << shift);
+
+ return 1;
+}
+
/*
+static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
+{
+ unsigned char p[6] = {0};
+ *val = 0;
+
if (pull_byte(read, &p[0]) && (p[0] & 0x80) == 0) {
*val = LEB128_1(unsigned int);
+ if (p[0] == 0x7F)
+ assert((int)*val == -1);
return 1;
} else if (pull_byte(read, &p[1]) && (p[1] & 0x80) == 0) {
*val = LEB128_2(unsigned int);
@@ -1000,16 +1049,23 @@ static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
}
//printf("%02X & 0xF0\n", p[4] & 0xF0);
}
- */
- /* reset if we're missing */
- //read->p = start;
+ return 0;
+}
+*/
static INLINE int read_int(struct cursor *read, int *val)
{
- return leb128_read(read, (unsigned int *)val);
+ return sleb128_read(read, val);
+}
+
+
+static INLINE int read_u32(struct cursor *read, u32 *val)
+{
+ return uleb128_read(read, val);
}
+
static int parse_section_tag(struct cursor *cur, enum section_tag *section)
{
unsigned char byte;
@@ -1052,7 +1108,7 @@ static int parse_valtype(struct wasm_parser *p, enum valtype *valtype)
static int parse_result_type(struct wasm_parser *p, struct resulttype *rt)
{
- int i, elems;
+ u32 i, elems;
enum valtype valtype;
unsigned char *start;
@@ -1060,7 +1116,7 @@ static int parse_result_type(struct wasm_parser *p, struct resulttype *rt)
rt->valtypes = 0;
start = p->mem.p;
- if (unlikely(!read_int(&p->cur, &elems))) {
+ if (unlikely(!read_u32(&p->cur, &elems))) {
parse_err(p, "vec len");
return 0;
}
@@ -1109,8 +1165,8 @@ static int parse_func_type(struct wasm_parser *p, struct functype *func)
static int parse_name(struct wasm_parser *p, const char **name)
{
- unsigned int bytes;
- if (unlikely(!leb128_read(&p->cur, &bytes))) {
+ u32 bytes;
+ if (unlikely(!read_u32(&p->cur, &bytes))) {
parse_err(p, "name len");
return 0;
}
@@ -1163,7 +1219,7 @@ static int parse_export(struct wasm_parser *p, struct wexport *export)
return 0;
}
- if (!leb128_read(&p->cur, &export->index)) {
+ if (!read_u32(&p->cur, &export->index)) {
parse_err(p, "export index");
return 0;
}
@@ -1173,7 +1229,7 @@ static int parse_export(struct wasm_parser *p, struct wexport *export)
static int parse_local(struct wasm_parser *p, struct local *local)
{
- if (unlikely(!read_int(&p->cur, &local->val.num.i32))) {
+ if (unlikely(!read_u32(&p->cur, &local->val.num.u32))) {
debug("fail parse local\n");
return parse_err(p, "n");
}
@@ -1186,12 +1242,11 @@ static int parse_local(struct wasm_parser *p, struct local *local)
return 1;
}
-static int parse_vector(struct wasm_parser *p, unsigned int item_size,
- unsigned int *elems, void **items)
+static int parse_vector(struct wasm_parser *p, int item_size,
+ u32 *elems, void **items)
{
- if (!leb128_read(&p->cur, elems)) {
- parse_err(p, "len");
- return 0;
+ if (!read_u32(&p->cur, elems)) {
+ return parse_err(p, "len");
}
*items = cursor_alloc(&p->mem, *elems * item_size);
@@ -1206,19 +1261,18 @@ static int parse_vector(struct wasm_parser *p, unsigned int item_size,
static int parse_func(struct wasm_parser *p, struct wasm_func *func)
{
- unsigned int size;
- int i;
- unsigned char *start;
struct local *locals;
+ u32 i, size;
+ u8 *start;
- if (!leb128_read(&p->cur, &size)) {
+ if (!read_u32(&p->cur, &size)) {
return parse_err(p, "code size");
}
start = p->cur.p;
locals = (struct local*)p->mem.p;
- if (!read_int(&p->cur, &func->num_locals)) {
+ if (!read_u32(&p->cur, &func->num_locals)) {
return parse_err(p, "read locals vec");
}
@@ -1262,18 +1316,13 @@ static int parse_code_section(struct wasm_parser *p,
struct codesec *code_section)
{
struct wasm_func *funcs;
- int i;
+ u32 i;
- if (!parse_vector(p, sizeof(*funcs),
- (unsigned int*)&code_section->num_funcs,
+ if (!parse_vector(p, sizeof(*funcs), &code_section->num_funcs,
(void**)&funcs)) {
return parse_err(p, "funcs");
}
- if (code_section->num_funcs < 0) {
- return parse_err(p, "code_section num_funcs < 0");
- }
-
for (i = 0; i < code_section->num_funcs; i++) {
if (!parse_func(p, &funcs[i])) {
return parse_err(p, "func #%d", i);
@@ -1319,7 +1368,7 @@ static int parse_export_section(struct wasm_parser *p,
struct exportsec *export_section)
{
struct wexport *exports;
- unsigned int elems, i;
+ u32 elems, i;
if (!parse_vector(p, sizeof(*exports), &elems, (void**)&exports)) {
parse_err(p, "vector");
@@ -1350,14 +1399,14 @@ static int parse_limits(struct wasm_parser *p, struct limits *limits)
return parse_err(p, "invalid tag %02x", tag);
}
- if (!leb128_read(&p->cur, &limits->min)) {
+ if (!read_u32(&p->cur, &limits->min)) {
return parse_err(p, "min");
}
if (tag == limit_min)
return 1;
- if (!leb128_read(&p->cur, &limits->max)) {
+ if (!read_u32(&p->cur, &limits->max)) {
return parse_err(p, "max");
}
@@ -1509,7 +1558,7 @@ static const char *show_instr(struct instr *instr)
case i_ref_func:
case i_table_set:
case i_table_get:
- sprintf(tmp, "%d", instr->integer);
+ sprintf(tmp, "%d", instr->i32);
cursor_push_str(&buf, tmp);
break;
@@ -1723,12 +1772,12 @@ static int eval_const_instr(struct instr *instr, struct errors *errs,
}
return 1;
case ci_ref_func:
- if (unlikely(!cursor_push_funcref(stack, instr->integer))) {
+ if (unlikely(!cursor_push_funcref(stack, instr->i32))) {
return note_error(errs, stack, "couldn't push funcref");
}
return 1;
case ci_const_i32:
- if (unlikely(!cursor_push_i32(stack, instr->integer))) {
+ if (unlikely(!cursor_push_i32(stack, instr->i32))) {
return note_error(errs, stack,
"global push i32 const");
}
@@ -1867,7 +1916,7 @@ static int parse_global_section(struct wasm_parser *p,
struct globalsec *global_section)
{
struct global *globals;
- unsigned int elems, i;
+ u32 elems, i;
if (!parse_vector(p, sizeof(*globals), &elems, (void**)&globals)) {
return parse_err(p, "globals vector");
@@ -1898,7 +1947,7 @@ static INLINE void make_interp_expr_parser(struct wasm_interp *interp,
}
static int parse_instrs_until(struct expr_parser *p, u8 stop_instr,
- u8 **parsed_instrs, int *instr_len)
+ u8 **parsed_instrs, u32 *instr_len)
{
u8 tag;
struct instr op;
@@ -1942,10 +1991,10 @@ static int parse_expr(struct wasm_parser *p, struct expr *expr)
static int parse_elem_func_inits(struct wasm_parser *p, struct elem *elem)
{
- int index, i;
+ u32 index, i;
struct expr *expr;
- if (!read_int(&p->cur, &elem->num_inits))
+ if (!read_u32(&p->cur, &elem->num_inits))
return parse_err(p, "func indices vec read fail");
if (!(elem->inits = cursor_alloc(&p->mem, elem->num_inits *
@@ -1957,12 +2006,12 @@ static int parse_elem_func_inits(struct wasm_parser *p, struct elem *elem)
expr = &elem->inits[i];
expr->code = p->mem.p;
- if (!read_int(&p->cur, &index))
+ if (!read_u32(&p->cur, &index))
return parse_err(p, "func index %d read fail", i);
if (!cursor_push_byte(&p->mem, i_ref_func))
return parse_err(p, "push ref_func instr oob for %d", i);
if (!leb128_write(&p->mem, index))
- return parse_err(p, "push ref_func int index oob for %d", i);
+ return parse_err(p, "push ref_func u32 index oob for %d", i);
if (!cursor_push_byte(&p->mem, i_end))
return parse_err(p, "push i_end for init %d", i);
@@ -2028,7 +2077,7 @@ static int parse_custom_section(struct wasm_parser *p, u32 size,
static int parse_element_section(struct wasm_parser *p, struct elemsec *elemsec)
{
struct elem *elements;
- unsigned int count, i;
+ u32 count, i;
if (!parse_vector(p, sizeof(struct elem), &count, (void**)&elements))
return parse_err(p, "elements vec");
@@ -2048,7 +2097,7 @@ static int parse_memory_section(struct wasm_parser *p,
struct memsec *memory_section)
{
struct limits *mems;
- unsigned int elems, i;
+ u32 elems, i;
if (!parse_vector(p, sizeof(*mems), &elems, (void**)&mems)) {
return parse_err(p, "mems vector");
@@ -2069,17 +2118,17 @@ static int parse_memory_section(struct wasm_parser *p,
static int parse_start_section(struct wasm_parser *p,
struct startsec *start_section)
{
- if (!read_int(&p->cur, &start_section->start_fn)) {
+ if (!read_u32(&p->cur, &start_section->start_fn)) {
return parse_err(p, "start_fn index");
}
return 1;
}
-static INLINE int parse_byte_vector(struct wasm_parser *p, unsigned char **data,
- int *data_len)
+static INLINE int parse_byte_vector(struct wasm_parser *p, u8 **data,
+ u32 *data_len)
{
- if (!read_int(&p->cur, data_len)) {
+ if (!read_u32(&p->cur, data_len)) {
return parse_err(p, "len");
}
@@ -2136,7 +2185,7 @@ static int parse_wdata(struct wasm_parser *p, struct wdata *data)
case 2:
data->mode = datamode_active;
- if (!read_int(&p->cur, &data->active.mem_index)) {
+ if (!read_u32(&p->cur, &data->active.mem_index)) {
return parse_err(p, "read active data mem_index");
}
@@ -2157,7 +2206,7 @@ static int parse_wdata(struct wasm_parser *p, struct wdata *data)
static int parse_data_section(struct wasm_parser *p, struct datasec *section)
{
struct wdata *data;
- unsigned int elems, i;
+ u32 elems, i;
if (!parse_vector(p, sizeof(*data), &elems, (void**)&data)) {
return parse_err(p, "datas vector");
@@ -2179,11 +2228,10 @@ static int parse_table_section(struct wasm_parser *p,
struct tablesec *table_section)
{
struct table *tables;
- unsigned int elems, i;
+ u32 elems, i;
if (!parse_vector(p, sizeof(*tables), &elems, (void**)&tables)) {
- parse_err(p, "tables vector");
- return 0;
+ return parse_err(p, "tables vector");
}
for (i = 0; i < elems; i++) {
@@ -2202,16 +2250,14 @@ static int parse_table_section(struct wasm_parser *p,
static int parse_function_section(struct wasm_parser *p,
struct funcsec *funcsec)
{
- unsigned int *indices;
- unsigned int i, elems;
+ u32 i, elems, *indices;
if (!parse_vector(p, sizeof(*indices), &elems, (void**)&indices)) {
- parse_err(p, "indices");
- return 0;
+ return parse_err(p, "indices");
}
for (i = 0; i < elems; i++) {
- if (!leb128_read(&p->cur, &indices[i])) {
+ if (!read_u32(&p->cur, &indices[i])) {
parse_err(p, "typeidx #%d", i);
return 0;
}
@@ -2240,7 +2286,7 @@ static int parse_import_table(struct wasm_parser *p, struct limits *limits)
static int parse_importdesc(struct wasm_parser *p, struct importdesc *desc)
{
- unsigned char tag;
+ u8 tag;
if (!pull_byte(&p->cur, &tag)) {
parse_err(p, "oom");
@@ -2251,7 +2297,7 @@ static int parse_importdesc(struct wasm_parser *p, struct importdesc *desc)
switch (desc->type) {
case import_func:
- if (!leb128_read(&p->cur, &desc->typeidx)) {
+ if (!read_u32(&p->cur, &desc->typeidx)) {
parse_err(p, "typeidx");
return 0;
}
@@ -2318,18 +2364,16 @@ static int parse_import(struct wasm_parser *p, struct import *import)
static int parse_import_section(struct wasm_parser *p, struct importsec *importsec)
{
- unsigned int elems, i;
+ u32 elems, i;
struct import *imports;
if (!parse_vector(p, sizeof(*imports), &elems, (void**)&imports)) {
- parse_err(p, "imports");
- return 0;
+ return parse_err(p, "imports");
}
for (i = 0; i < elems; i++) {
if (!parse_import(p, &imports[i])) {
- parse_err(p, "import #%d", i);
- return 0;
+ return parse_err(p, "import #%d", i);
}
}
@@ -2342,7 +2386,7 @@ static int parse_import_section(struct wasm_parser *p, struct importsec *imports
/* type section is just a vector of function types */
static int parse_type_section(struct wasm_parser *p, struct typesec *typesec)
{
- unsigned int elems, i;
+ u32 elems, i;
struct functype *functypes;
typesec->num_functypes = 0;
@@ -2479,14 +2523,14 @@ static int parse_section(struct wasm_parser *p)
{
enum section_tag tag;
struct section;
- unsigned int bytes;
+ u32 bytes;
if (!parse_section_tag(&p->cur, &tag)) {
parse_err(p, "section tag");
return 2;
}
- if (!leb128_read(&p->cur, &bytes)) {
+ if (!read_u32(&p->cur, &bytes)) {
return parse_err(p, "section len");
}
@@ -2499,9 +2543,9 @@ static int parse_section(struct wasm_parser *p)
return 1;
}
-static struct builtin *builtin_func(int ind)
+static struct builtin *builtin_func(u32 ind)
{
- if (unlikely(ind < 0 || ind >= NUM_BUILTINS)) {
+ if (unlikely(ind >= NUM_BUILTINS)) {
printf("UNUSUAL: invalid builtin index %d (max %d)\n", ind,
NUM_BUILTINS-1);
return NULL;
@@ -2509,9 +2553,9 @@ static struct builtin *builtin_func(int ind)
return &BUILTINS[ind];
}
-static const char *find_exported_function_name(struct module *module, int fn)
+static const char *find_exported_function_name(struct module *module, u32 fn)
{
- int i;
+ u32 i;
struct wexport *export;
if (!was_section_parsed(module, section_export))
@@ -2520,7 +2564,7 @@ static const char *find_exported_function_name(struct module *module, int fn)
for (i = 0; i < module->export_section.num_exports; i++) {
export = &module->export_section.exports[i];
if (export->desc == export_func &&
- export->index == (unsigned int)fn) {
+ export->index == fn) {
return export->name;
}
}
@@ -2531,11 +2575,12 @@ static const char *find_exported_function_name(struct module *module, int fn)
static int make_func_lookup_table(struct wasm_parser *parser)
{
- int i, num_imports, num_func_imports, num_internal_funcs, typeidx;
+ u32 i, num_imports, num_func_imports, num_internal_funcs, typeidx, fn;
struct import *import;
struct importsec *imports;
struct func *func;
- int fn = 0;
+
+ fn = 0;
imports = &parser->module.import_section;
num_func_imports = count_imported_functions(&parser->module);
@@ -2618,7 +2663,7 @@ int parse_wasm(struct wasm_parser *p)
return parse_err(p, "failed making func lookup table");
}
- print_module(&p->module);
+ //print_module(&p->module);
debug("module parse success!\n\n");
return 1;
@@ -2679,7 +2724,7 @@ static int interp_i32_sub(struct wasm_interp *interp)
return stack_pushval(interp, &c);
}
-static INLINE int set_fn_local(struct wasm_interp *interp, int fn, int ind,
+static INLINE int set_fn_local(struct wasm_interp *interp, int fn, u32 ind,
struct val *val)
{
struct val *local;
@@ -2693,7 +2738,7 @@ static INLINE int set_fn_local(struct wasm_interp *interp, int fn, int ind,
return 1;
}
-static INLINE int set_local(struct wasm_interp *interp, int ind,
+static INLINE int set_local(struct wasm_interp *interp, u32 ind,
struct val *val)
{
struct callframe *frame;
@@ -2705,7 +2750,7 @@ static INLINE int set_local(struct wasm_interp *interp, int ind,
return set_fn_local(interp, frame->fn, ind, val);
}
-static INLINE int interp_local_tee(struct wasm_interp *interp, int index)
+static INLINE int interp_local_tee(struct wasm_interp *interp, u32 index)
{
struct val *val;
@@ -2720,7 +2765,7 @@ static INLINE int interp_local_tee(struct wasm_interp *interp, int index)
return 1;
}
-static int interp_local_set(struct wasm_interp *interp, int index)
+static int interp_local_set(struct wasm_interp *interp, u32 index)
{
struct val val;
@@ -2735,7 +2780,7 @@ static int interp_local_set(struct wasm_interp *interp, int index)
return 1;
}
-static INLINE int interp_local_get(struct wasm_interp *interp, int index)
+static INLINE int interp_local_get(struct wasm_interp *interp, u32 index)
{
struct val *val;
@@ -2746,7 +2791,7 @@ static INLINE int interp_local_get(struct wasm_interp *interp, int index)
return stack_pushval(interp, val);
}
-static INLINE void make_i64_val(struct val *val, int64_t v)
+static INLINE void make_i64_val(struct val *val, u64 v)
{
val->type = val_i64;
val->num.i64 = v;
@@ -2790,12 +2835,92 @@ static INLINE int interp_i32_gt_s(struct wasm_interp *interp)
return stack_pushval(interp, &c);
}
+static INLINE int interp_i64_sub(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
+ return interp_error(interp, "binop prep");
+ c.num.i64 = lhs.num.i64 - rhs.num.i64;
+ return stack_pushval(interp, &c);
+}
+
+static INLINE int interp_i64_ge_u(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
+ return interp_error(interp, "binop prep");
+ c.type = val_i32;
+ c.num.i32 = lhs.num.i64 >= rhs.num.i64;
+ return stack_pushval(interp, &c);
+}
+
+static INLINE int interp_i64_mul(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
+ return interp_error(interp, "binop prep");
+ c.num.i64 = lhs.num.i64 * rhs.num.i64;
+ return stack_pushval(interp, &c);
+}
+
+static INLINE int interp_i64_div_u(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
+ return interp_error(interp, "binop prep");
+ if (rhs.num.u64 == 0)
+ return interp_error(interp, "congrats, you divided by zero");
+ c.num.u64 = lhs.num.u64 / rhs.num.u64;
+ return stack_pushval(interp, &c);
+}
+
+static int interp_i64_eqz(struct wasm_interp *interp)
+{
+ struct val a, res;
+ if (unlikely(!stack_pop_valtype(interp, val_i64, &a)))
+ return interp_error(interp, "pop val");
+ res.type = val_i32;
+ res.num.i64 = a.num.i64 == 0;
+ return cursor_pushval(&interp->stack, &res);
+}
+
+static INLINE int interp_i64_gt_s(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
+ return interp_error(interp, "binop prep");
+ c.type = val_i32;
+ c.num.i32 = lhs.num.i64 > rhs.num.i64;
+ return stack_pushval(interp, &c);
+}
+
+static INLINE int interp_i64_gt_u(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
+ return interp_error(interp, "binop prep");
+ c.type = val_i32;
+ c.num.i32 = lhs.num.u64 > rhs.num.u64;
+ return stack_pushval(interp, &c);
+}
+
static INLINE int interp_i32_gt_u(struct wasm_interp *interp)
{
struct val lhs, rhs, c;
if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
return interp_error(interp, "binop prep");
- c.num.i32 = (unsigned int)lhs.num.i32 > (unsigned int)rhs.num.i32;
+ c.num.i32 = lhs.num.u32 > rhs.num.u32;
+ return stack_pushval(interp, &c);
+}
+
+static INLINE int interp_i32_div_u(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
+ return interp_error(interp, "binop prep");
+ if (rhs.num.u64 == 0)
+ return interp_error(interp, "congrats, you divided by zero");
+ c.num.i32 = lhs.num.i32 / rhs.num.i32;
return stack_pushval(interp, &c);
}
@@ -2826,7 +2951,7 @@ static INLINE int interp_i32_le_s(struct wasm_interp *interp)
return stack_pushval(interp, &c);
}
-static INLINE int interp_i64_const(struct wasm_interp *interp, int64_t c)
+static INLINE int interp_i64_const(struct wasm_interp *interp, u64 c)
{
struct val val;
make_i64_val(&val, c);
@@ -2834,7 +2959,7 @@ static INLINE int interp_i64_const(struct wasm_interp *interp, int64_t c)
}
-static INLINE int interp_i32_const(struct wasm_interp *interp, int c)
+static INLINE int interp_i32_const(struct wasm_interp *interp, u32 c)
{
struct val val;
make_i32_val(&val, c);
@@ -2971,12 +3096,13 @@ static int prepare_function_args(struct wasm_interp *interp, struct func *func,
struct local *local;
enum valtype paramtype;
struct val val;
- int i, ind;
+ u32 i, ind;
/* push params as locals */
for (i = 0; i < func->functype->params.num_valtypes; i++) {
- paramtype = (enum valtype)func->functype->params.valtypes[i];
ind = func->functype->params.num_valtypes-1-i;
+ paramtype = (enum valtype)func->functype->params.valtypes[ind];
+ //ind = i;
local = &func->locals[ind];
if (unlikely(!cursor_popval(&interp->stack, &val))) {
@@ -3005,11 +3131,13 @@ static int prepare_function_args(struct wasm_interp *interp, struct func *func,
}
- for (; i < func->num_locals - func->functype->params.num_valtypes; i++) {
+ for (i=func->functype->params.num_valtypes;
+ i < func->num_locals; i++) {
local = &func->locals[i];
make_default_val(&local->val);
debug("setting local %d (%s) to default\n",
- i, valtype_name(local->val.type));
+ i-func->functype->params.num_valtypes,
+ valtype_name(local->val.type));
}
return 1;
@@ -3077,7 +3205,8 @@ static int interp_call_indirect(struct wasm_interp *interp, struct call_indirect
struct func *func;
struct table_inst *table;
struct refval *ref;
- int i, ftidx;
+ u32 ftidx;
+ int i;
if (unlikely(!was_section_parsed(interp->module, section_table))) {
return interp_error(interp, "no table section");
@@ -3110,7 +3239,7 @@ static int interp_call_indirect(struct wasm_interp *interp, struct call_indirect
return interp_error(interp, "pop i32");
}
- if (unlikely(i >= table->num_refs)) {
+ if (unlikely(i >= (int)table->num_refs)) {
return interp_error(interp, "invalid index %d in table %d (max %d)",
i, call->tableidx, table->num_refs-1);
}
@@ -3143,7 +3272,7 @@ static int interp_call_indirect(struct wasm_interp *interp, struct call_indirect
ref, interp->module->num_funcs-1);
}
- debug("calling %s:%d indirectly",
+ debug("calling %s:%d indirectly\n",
get_function_name(interp->module, ref->addr),
ref->addr);
@@ -3167,6 +3296,7 @@ static int parse_blocktype(struct cursor *cur, struct errors *errs, struct block
blocktype->tag = blocktype_index;
cur->p--;
+ // TODO: this should be read_s64
if (!read_int(cur, &blocktype->type_index)) {
note_error(errs, cur, "parse_blocktype: read type_index\n");
return 0;
@@ -3176,7 +3306,7 @@ static int parse_blocktype(struct cursor *cur, struct errors *errs, struct block
return 1;
}
-static INLINE struct label *index_label(struct cursor *a, int fn, int ind)
+static INLINE struct label *index_label(struct cursor *a, u32 fn, u32 ind)
{
return index_cursor(a, ((MAX_LABELS * fn) + ind), sizeof(struct label));
}
@@ -3191,7 +3321,7 @@ static INLINE int is_label_resolved(struct label *label)
return label->instr_pos & 0x80000000;
}
-static struct label *index_frame_label(struct wasm_interp *interp, int ind)
+static struct label *index_frame_label(struct wasm_interp *interp, u32 ind)
{
struct callframe *frame;
@@ -3226,6 +3356,7 @@ static INLINE int pop_resolver(struct wasm_interp *interp,
/*
#ifdef DEBUG
int num_resolvers;
+ struct label *label;
#endif
*/
@@ -3238,10 +3369,16 @@ static INLINE int pop_resolver(struct wasm_interp *interp,
if (unlikely(!count_local_resolvers(interp, &num_resolvers))) {
return interp_error(interp, "local resolvers fn start");
};
+
+ label = index_label(&interp->labels,
+ top_callframe(&interp->callframes)->fn,
+ resolver->label);
#endif
- debug("popped resolver %d i_%s i_%s %d local_resolvers:%d\n",
- resolver->label,
+ debug("%04lX popped resolver %04x-%04x i_%s i_%s %d local_resolvers:%d\n",
+ interp_codeptr(interp)->p - interp_codeptr(interp)->start,
+ label_instr_pos(label),
+ label->jump,
instr_name(resolver->start_tag),
instr_name(resolver->end_tag),
count_resolvers(interp),
@@ -3251,31 +3388,37 @@ static INLINE int pop_resolver(struct wasm_interp *interp,
return 1;
}
-static int pop_label_checkpoint(struct wasm_interp *interp)
+static int pop_label(struct wasm_interp *interp,
+ struct resolver *resolver,
+ struct callframe **frame,
+ struct label **label)
{
- struct label *label;
- struct callframe *frame;
- struct resolver resolver;
-
- resolver.label = 0;
- resolver.end_tag = 0;
-
- if (unlikely(!pop_resolver(interp, &resolver)))
+ if (unlikely(!pop_resolver(interp, resolver)))
return interp_error(interp, "couldn't pop jump resolver stack");
- if (unlikely(!(frame = top_callframe(&interp->callframes))))
+ if (unlikely(!(*frame = top_callframe(&interp->callframes))))
return interp_error(interp, "no callframe?");
- if (unlikely(!(label = index_label(&interp->labels, frame->fn, resolver.label))))
+ if (unlikely(!(*label = index_label(&interp->labels, (*frame)->fn,
+ resolver->label))))
return interp_error(interp, "index label");
- if (unlikely(!resolve_label(label, &frame->code)))
+ if (unlikely(!resolve_label(*label, &(*frame)->code)))
return interp_error(interp, "resolve label");
return 1;
}
-static INLINE u16 *func_num_labels(struct wasm_interp *interp, int fn)
+static INLINE int pop_label_checkpoint(struct wasm_interp *interp)
+{
+ struct resolver resolver;
+ struct callframe *frame;
+ struct label *label;
+
+ return pop_label(interp, &resolver, &frame, &label);
+}
+
+static INLINE u16 *func_num_labels(struct wasm_interp *interp, u32 fn)
{
u16 *num = index_cursor(&interp->num_labels, fn, sizeof(u16));
assert(num);
@@ -3283,7 +3426,7 @@ static INLINE u16 *func_num_labels(struct wasm_interp *interp, int fn)
return num;
}
-static int find_label(struct wasm_interp *interp, int fn, u32 instr_pos)
+static int find_label(struct wasm_interp *interp, u32 fn, u32 instr_pos)
{
u16 *num_labels, i;
struct label *label;
@@ -3310,7 +3453,7 @@ static INLINE void set_label_pos(struct label *label, u32 pos)
}
// upsert an unresolved label
-static int upsert_label(struct wasm_interp *interp, int fn,
+static int upsert_label(struct wasm_interp *interp, u32 fn,
u32 instr_pos, int *ind)
{
struct label *label;
@@ -3359,12 +3502,12 @@ struct tag_info {
static int push_label_checkpoint(struct wasm_interp *interp, struct label **label,
u8 start_tag, u8 end_tag)
{
- u32 instr_pos;
- int ind, fns;
+ u32 instr_pos, fns;
+ int ind;
struct resolver resolver;
struct callframe *frame;
-/*
+ /*
#ifdef DEBUG
int num_resolvers;
#endif
@@ -3406,8 +3549,9 @@ static int push_label_checkpoint(struct wasm_interp *interp, struct label **labe
return interp_error(interp, "local resolvers fn start");
};
#endif
- debug("pushed resolver %d i_%s i_%s %ld local_resolvers:%d \n",
- resolver.label,
+ debug("pushed resolver 0x%04X-0x%04X i_%s i_%s %ld local_resolvers:%d \n",
+ label_instr_pos(*label),
+ (*label)->jump,
instr_name(resolver.start_tag),
instr_name(resolver.end_tag),
cursor_count(&interp->resolver_stack, sizeof(resolver)),
@@ -3437,21 +3581,86 @@ static int interp_jump(struct wasm_interp *interp, int jmp)
return 1;
}
-static int pop_label_and_jump(struct wasm_interp *interp, struct label *label, int times)
+static INLINE struct resolver *top_resolver_stack(struct cursor *stack, int index)
+{
+ struct resolver *p = (struct resolver*)stack->p;
+ p = &p[-(index+1)];
+ if (p < (struct resolver*)stack->start)
+ return NULL;
+ return p;
+}
+
+static INLINE struct resolver *top_resolver(struct wasm_interp *interp, u32 index)
+{
+ return top_resolver_stack(&interp->resolver_stack, index);
+}
+
+static int break_jump(struct wasm_interp *interp, struct resolver *resolver,
+ struct label *label)
+{
+ /*
+ debug("break jumping to %s %s\n",
+ instr_name(resolver->start_tag),
+ instr_name(resolver->end_tag)
+ );
+ */
+
+ if (resolver->start_tag != i_loop)
+ return interp_jump(interp, label->jump);
+
+ return interp_jump(interp, label_instr_pos(label));
+}
+
+static int pop_label_and_skip(struct wasm_interp *interp, struct label *label,
+ int times)
{
int i;
+ struct resolver resolver;
assert(is_label_resolved(label));
+
+ if (unlikely(times == 0))
+ return interp_error(interp, "can't pop label 0 times");
for (i = 0; i < times; i++) {
- if (!cursor_drop(&interp->resolver_stack,
- sizeof(struct resolver))) {
- return interp_error(interp, "drop label");
+ if (!pop_resolver(interp, &resolver)) {
+ return interp_error(interp, "top resolver");
}
}
return interp_jump(interp, label->jump);
}
+static int pop_label_and_break(struct wasm_interp *interp, struct label *label,
+ int times)
+{
+ int i;
+ struct resolver resolver;
+ assert(is_label_resolved(label));
+
+ if (unlikely(times == 0))
+ return interp_error(interp, "can't pop label 0 times");
+
+ for (i = 0; i < times; i++) {
+ if (!pop_resolver(interp, &resolver)) {
+ return interp_error(interp, "pop resolver");
+ }
+ }
+
+ // we have a loop, push the popped resolver
+ if (resolver.start_tag == i_loop) {
+ debug("repushing resolver\n");
+ if (unlikely(!cursor_push_resolver(&interp->resolver_stack, &resolver))) {
+ return interp_error(interp, "re-push loop resolver");
+ }
+ }
+
+ if (!(label = index_frame_label(interp, resolver.label))) {
+ return interp_error(interp, "index label");
+ }
+
+ return break_jump(interp, &resolver, label);
+}
+
static int parse_block(struct expr_parser *p, struct block *block, u8 start_tag, u8 end_tag)
{
struct label *label = NULL;
@@ -3470,11 +3679,7 @@ static int parse_block(struct expr_parser *p, struct block *block, u8 start_tag,
block->instrs = p->code->start + label_instr_pos(label);
block->instrs_len = (p->code->start + label->jump) - block->instrs;
- if (unlikely(block->instrs_len < 0)) {
- return interp_error(p->interp, "jump is before instr_pos ??");
- }
-
- return pop_label_and_jump(p->interp, label, 1);
+ return pop_label_and_skip(p->interp, label, 1);
}
if (!parse_instrs_until(p, end_tag, &block->instrs, &block->instrs_len))
@@ -3488,35 +3693,35 @@ static int parse_block(struct expr_parser *p, struct block *block, u8 start_tag,
static INLINE int parse_memarg(struct cursor *code, struct memarg *memarg)
{
- return read_int(code, &memarg->align) &&
- read_int(code, &memarg->offset);
+ return read_u32(code, &memarg->align) &&
+ read_u32(code, &memarg->offset);
}
static int parse_call_indirect(struct cursor *code,
struct call_indirect *call_indirect)
{
- return read_int(code, &call_indirect->typeidx) &&
- read_int(code, &call_indirect->tableidx);
+ return read_u32(code, &call_indirect->typeidx) &&
+ read_u32(code, &call_indirect->tableidx);
}
static int parse_br_table(struct cursor *code, struct errors *errs,
struct br_table *br_table)
{
- int i;
+ u32 i;
- if (unlikely(!read_int(code, &br_table->num_label_indices))) {
+ if (unlikely(!read_u32(code, &br_table->num_label_indices))) {
return note_error(errs, code, "fail read br_table num_indices");
}
for (i = 0; i < br_table->num_label_indices; i++) {
- if (unlikely(!read_int(code, &br_table->label_indices[i]))) {
+ if (unlikely(!read_u32(code, &br_table->label_indices[i]))) {
return note_error(errs, code,
"failed to read br_table label %d/%d",
i+1, br_table->num_label_indices);
}
}
- if (unlikely(!read_int(code, &br_table->default_label))) {
+ if (unlikely(!read_u32(code, &br_table->default_label))) {
return note_error(errs, code, "failed to parse default label");
}
@@ -3532,7 +3737,7 @@ static int parse_select(struct cursor *code, struct errors *errs, u8 tag,
return 1;
}
- if (unlikely(!read_int(code, &select->num_valtypes))) {
+ if (unlikely(!read_u32(code, &select->num_valtypes))) {
return note_error(errs, code,
"couldn't parse select valtype vec count");
}
@@ -3577,17 +3782,29 @@ static int parse_instr(struct expr_parser *p, u8 tag, struct instr *op)
case i_global_set:
case i_br:
case i_br_if:
- case i_i32_const:
- case i_i64_const:
case i_ref_func:
case i_table_set:
case i_table_get:
- if (!read_int(p->code, &op->integer)) {
+ if (!read_u32(p->code, &op->u32)) {
return note_error(p->errs, p->code,
"couldn't read int");
}
return 1;
+ case i_i32_const:
+ if (!read_int(p->code, &op->i32)) {
+ return note_error(p->errs, p->code,
+ "couldn't read int");
+ }
+ return 1;
+
+ case i_i64_const:
+ if (!read_i64(p->code, &op->i64)) {
+ return note_error(p->errs, p->code,
+ "couldn't read i64");
+ }
+ return 1;
+
case i_i32_load:
case i_i64_load:
case i_f32_load:
@@ -3764,7 +3981,7 @@ static int parse_instr(struct expr_parser *p, u8 tag, struct instr *op)
static int branch_jump(struct wasm_interp *interp, u8 start_tag, u8 end_tag)
{
u8 *instrs;
- int instrs_len;
+ u32 instrs_len;
struct expr_parser parser;
struct label *label;
@@ -3777,7 +3994,7 @@ static int branch_jump(struct wasm_interp *interp, u8 start_tag, u8 end_tag)
}
if (is_label_resolved(label)) {
- return pop_label_and_jump(interp, label, 1);
+ return pop_label_and_skip(interp, label, 1);
}
make_interp_expr_parser(interp, &parser);
@@ -3815,6 +4032,30 @@ static int interp_block(struct wasm_interp *interp)
return 1;
}
+static INLINE int interp_end(struct wasm_interp *interp)
+{
+ return pop_label_checkpoint(interp);
+
+ /*
+ struct resolver resolver;
+ struct callframe *frame;
+ struct label *label;
+
+ debug("interp end\n");
+
+ if (!pop_label(interp, &resolver, &frame, &label)) {
+ return interp_error(interp, "pop label at end inst");
+ }
+
+ if (resolver.start_tag == i_loop) {
+ debug("loop jumping at end instr\n");
+ return interp_jump(interp, label->jump);
+ }
+
+ return 1;
+ */
+}
+
static int interp_if(struct wasm_interp *interp)
{
struct val cond;
@@ -3857,21 +4098,7 @@ static int interp_i32_eqz(struct wasm_interp *interp)
return cursor_pushval(&interp->stack, &res);
}
-static INLINE struct resolver *top_resolver_stack(struct cursor *stack, int index)
-{
- struct resolver *p = (struct resolver*)stack->p;
- p = &p[-(index+1)];
- if (p < (struct resolver*)stack->start)
- return NULL;
- return p;
-}
-
-static INLINE struct resolver *top_resolver(struct wasm_interp *interp, int index)
-{
- return top_resolver_stack(&interp->resolver_stack, index);
-}
-
-static INLINE struct label *top_label(struct wasm_interp *interp, int index)
+static INLINE struct label *top_label(struct wasm_interp *interp, u32 index)
{
struct resolver *resolver;
@@ -3887,18 +4114,28 @@ static int unresolved_break(struct wasm_interp *interp, int index)
{
struct expr_parser parser;
struct callframe *frame;
- struct label *label;
+ u32 instrs_len;
u8 *instrs;
- int instrs_len;
- struct resolver *resolver;
- debug("breaking %d times from unresolved label\n", index+1);
+ struct resolver *resolver = NULL;
+ struct label *label = NULL;
+
+#if DEBUG
+ int times;
+#endif
+
make_interp_expr_parser(interp, &parser);
if (unlikely(!(frame = top_callframe(&interp->callframes)))) {
return interp_error(interp, "no top callframe?");
}
+
+#if DEBUG
+ times = index+1;
+#endif
+ debug("breaking %d times from unresolved label\n", times);
+
while (index-- >= 0) {
if (unlikely(!(resolver = top_resolver(interp, 0)))) {
return interp_error(interp, "invalid resolver index %d",
@@ -3911,7 +4148,7 @@ static int unresolved_break(struct wasm_interp *interp, int index)
// TODO: breaking from functions (return)
if (is_label_resolved(label)) {
- if (!pop_label_and_jump(interp, label, 1))
+ if (!pop_label_and_skip(interp, label, 1))
return interp_error(interp, "pop and jump");
else
continue;
@@ -3923,16 +4160,30 @@ static int unresolved_break(struct wasm_interp *interp, int index)
}
if (unlikely(!pop_label_checkpoint(interp))) {
- return interp_error(interp, "pop label");
+ return interp_error(interp, "pop label");
}
+ }
+
+ debug("finished breaking %d times from unresolved label (it was a %s)\n",
+ times,
+ instr_name(resolver->start_tag));
+ assert(resolver);
+ assert(label);
+ if (resolver->start_tag == i_loop) {
+ debug("jumping to start of loop\n");
+ if (unlikely(!cursor_push_resolver(&interp->resolver_stack,
+ resolver))) {
+ return interp_error(interp, "re-push loop resolver");
+ }
+ return interp_jump(interp, label_instr_pos(label));
}
return 1;
}
-static int interp_br_jump(struct wasm_interp *interp, int index)
+static int interp_br_jump(struct wasm_interp *interp, u32 index)
{
struct label *label;
@@ -3941,18 +4192,34 @@ static int interp_br_jump(struct wasm_interp *interp, int index)
}
if (is_label_resolved(label)) {
- return pop_label_and_jump(interp, label, index+1);
+ return pop_label_and_break(interp, label, index+1);
}
return unresolved_break(interp, index);
}
-static INLINE int interp_br(struct wasm_interp *interp, int ind)
+static INLINE int interp_br(struct wasm_interp *interp, u32 ind)
{
return interp_br_jump(interp, ind);
}
-static INLINE int interp_br_if(struct wasm_interp *interp, int ind)
+static INLINE int interp_br_table(struct wasm_interp *interp,
+ struct br_table *br_table)
+{
+ int i;
+
+ if (!stack_pop_i32(interp, &i)) {
+ return interp_error(interp, "pop br_table index");
+ }
+
+ if ((u32)i < br_table->num_label_indices) {
+ return interp_br_jump(interp, br_table->label_indices[i]);
+ }
+
+ return interp_br_jump(interp, br_table->default_label);
+}
+
+static INLINE int interp_br_if(struct wasm_interp *interp, u32 ind)
{
int cond = 0;
@@ -3967,7 +4234,7 @@ static INLINE int interp_br_if(struct wasm_interp *interp, int ind)
return 1;
}
-static struct val *get_global_inst(struct wasm_interp *interp, int ind)
+static struct val *get_global_inst(struct wasm_interp *interp, u32 ind)
{
struct global_inst *global_inst;
@@ -3991,7 +4258,7 @@ static struct val *get_global_inst(struct wasm_interp *interp, int ind)
return &global_inst->val;
}
-static int interp_global_get(struct wasm_interp *interp, int ind)
+static int interp_global_get(struct wasm_interp *interp, u32 ind)
{
struct globalsec *section = &interp->module->global_section;
struct val *global;
@@ -4061,6 +4328,11 @@ static int interp_mem_offset(struct wasm_interp *interp,
t->size = *N/8;
t->pos = interp->memory.start + offset;
+ if (t->pos < interp->memory.start) {
+ return interp_error(interp,
+ "invalid memory offset %d\n", offset);
+ }
+
if (t->pos + t->size > interp->memory.p) {
return interp_error(interp,
"mem store oob pos:%d size:%d mem:%d", offset, t->size,
@@ -4073,12 +4345,16 @@ static int interp_mem_offset(struct wasm_interp *interp,
static int wrap_val(struct val *val, unsigned int size) {
switch (val->type) {
case val_i32:
+ if (size == 32)
+ return 1;
//debug("before %d size %d (mask %lx)\n", val->num.i32, size, (1UL << size)-1);
val->num.i32 &= (1UL << size)-1;
//debug("after %d size %d (mask %lx)\n", val->num.i32, size, (1UL << size)-1);
break;
case val_i64:
- val->num.i64 &= (1UL << size)-1;
+ if (size == 64)
+ return 1;
+ val->num.i64 &= (1ULL << size)-1;
break;
default:
return 0;
@@ -4103,8 +4379,9 @@ static int store_val(struct wasm_interp *interp, int i,
}
}
- debug("storing %d at %ld, N:%d\n", val->num.i32,
- target.pos - interp->memory.start, N);
+ debug("storing %d at %ld (%d bytes), N:%d\n", val->num.i32,
+ target.pos - interp->memory.start,
+ target.size, N);
memcpy(target.pos, &val->num.i32, target.size);
@@ -4124,6 +4401,112 @@ static INLINE int store_i32(struct wasm_interp *interp, int offset, int i)
return store_simple(interp, offset, &val);
}
+static int interp_load(struct wasm_interp *interp, struct memarg *memarg,
+ enum valtype type, int N, int sign)
+{
+ struct memtarget target;
+ struct val out = {0};
+ int i;
+
+ (void)sign;
+
+ out.type = type;
+
+ if (unlikely(!stack_pop_i32(interp, &i))) {
+ return interp_error(interp, "pop stack");
+ }
+
+ if (unlikely(!interp_mem_offset(interp, &N, i, type, memarg, &target))) {
+ return interp_error(interp, "memory target");
+ }
+
+ memcpy(&out.num.i32, target.pos, target.size);
+ wrap_val(&out, target.size * 8);
+ debug("loading %d from %ld (copying %d bytes)\n", out.num.i32,
+ target.pos - interp->memory.start, target.size);
+
+ if (unlikely(!stack_pushval(interp, &out))) {
+ return interp_error(interp,
+ "push to stack after load %s", valtype_name(type));
+ }
+
+ return 1;
+}
+
+static INLINE int load_i32(struct wasm_interp *interp, int *i)
+{
+ struct memarg memarg = { .offset = 0, .align = 0 };
+ if (!interp_load(interp, &memarg, val_i32, 0, -1)) {
+ return interp_error(interp, "load");
+ }
+ return stack_pop_i32(interp, i);
+}
+
+static int builtin_fd_write(struct wasm_interp *interp)
+{
+ struct val *fd, *iovs, *iovs_len, *written;
+ int iovec_data = 0;
+ int str_len = 0;
+
+ if (!(fd = get_local(interp, 0)))
+ return interp_error(interp, "fd");
+
+ if (!(iovs = get_local(interp, 1)))
+ return interp_error(interp, "iovs");
+
+ if (!(iovs_len = get_local(interp, 2)))
+ return interp_error(interp, "iovs_len");
+
+ if (!(written = get_local(interp, 3)))
+ return interp_error(interp, "written");
+
+ debug("fd_write %d %d %d %d\n",
+ fd->num.i32,
+ iovs->num.i32,
+ iovs_len->num.i32,
+ written->num.i32
+ );
+
+ if (!stack_push_i32(interp, iovs->num.i32)) {
+ return interp_error(interp, "push iovec ptr");
+ }
+
+ if (!load_i32(interp, &iovec_data)) {
+ return interp_error(interp, "load iovec data");
+ }
+
+ if (!stack_push_i32(interp, iovs->num.i32 + 4)) {
+ return interp_error(interp, "push iovec ptr");
+ }
+
+ if (!load_i32(interp, &str_len)) {
+ return interp_error(interp, "load iovec data");
+ }
+
+ debug("fd_write len %d\n", str_len);
+
+ if (interp->memory.start + iovec_data + str_len >=
+ interp->memory.p) {
+ return interp_error(interp, "fd_write oob");
+ }
+
+ if (fd->num.i32 >= 10) {
+ return interp_error(interp, "weird fd %d", fd->num.i32);
+ }
+
+ written->num.i32 = write(fd->num.i32,
+ interp->memory.start + iovec_data,
+ str_len
+ );
+
+ if (written->num.i32 != str_len) {
+ return interp_error(interp, "written %d != %d",
+ written->num.i32, str_len);
+ }
+
+ return stack_push_i32(interp, written->num.i32);
+}
+
static int builtin_get_args(struct wasm_interp *interp)
{
struct val *argv, *argv_buf;
@@ -4182,37 +4565,6 @@ static int interp_store(struct wasm_interp *interp, struct memarg *memarg,
return store_val(interp, i, memarg, type, &c, N);
}
-static int interp_load(struct wasm_interp *interp, struct memarg *memarg,
- enum valtype type, int N, int sign)
-{
- struct memtarget target;
- struct val out = {0};
- int i;
-
- (void)sign;
-
- out.type = type;
-
- if (unlikely(!stack_pop_i32(interp, &i))) {
- return interp_error(interp, "pop stack");
- }
-
- if (unlikely(!interp_mem_offset(interp, &N, i, type, memarg, &target))) {
- return interp_error(interp, "memory target");
- }
-
- memcpy(&out.num.i32, target.pos, target.size);
- wrap_val(&out, target.size * 8);
- debug("loading %d from %ld (copying %d bytes)\n", out.num.i32,
- target.pos - interp->memory.start, target.size);
-
- if (unlikely(!stack_pushval(interp, &out))) {
- return interp_error(interp,
- "push to stack after load %s", valtype_name(type));
- }
-
- return 1;
-}
static INLINE int interp_global_set(struct wasm_interp *interp, int global_ind)
{
@@ -4238,8 +4590,7 @@ static INLINE int active_pages(struct wasm_interp *interp)
static int interp_memory_grow(struct wasm_interp *interp, u8 memidx)
{
- int pages = 0, prev_size;
- unsigned int grow;
+ int pages = 0, prev_size, grow;
(void)memidx;
@@ -4279,6 +4630,36 @@ static INLINE int interp_memory_size(struct wasm_interp *interp, u8 memidx)
return 1;
}
+static INLINE int interp_i32_eq(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) {
+ return interp_error(interp, "binop prep");
+ }
+
+ return stack_push_i32(interp, lhs.num.i32 == rhs.num.i32);
+}
+
+static INLINE int interp_i32_wrap_i64(struct wasm_interp *interp)
+{
+ int64_t n;
+ if (unlikely(!stack_pop_i64(interp, &n)))
+ return interp_error(interp, "pop");
+ return stack_push_i32(interp, (int)n);
+}
+
+static INLINE int interp_i32_xor(struct wasm_interp *interp)
+{
+ struct val lhs, rhs, c;
+
+ if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) {
+ return interp_error(interp, "binop prep");
+ }
+
+ return stack_push_i32(interp, lhs.num.i32 ^ rhs.num.i32);
+}
+
static INLINE int interp_i32_ne(struct wasm_interp *interp)
{
struct val lhs, rhs, c;
@@ -4450,7 +4831,7 @@ static int interp_loop(struct wasm_interp *interp)
}
static INLINE int table_set(struct wasm_interp *interp,
- struct table_inst *table, int ind, struct val *val)
+ struct table_inst *table, u32 ind, struct val *val)
{
if (unlikely(ind >= table->num_refs)) {
@@ -4478,7 +4859,7 @@ static INLINE int table_set(struct wasm_interp *interp,
return 1;
}
-static int interp_table_set(struct wasm_interp *interp, int tableidx)
+static int interp_table_set(struct wasm_interp *interp, u32 tableidx)
{
struct table_inst *table;
struct val val;
@@ -4503,10 +4884,11 @@ static int interp_table_set(struct wasm_interp *interp, int tableidx)
return table_set(interp, table, ind, &val);
}
-static int interp_memory_init(struct wasm_interp *interp, int dataidx)
+static int interp_memory_init(struct wasm_interp *interp, u32 dataidx)
{
struct wdata *data;
- int count, src, dst, num_data;
+ int count, src, dst;
+ u32 num_data;
num_data = interp->module->data_section.num_datas;
if (unlikely(dataidx >= num_data)) {
@@ -4525,10 +4907,7 @@ static int interp_memory_init(struct wasm_interp *interp, int dataidx)
if(unlikely(!stack_pop_i32(interp, &dst)))
return interp_error(interp, "pop dst");
- debug("memory_init src:%d dst:%d count:%d\n",
- src, dst, count);
-
- if (src + count > data->bytes_len) {
+ if (src + count > (int)data->bytes_len) {
return interp_error(interp, "count %d > data len %d", count,
data->bytes_len);
}
@@ -4538,8 +4917,11 @@ static int interp_memory_init(struct wasm_interp *interp, int dataidx)
count, interp->memory.p - interp->memory.start);
}
- memcpy(interp->memory.start + dst + count,
- data->bytes + src + count,
+ debug("memory_init src:%d dst:%d count:%d\n",
+ src, dst, count);
+
+ memcpy(interp->memory.start + dst,
+ data->bytes + src,
count);
return 1;
@@ -4597,13 +4979,13 @@ static int interp_table_init(struct wasm_interp *interp,
}
for (; num_inits; num_inits--, dst++, src++) {
- if (unlikely(src + num_inits > interp->module_inst.num_elements)) {
+ if (unlikely((u32)src + num_inits > interp->module_inst.num_elements)) {
return interp_error(interp, "index oob elem.elem s+n %d (max %d)",
src + num_inits,
interp->module_inst.num_elements + 1);
}
- if (unlikely(dst + num_inits > table->num_refs)) {
+ if (unlikely((u32)dst + num_inits > table->num_refs)) {
return interp_error(interp, "index oob tab.elem d+n %d (max %d)",
dst + num_inits,
table->num_refs + 1);
@@ -4681,16 +5063,17 @@ static int interp_instr(struct wasm_interp *interp, struct instr *instr)
case i_selects:
return interp_select(interp, &instr->select);
- case i_local_get: return interp_local_get(interp, instr->integer);
- case i_local_set: return interp_local_set(interp, instr->integer);
- case i_local_tee: return interp_local_tee(interp, instr->integer);
- case i_global_get: return interp_global_get(interp, instr->integer);
- case i_global_set: return interp_global_set(interp, instr->integer);
+ case i_local_get: return interp_local_get(interp, instr->i32);
+ case i_local_set: return interp_local_set(interp, instr->i32);
+ case i_local_tee: return interp_local_tee(interp, instr->i32);
+ case i_global_get: return interp_global_get(interp, instr->i32);
+ case i_global_set: return interp_global_set(interp, instr->i32);
case i_i32_eqz: return interp_i32_eqz(interp);
case i_i32_add: return interp_i32_add(interp);
case i_i32_sub: return interp_i32_sub(interp);
- case i_i32_const: return interp_i32_const(interp, instr->integer);
+ case i_i32_const: return interp_i32_const(interp, instr->i32);
+ case i_i32_div_u: return interp_i32_div_u(interp);
case i_i32_ge_u: return interp_i32_ge_u(interp);
case i_i32_ge_s: return interp_i32_ge_s(interp);
case i_i32_gt_u: return interp_i32_gt_u(interp);
@@ -4703,10 +5086,20 @@ static int interp_instr(struct wasm_interp *interp, struct instr *instr)
case i_i32_or: return interp_i32_or(interp);
case i_i32_and: return interp_i32_and(interp);
case i_i32_mul: return interp_i32_mul(interp);
+ case i_i32_xor: return interp_i32_xor(interp);
case i_i32_ne: return interp_i32_ne(interp);
-
+ case i_i32_eq: return interp_i32_eq(interp);
+ case i_i32_wrap_i64:return interp_i32_wrap_i64(interp);
+
+ case i_i64_eqz: return interp_i64_eqz(interp);
+ case i_i64_gt_s: return interp_i64_gt_s(interp);
+ case i_i64_gt_u: return interp_i64_gt_u(interp);
+ case i_i64_ge_u: return interp_i64_ge_u(interp);
+ case i_i64_div_u: return interp_i64_div_u(interp);
+ case i_i64_mul: return interp_i64_mul(interp);
case i_i64_shl: return interp_i64_shl(interp);
case i_i64_or: return interp_i64_or(interp);
+ case i_i64_sub: return interp_i64_sub(interp);
case i_i64_const: return interp_i64_const(interp, instr->i64);
case i_i64_extend_i32_u: return interp_extend(interp, val_i64, val_i32, 0);
@@ -4740,16 +5133,17 @@ static int interp_instr(struct wasm_interp *interp, struct instr *instr)
case i_drop: return interp_drop(interp);
case i_loop: return interp_loop(interp);
case i_if: return interp_if(interp);
- case i_end: return pop_label_checkpoint(interp);
- case i_call: return interp_call(interp, instr->integer);
+ case i_end: return interp_end(interp);
+ case i_call: return interp_call(interp, instr->i32);
case i_call_indirect: return interp_call_indirect(interp, &instr->call_indirect);
case i_block: return interp_block(interp);
- case i_br: return interp_br(interp, instr->integer);
- case i_br_if: return interp_br_if(interp, instr->integer);
+ case i_br: return interp_br(interp, instr->i32);
+ case i_br_table: return interp_br_table(interp, &instr->br_table);
+ case i_br_if: return interp_br_if(interp, instr->i32);
case i_memory_size: return interp_memory_size(interp, instr->memidx);
case i_memory_grow: return interp_memory_grow(interp, instr->memidx);
case i_table_op: return interp_error(interp, "todo: interp table_op");
- case i_table_set: return interp_table_set(interp, instr->integer);
+ case i_table_set: return interp_table_set(interp, instr->i32);
case i_return: return interp_return(interp);
default:
interp_error(interp, "unhandled instruction %s 0x%x",
@@ -4809,8 +5203,10 @@ static enum interp_end interp_code_end(struct wasm_interp *interp,
struct callframe *frame, struct cursor *code)
{
struct resolver *resolver;
- struct label *label;
+ //struct label *label;
int num_resolvers = 0;
+ (void)frame;
+ (void)code;
if (unlikely(!(resolver = top_resolver(interp, 0)))) {
// no more resolvers, we done.
@@ -4828,6 +5224,7 @@ static enum interp_end interp_code_end(struct wasm_interp *interp,
}
// if we hit the end of a loop, continue at the start
+ /*
if (resolver && resolver->start_tag == i_loop) {
if (unlikely(!(label = index_label(&interp->labels, frame->fn,
resolver->label)))) {
@@ -4843,6 +5240,7 @@ static enum interp_end interp_code_end(struct wasm_interp *interp,
return interp_end_cont;
}
+ */
return interp_end_next;
}
@@ -4904,7 +5302,7 @@ static int interp_code(struct wasm_interp *interp)
static int find_function(struct module *module, const char *name)
{
struct wexport *export;
- int i;
+ u32 i;
for (i = 0; i < module->export_section.num_exports; i++) {
export = &module->export_section.exports[i];
@@ -4949,7 +5347,7 @@ void wasm_parser_init(struct wasm_parser *p, u8 *wasm, size_t wasm_len, size_t a
static int count_fn_locals(struct func *func)
{
- int i, num_locals = 0;
+ u32 i, num_locals = 0;
num_locals += func->functype->params.num_valtypes;
@@ -4965,7 +5363,7 @@ static int count_fn_locals(struct func *func)
static int calculate_tables_size(struct module *module)
{
- int i, num_tables, size;
+ u32 i, num_tables, size;
struct table *tables;
if (!was_section_parsed(module, section_table))
@@ -4984,10 +5382,9 @@ static int calculate_tables_size(struct module *module)
static int alloc_tables(struct wasm_interp *interp)
{
- int size;
struct table *t;
struct table_inst *inst;
- int i;
+ u32 i, size;
if (!was_section_parsed(interp->module, section_table))
return 1;
@@ -5021,7 +5418,7 @@ static int alloc_tables(struct wasm_interp *interp)
static int calculate_locals_size(struct module *module)
{
- int i, locals_size = 0;
+ u32 i, locals_size = 0;
struct func *func;
for (i = 0; i < module->num_funcs; i++) {
@@ -5037,7 +5434,7 @@ static int calculate_locals_size(struct module *module)
static int alloc_locals(struct module *module, struct cursor *mem,
struct errors *errs)
{
- int i, j, num_locals, size, sizes = 0;
+ u32 i, j, k, num_locals, size, sizes = 0, ind;
struct func *func;
for (i = 0; i < module->num_funcs; i++) {
@@ -5057,9 +5454,23 @@ static int alloc_locals(struct module *module, struct cursor *mem,
func->name);
}
- for (j = 0; j < func->num_locals; j++) {
+ for (j = 0, ind = 0; j < func->functype->params.num_valtypes; j++, ind++) {
func->locals[j].val.type = func->functype->params.valtypes[j];
}
+
+ if (func->type != func_type_wasm)
+ continue;
+
+ for (j = 0; j < func->wasm_func->num_locals; j++) {
+ for (k = 0; k < func->wasm_func->locals[j].val.num.u32; k++, ind++) {
+ debug("initializing function %d local %d to type %s\n",
+ i, ind, valtype_name(
+ func->wasm_func->locals[j].val.type));
+
+ func->locals[ind].val.type =
+ func->wasm_func->locals[j].val.type;
+ }
+ }
}
debug("alloc_locals sizes %d\n", sizes);
@@ -5134,7 +5545,7 @@ static int init_globals(struct wasm_interp *interp)
{
struct global *globals, *global;
struct global_inst *global_insts, *global_inst;
- int i;
+ u32 i;
if (!was_section_parsed(interp->module, section_global)) {
// nothing to init
@@ -5159,7 +5570,7 @@ static int init_globals(struct wasm_interp *interp)
static int count_element_insts(struct module *module)
{
struct elem *elem;
- int i, size = 0;
+ u32 i, size = 0;
if (!was_section_parsed(module, section_element))
return 0;
@@ -5230,7 +5641,7 @@ static int init_memories(struct wasm_interp *interp)
static int init_tables(struct wasm_interp *interp)
{
struct elem *elem;
- int i;
+ u32 i;
if (!was_section_parsed(interp->module, section_table))
return 1;
@@ -5254,8 +5665,8 @@ static int init_elements(struct wasm_interp *interp)
struct elem *elems, *elem;
struct elem_inst *inst;
struct expr *init;
- int count = 0;
- int i, j;
+ u32 count = 0;
+ u32 i, j;
debug("init elements\n");
diff --git a/src/wasm.h b/src/wasm.h
@@ -41,8 +41,8 @@ enum limit_type {
};
struct limits {
- unsigned int min;
- unsigned int max;
+ u32 min;
+ u32 max;
enum limit_type type;
};
@@ -69,7 +69,7 @@ enum reftype {
struct resulttype {
unsigned char *valtypes; /* enum valtype */
- int num_valtypes;
+ u32 num_valtypes;
};
struct functype {
@@ -84,7 +84,7 @@ struct table {
struct tablesec {
struct table *tables;
- int num_tables;
+ u32 num_tables;
};
enum elem_mode {
@@ -94,24 +94,26 @@ enum elem_mode {
};
struct expr {
- unsigned char *code;
- int code_len;
+ u8 *code;
+ u32 code_len;
};
struct refval {
- int addr;
+ u32 addr;
};
struct table_inst {
struct refval *refs;
enum reftype reftype;
- int num_refs;
+ u32 num_refs;
};
struct numval {
union {
int i32;
- u64 i64;
+ u32 u32;
+ int64_t i64;
+ uint64_t u64;
float f32;
double f64;
};
@@ -133,9 +135,9 @@ struct elem_inst {
struct elem {
struct expr offset;
- int tableidx;
+ u32 tableidx;
struct expr *inits;
- int num_inits;
+ u32 num_inits;
enum elem_mode mode;
enum reftype reftype;
struct val val;
@@ -149,17 +151,17 @@ struct customsec {
struct elemsec {
struct elem *elements;
- int num_elements;
+ u32 num_elements;
};
struct memsec {
struct limits *mems; /* memtype */
- int num_mems;
+ u32 num_mems;
};
struct funcsec {
- unsigned int *type_indices;
- int num_indices;
+ u32 *type_indices;
+ u32 num_indices;
};
enum mut {
@@ -174,12 +176,12 @@ struct globaltype {
struct globalsec {
struct global *globals;
- int num_globals;
+ u32 num_globals;
};
struct typesec {
struct functype *functypes;
- int num_functypes;
+ u32 num_functypes;
};
enum import_type {
@@ -192,7 +194,7 @@ enum import_type {
struct importdesc {
enum import_type type;
union {
- unsigned int typeidx;
+ u32 typeidx;
struct limits tabletype;
struct limits memtype;
struct globaltype globaltype;
@@ -208,7 +210,7 @@ struct import {
struct importsec {
struct import *imports;
- int num_imports;
+ u32 num_imports;
};
struct global {
@@ -225,7 +227,7 @@ struct local {
struct wasm_func {
struct expr code;
struct local *locals;
- int num_locals;
+ u32 num_locals;
};
enum func_type {
@@ -239,7 +241,7 @@ struct func {
struct builtin *builtin;
};
struct local *locals;
- int num_locals;
+ u32 num_locals;
struct functype *functype;
enum func_type type;
const char *name;
@@ -247,7 +249,7 @@ struct func {
struct codesec {
struct wasm_func *funcs;
- int num_funcs;
+ u32 num_funcs;
};
enum exportdesc {
@@ -259,13 +261,13 @@ enum exportdesc {
struct wexport {
const char *name;
- unsigned int index;
+ u32 index;
enum exportdesc desc;
};
struct exportsec {
struct wexport *exports;
- int num_exports;
+ u32 num_exports;
};
struct section {
@@ -499,33 +501,33 @@ struct blocktype {
struct block {
struct blocktype type;
unsigned char *instrs;
- int instrs_len;
+ u32 instrs_len;
};
struct memarg {
- int offset;
- int align;
+ u32 offset;
+ u32 align;
};
struct br_table {
- int num_label_indices;
- int label_indices[32];
- int default_label;
+ u32 num_label_indices;
+ u32 label_indices[32];
+ u32 default_label;
};
struct call_indirect {
- int tableidx;
- int typeidx;
+ u32 tableidx;
+ u32 typeidx;
};
struct table_init {
- int tableidx;
- int elemidx;
+ u32 tableidx;
+ u32 elemidx;
};
struct select_instr {
u8 *valtypes;
- int num_valtypes;
+ u32 num_valtypes;
};
struct instr {
@@ -540,8 +542,10 @@ struct instr {
struct block block;
double fp_double;
float fp_single;
- int integer;
+ int i32;
+ u32 u32;
int64_t i64;
+ u64 u64;
unsigned char memidx;
enum reftype reftype;
};
@@ -553,14 +557,14 @@ enum datamode {
};
struct wdata_active {
- int mem_index;
+ u32 mem_index;
struct expr offset_expr;
};
struct wdata {
struct wdata_active active;
- unsigned char *bytes;
- int bytes_len;
+ u8 *bytes;
+ u32 bytes_len;
enum datamode mode;
};
@@ -570,7 +574,7 @@ struct datasec {
};
struct startsec {
- int start_fn;
+ u32 start_fn;
};
struct module {
@@ -578,7 +582,7 @@ struct module {
unsigned int custom_sections;
struct func *funcs;
- int num_funcs;
+ u32 num_funcs;
struct customsec custom_section[MAX_CUSTOM_SECTIONS];
struct typesec type_section;
@@ -602,7 +606,7 @@ struct label {
struct callframe {
struct cursor code;
- int fn;
+ u32 fn;
};
struct resolver {
@@ -620,9 +624,9 @@ struct module_inst {
struct global_inst *globals;
struct elem_inst *elements;
- int num_tables;
- int num_globals;
- int num_elements;
+ u32 num_tables;
+ u32 num_globals;
+ u32 num_elements;
int start_fn;
unsigned char *globals_init;
diff --git a/wasm/hello-c.c b/wasm/hello-c.c
@@ -1,14 +0,0 @@
-#include <stdio.h>
-
-int add(int a, int b, int c, int d)
-{
- return a + b + c + d;
-}
-
-int main(int argc, const char *argv[])
-{
- printf("Hello, world? %d\n", add(1,2,3,4));
- return 0;
-}
-
-
diff --git a/wasm/hello-c.wasm b/wasm/hello-c.wasm
Binary files differ.
diff --git a/wasm/hello.wasm b/wasm/hello.wasm
Binary files differ.
diff --git a/wasm/hello.wat b/wasm/hello.wat
@@ -10,12 +10,8 @@
)
(func $start (result i32)
(local i32 i32)
- i32.const 65537
- local.set 0
- local.get 0
+ i32.const 1
i32.const 2
- call $add
- i32.const 3
call $sub
)
(export "start" (func $start))
diff --git a/wasm/loop.wat b/wasm/loop.wat
@@ -12,15 +12,17 @@
(local i32 i32)
i32.const 0
local.set 0
- loop
- local.get 0
- i32.const 1
- i32.add
- local.set 0
- local.get 0
- i32.const 4
- i32.gt_u
- br_if 0
+ block
+ loop
+ local.get 0
+ i32.const 1
+ i32.add
+ local.set 0
+ i32.const 4
+ local.get 0
+ i32.gt_u
+ br_if 0
+ end
end
i32.const 0
)