protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

wasm.c (176788B)


      1 
      2 #include "wasm.h"
      3 #include "parser.h"
      4 #include "debug.h"
      5 #include "error.h"
      6 
      7 #include <unistd.h>
      8 #include <math.h>
      9 #include <limits.h>
     10 #include <stdarg.h>
     11 #include <stdio.h>
     12 #include <assert.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 #include <stdint.h>
     16 #include <inttypes.h>
     17 
     18 #define interp_error(p, fmt, ...) note_error(&((p)->errors), interp_codeptr(p), fmt, ##__VA_ARGS__)
     19 #define parse_err(p, fmt, ...) note_error(&((p)->errs), &(p)->cur, fmt, ##__VA_ARGS__)
     20 
     21 #ifdef NOINLINE
     22   #define INLINE __attribute__((noinline))
     23 #else
     24   #define INLINE inline
     25 #endif
     26 
     27 #define ERR_STACK_SIZE 16
     28 #define NUM_LOCALS 0xFFFF
     29 #define WASM_PAGE_SIZE 65536
     30 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
     31 
     32 static const int MAX_LABELS = 1024;
     33 
     34 static int interp_code(struct wasm_interp *interp);
     35 static INLINE int pop_label_checkpoint(struct wasm_interp *interp);
     36 
     37 struct expr_parser {
     38 	struct wasm_interp *interp; // optional...
     39 	struct cursor *code;
     40 	struct errors *errs;
     41 	struct cursor *stack; // optional
     42 };
     43 
     44 static INLINE struct callframe *top_callframes(struct cursor *cur, int top)
     45 {
     46 	return (struct callframe*)cursor_topn(cur, sizeof(struct callframe), top);
     47 }
     48 
     49 static INLINE struct callframe *top_callframe(struct cursor *cur)
     50 {
     51 	return (struct callframe*)cursor_top(cur, sizeof(struct callframe));
     52 }
     53 
     54 static INLINE struct cursor *interp_codeptr(struct wasm_interp *interp)
     55 {
     56 	struct callframe *frame;
     57 	if (unlikely(!(frame = top_callframe(&interp->callframes))))
     58 		return 0;
     59 	return &frame->code;
     60 }
     61 
     62 static INLINE int cursor_popval(struct cursor *cur, struct val *val)
     63 {
     64 	return cursor_pop(cur, (unsigned char*)val, sizeof(*val));
     65 }
     66 
     67 static const char *valtype_name(enum valtype valtype)
     68 {
     69 	switch (valtype) {
     70 	case val_i32: return "i32";
     71 	case val_i64: return "i64";
     72 	case val_f32: return "f32";
     73 	case val_f64: return "f64";
     74 	case val_ref_null: return "null";
     75 	case val_ref_func: return "func";
     76 	case val_ref_extern: return "extern";
     77 	}
     78 
     79 	return "?";
     80 }
     81 
     82 static const char *reftype_name(enum reftype reftype) {
     83 	return valtype_name((enum valtype)reftype);
     84 }
     85 
     86 static const char *valtype_literal(enum valtype valtype)
     87 {
     88 	switch (valtype) {
     89 	case val_i32: return "";
     90 	case val_i64: return "L";
     91 	case val_f32: return "";
     92 	case val_f64: return "f";
     93 	case val_ref_null: return "null";
     94 	case val_ref_func: return "func";
     95 	case val_ref_extern: return "extern";
     96 	}
     97 
     98 	return "?";
     99 }
    100 
    101 static INLINE int is_valid_fn_index(struct module *module, u32 ind)
    102 {
    103 	return ind < module->num_funcs;
    104 }
    105 
    106 static INLINE struct func *get_fn(struct module *module, u32 ind)
    107 {
    108 	if (unlikely(!is_valid_fn_index(module, ind)))
    109 		return NULL;
    110 	return &module->funcs[ind];
    111 }
    112 
    113 static INLINE u8 *mem_ptr(struct wasm_interp *interp, u32 ptr, int size)
    114 {
    115 	u8 *pos = interp->memory.start + ptr;
    116 
    117 	if (ptr == 0) {
    118 		interp_error(interp, "null mem_ptr");
    119 		return NULL;
    120 	}
    121 
    122 	if (pos + size >= interp->memory.p) {
    123 		interp_error(interp, "guest invalid mem read: %d > %d",
    124 			pos, interp->memory.p - interp->memory.start);
    125 		return NULL;
    126 	}
    127 
    128 	return pos;
    129 }
    130 
    131 static INLINE int read_mem(struct wasm_interp *interp, u32 ptr, int size,
    132 		void *dest)
    133 {
    134 	u8 *mem;
    135 	if (!(mem = mem_ptr(interp, ptr, size)))
    136 		return interp_error(interp, "invalid mem pointer");
    137 	memcpy(dest, mem, size);
    138 	return 1;
    139 }
    140 
    141 static INLINE int read_mem_u32(struct wasm_interp *interp, u32 ptr, u32 *i)
    142 {
    143 	return read_mem(interp, ptr, sizeof(*i), i);
    144 }
    145 
    146 static INLINE int mem_ptr_i32(struct wasm_interp *interp, u32 ptr, int **i)
    147 {
    148 	if (!(*i = (int*)mem_ptr(interp, ptr, sizeof(int))))
    149 		return interp_error(interp, "int memptr");
    150 	return 1;
    151 }
    152 
    153 static INLINE int mem_ptr_f32(struct wasm_interp *interp, u32 ptr, float **i)
    154 {
    155 	if (!(*i = (float*)mem_ptr(interp, ptr, sizeof(float))))
    156 		return interp_error(interp, "int memptr");
    157 	return 1;
    158 }
    159 
    160 static INLINE int mem_ptr_u32(struct wasm_interp *interp, u32 ptr, u32 **i)
    161 {
    162 	if (!(*i = (u32*)mem_ptr(interp, ptr, sizeof(int))))
    163 		return interp_error(interp, "uint memptr");
    164 	return 1;
    165 }
    166 
    167 static INLINE int mem_ptr_u32_arr(struct wasm_interp *interp, u32 ptr, int n, u32 **i)
    168 {
    169 	if (!(*i = (u32*)mem_ptr(interp, ptr, n * sizeof(int))))
    170 		return interp_error(interp, "uint memptr");
    171 	return 1;
    172 }
    173 
    174 
    175 static INLINE int mem_ptr_str(struct wasm_interp *interp, u32 ptr,
    176 		const char **str)
    177 {
    178 	// still technically unsafe if the string runs over the end of memory...
    179 	if (!(*str = (const char*)mem_ptr(interp, ptr, 1))) {
    180 		return interp_error(interp, "int memptr");
    181 	}
    182 	return 1;
    183 }
    184 
    185 static INLINE int read_mem_i32(struct wasm_interp *interp, u32 ptr, int *i)
    186 {
    187 	return read_mem(interp, ptr, sizeof(*i), i);
    188 }
    189 
    190 static INLINE struct val *get_local(struct wasm_interp *interp, u32 ind)
    191 {
    192 	struct callframe *frame;
    193 
    194 	if (unlikely(!(frame = top_callframe(&interp->callframes)))) {
    195 		interp_error(interp, "no callframe?");
    196 		return NULL;
    197 	}
    198 
    199 	if (unlikely(ind >= frame->func->num_locals)) {
    200 		interp_error(interp, "local index %d too high for %s:%d (max %d)",
    201 				ind, frame->func->name, frame->func->idx,
    202 				frame->func->num_locals-1);
    203 		return NULL;
    204 	}
    205 
    206 	return &frame->locals[ind];
    207 }
    208 
    209 static INLINE int get_params(struct wasm_interp *interp, struct val** vals,
    210 			     u32 num_vals)
    211 {
    212 	struct callframe *frame;
    213 
    214 	if (unlikely(!(frame = top_callframe(&interp->callframes))))
    215 		return interp_error(interp, "no callframe?");
    216 
    217 	if (unlikely(num_vals != frame->func->functype->params.num_valtypes)) {
    218 		return interp_error(interp,
    219 				"requested %d params, but there are %d",
    220 				num_vals, frame->func->functype->params.num_valtypes);
    221 	}
    222 
    223 	*vals = frame->locals;
    224 
    225 	return 1;
    226 }
    227 
    228 static INLINE int stack_popval(struct wasm_interp *interp, struct val *val)
    229 {
    230 	return cursor_popval(&interp->stack, val);
    231 }
    232 
    233 static INLINE struct val *cursor_topval(struct cursor *stack)
    234 {
    235 	return (struct val *)cursor_top(stack, sizeof(struct val));
    236 }
    237 
    238 static INLINE struct val *stack_topval(struct wasm_interp *interp)
    239 {
    240 	return cursor_topval(&interp->stack);
    241 }
    242 
    243 static INLINE struct val *stack_top_type(struct wasm_interp *interp,
    244 					 enum valtype type)
    245 {
    246 	struct val *val;
    247 	if (unlikely(!(val = stack_topval(interp)))) {
    248 		interp_error(interp, "pop");
    249 		return NULL;
    250 	}
    251 	if (val->type != type) {
    252 		interp_error(interp,
    253 				"type mismatch: got %s, expected %s",
    254 				valtype_name(val->type),
    255 				valtype_name(type)
    256 				);
    257 		return NULL;
    258 	}
    259 	return val;
    260 }
    261 
    262 static INLINE struct val *stack_top_i32(struct wasm_interp *interp)
    263 {
    264 	return stack_top_type(interp, val_i32);
    265 }
    266 
    267 static INLINE struct val *stack_top_f32(struct wasm_interp *interp)
    268 {
    269 	return stack_top_type(interp, val_f32);
    270 }
    271 
    272 static INLINE struct val *stack_top_f64(struct wasm_interp *interp)
    273 {
    274 	return stack_top_type(interp, val_f64);
    275 }
    276 
    277 static INLINE struct val *stack_top_i64(struct wasm_interp *interp)
    278 {
    279 	return stack_top_type(interp, val_i64);
    280 }
    281 
    282 static INLINE int cursor_pop_i32(struct cursor *stack, int *i)
    283 {
    284 	struct val val;
    285 	if (unlikely(!cursor_popval(stack, &val)))
    286 		return 0;
    287 	if (unlikely(val.type != val_i32))
    288 		return 0;
    289 	*i = val.num.i32;
    290 	return 1;
    291 }
    292 
    293 static INLINE int cursor_pop_i64(struct cursor *stack, int64_t *i)
    294 {
    295 	struct val val;
    296 	if (unlikely(!cursor_popval(stack, &val)))
    297 		return 0;
    298 	if (unlikely(val.type != val_i64))
    299 		return 0;
    300 	*i = val.num.i64;
    301 	return 1;
    302 }
    303 
    304 
    305 static int is_reftype(enum valtype type)
    306 {
    307 	switch (type) {
    308 	case val_i32:
    309 	case val_i64:
    310 	case val_f32:
    311 	case val_f64:
    312 		return 0;
    313 	case val_ref_null:
    314 	case val_ref_func:
    315 	case val_ref_extern:
    316 		return 1;
    317 	}
    318 	return 0;
    319 }
    320 
    321 /*
    322 static INLINE int cursor_pop_ref(struct cursor *stack, struct val *val)
    323 {
    324 	if (!cursor_popval(stack, val)) {
    325 		return 0;
    326 	}
    327 	if (!is_reftype(val->type)) {
    328 		return 0;
    329 	}
    330 	return 1;
    331 }
    332 */
    333 
    334 static INLINE int stack_pop_ref(struct wasm_interp *interp, struct val *val)
    335 {
    336 	if (!cursor_popval(&interp->stack, val)) {
    337 		return interp_error(interp, "no value on stack");
    338 	}
    339 	if (!is_reftype(val->type)) {
    340 		return interp_error(interp, "not a reftype, got %s",
    341 				valtype_name(val->type));
    342 	}
    343 	return 1;
    344 }
    345 
    346 static INLINE int stack_pop_i32(struct wasm_interp *interp, int *i)
    347 {
    348 	return cursor_pop_i32(&interp->stack, i);
    349 }
    350 
    351 static INLINE int stack_pop_i64(struct wasm_interp *interp, int64_t *i)
    352 {
    353 	return cursor_pop_i64(&interp->stack, i);
    354 }
    355 
    356 static INLINE int cursor_pop_valtype(struct cursor *stack, enum valtype type,
    357 		struct val *val)
    358 {
    359 	if (unlikely(!cursor_popval(stack, val))) {
    360 		return 0;
    361 	}
    362 
    363 	if (unlikely(val->type != type)) {
    364 		return 0;
    365 	}
    366 
    367 	return 1;
    368 }
    369 
    370 static INLINE int stack_pop_valtype(struct wasm_interp *interp,
    371 		enum valtype type, struct val *val)
    372 {
    373 	return cursor_pop_valtype(&interp->stack, type, val);
    374 }
    375 
    376 static void print_val(struct val *val)
    377 {
    378 	switch (val->type) {
    379 	case val_i32: printf("%d", val->num.i32); break;
    380 	case val_i64: printf("%" PRId64, val->num.i64); break;
    381 	case val_f32: printf("%f", val->num.f32); break;
    382 	case val_f64: printf("%f", val->num.f64); break;
    383 
    384 	case val_ref_null:
    385 		      break;
    386 	case val_ref_func:
    387 	case val_ref_extern:
    388 		      printf("%d", val->ref.addr);
    389 		      break;
    390 	}
    391 	printf("%s", valtype_literal(val->type));
    392 }
    393 
    394 #ifdef DEBUG
    395 static void print_refval(struct refval *ref, enum reftype reftype)
    396 {
    397 	struct val val;
    398 	val.type = (enum valtype)reftype;
    399 	val.ref = *ref;
    400 	print_val(&val);
    401 }
    402 #endif
    403 
    404 static void print_stack(struct cursor *stack)
    405 {
    406 	struct val val;
    407 	int i;
    408 	u8 *p = stack->p;
    409 
    410 	if (stack->p == stack->start) {
    411 		return;
    412 	}
    413 
    414 	for (i = 0; stack->p > stack->start; i++) {
    415 		cursor_popval(stack, &val);
    416 		printf("[%d] ", i);
    417 		print_val(&val);
    418 		printf("\n");
    419 	}
    420 
    421 	stack->p = p;
    422 }
    423 
    424 void print_callstack(struct wasm_interp *interp)
    425 {
    426 	int i = 0;
    427 	struct callframe *frame;
    428 
    429 	printf("callstack:\n");
    430 	while ((frame = top_callframes(&interp->callframes, i++))) {
    431 		if (!frame->func) {
    432 			printf("??\n");
    433 			continue;
    434 		}
    435 		else {
    436 			printf("%d %s:%d\n", i, frame->func->name, frame->func->idx);
    437 		}
    438 	}
    439 }
    440 
    441 static INLINE int cursor_pushval(struct cursor *cur, struct val *val)
    442 {
    443 	return cursor_push(cur, (u8*)val, sizeof(*val));
    444 }
    445 
    446 static INLINE int cursor_push_i32(struct cursor *stack, int i)
    447 {
    448 	struct val val;
    449 	val.type = val_i32;
    450 	val.num.i32 = i;
    451 
    452 	return cursor_pushval(stack, &val);
    453 }
    454 
    455 static INLINE int cursor_push_u64(struct cursor *stack, u64 i)
    456 {
    457 	struct val val;
    458 	val.type = val_i64;
    459 	val.num.u64 = i;
    460 
    461 	return cursor_pushval(stack, &val);
    462 }
    463 
    464 static INLINE int cursor_push_funcref(struct cursor *stack, int addr)
    465 {
    466 	struct val val;
    467 	val.type = val_ref_func;
    468 	val.ref.addr = addr;
    469 	return cursor_pushval(stack, &val);
    470 }
    471 
    472 static INLINE int stack_push_i64(struct wasm_interp *interp, s64 i)
    473 {
    474 	return cursor_push_u64(&interp->stack, (u64)i);
    475 }
    476 
    477 static INLINE int stack_push_u64(struct wasm_interp *interp, u64 i)
    478 {
    479 	return cursor_push_u64(&interp->stack, i);
    480 }
    481 
    482 
    483 static INLINE int stack_push_i32(struct wasm_interp *interp, int i)
    484 {
    485 	return cursor_push_i32(&interp->stack, i);
    486 }
    487 
    488 static INLINE void make_i32_val(struct val *val, int v)
    489 {
    490 	val->type = val_i32;
    491 	val->num.i32 = v;
    492 }
    493 
    494 static INLINE void make_f64_val(struct val *val, double v)
    495 {
    496 	val->type = val_f64;
    497 	val->num.f64 = v;
    498 }
    499 
    500 static INLINE void make_f32_val(struct val *val, float v)
    501 {
    502 	val->type = val_f32;
    503 	val->num.f32 = v;
    504 }
    505 
    506 static INLINE int stack_pushval(struct wasm_interp *interp, struct val *val)
    507 {
    508 	return cursor_pushval(&interp->stack, val);
    509 }
    510 
    511 static int interp_exit(struct wasm_interp *interp)
    512 {
    513 	struct val *vals = NULL;
    514 	if (!get_params(interp, &vals, 1))
    515 		return interp_error(interp, "exit param missing?");
    516 	interp->quitting = 1;
    517 	stack_push_i32(interp, vals[0].num.i32);
    518 	return 0;
    519 }
    520 
    521 static int wasi_proc_exit(struct wasm_interp *interp)
    522 {
    523 	return interp_exit(interp);
    524 }
    525 
    526 static int wasi_abort(struct wasm_interp *interp)
    527 {
    528 	struct val *params = NULL;
    529 
    530 	if (!get_params(interp, &params, 4))
    531 		return interp_error(interp, "exit param missing?");
    532 
    533 	printf("abort\n");
    534 
    535 	interp->quitting = 1;
    536 	stack_push_i32(interp, 88);
    537 
    538 	return 0;
    539 }
    540 
    541 static INLINE const char *get_function_name(struct module *module, int fn)
    542 {
    543 	struct func *func = NULL;
    544 	if (unlikely(!(func = get_fn(module, fn)))) {
    545 		return "unknown";
    546 	}
    547 	return func->name;
    548 }
    549 
    550 static int wasi_args_sizes_get(struct wasm_interp *interp);
    551 static int wasi_args_get(struct wasm_interp *interp);
    552 static int wasi_fd_write(struct wasm_interp *interp);
    553 static int wasi_fd_close(struct wasm_interp *interp);
    554 static int wasi_environ_sizes_get(struct wasm_interp *interp);
    555 static int wasi_environ_get(struct wasm_interp *interp);
    556 
    557 static struct builtin BUILTINS[] = {
    558 	{ .name = "null",              .fn = NULL }, // for reasons
    559 	{ .name = "args_get",          .fn = wasi_args_get },
    560 	{ .name = "fd_write",          .fn = wasi_fd_write },
    561 	{ .name = "fd_close",          .fn = wasi_fd_close },
    562 	{ .name = "environ_sizes_get", .fn = wasi_environ_sizes_get },
    563 	{ .name = "environ_get",       .fn = wasi_environ_get },
    564 	{ .name = "args_sizes_get",    .fn = wasi_args_sizes_get },
    565 	{ .name = "proc_exit",         .fn = wasi_proc_exit  },
    566 	{ .name = "abort",             .fn = wasi_abort  },
    567 };
    568 
    569 static const int NUM_BUILTINS = sizeof(BUILTINS) / sizeof(*BUILTINS);
    570 
    571 static int parse_instr(struct expr_parser *parser, u8 tag, struct instr *op);
    572 
    573 static INLINE int is_valtype(unsigned char byte)
    574 {
    575 	switch ((enum valtype)byte) {
    576 		case val_i32: // i32
    577 		case val_i64: // i64
    578 		case val_f32: // f32
    579 		case val_f64: // f64
    580 		case val_ref_func: // funcref
    581 		case val_ref_null: // null
    582 		case val_ref_extern: // externref
    583 			return 1;
    584 	}
    585 
    586 	return 0;
    587 }
    588 
    589 
    590 /*
    591 static int sizeof_valtype(enum valtype valtype)
    592 {
    593 	switch (valtype) {
    594 	case i32: return 4;
    595 	case f32: return 4;
    596 	case i64: return 8;
    597 	case f64: return 8;
    598 	}
    599 
    600 	return 0;
    601 }
    602 */
    603 
    604 static char *instr_name(enum instr_tag tag)
    605 {
    606 	static char unk[6] = {0};
    607 
    608 	switch (tag) {
    609 		case i_unreachable: return "unreachable";
    610 		case i_nop: return "nop";
    611 		case i_block: return "block";
    612 		case i_loop: return "loop";
    613 		case i_if: return "if";
    614 		case i_else: return "else";
    615 		case i_end: return "end";
    616 		case i_br: return "br";
    617 		case i_br_if: return "br_if";
    618 		case i_br_table: return "br_table";
    619 		case i_return: return "return";
    620 		case i_call: return "call";
    621 		case i_call_indirect: return "call_indirect";
    622 		case i_drop: return "drop";
    623 		case i_select: return "select";
    624 		case i_local_get: return "local_get";
    625 		case i_local_set: return "local_set";
    626 		case i_local_tee: return "local_tee";
    627 		case i_global_get: return "global_get";
    628 		case i_global_set: return "global_set";
    629 		case i_i32_load: return "i32_load";
    630 		case i_i64_load: return "i64_load";
    631 		case i_f32_load: return "f32_load";
    632 		case i_f64_load: return "f64_load";
    633 		case i_i32_load8_s: return "i32_load8_s";
    634 		case i_i32_load8_u: return "i32_load8_u";
    635 		case i_i32_load16_s: return "i32_load16_s";
    636 		case i_i32_load16_u: return "i32_load16_u";
    637 		case i_i64_load8_s: return "i64_load8_s";
    638 		case i_i64_load8_u: return "i64_load8_u";
    639 		case i_i64_load16_s: return "i64_load16_s";
    640 		case i_i64_load16_u: return "i64_load16_u";
    641 		case i_i64_load32_s: return "i64_load32_s";
    642 		case i_i64_load32_u: return "i64_load32_u";
    643 		case i_i32_store: return "i32_store";
    644 		case i_i64_store: return "i64_store";
    645 		case i_f32_store: return "f32_store";
    646 		case i_f64_store: return "f64_store";
    647 		case i_i32_store8: return "i32_store8";
    648 		case i_i32_store16: return "i32_store16";
    649 		case i_i64_store8: return "i64_store8";
    650 		case i_i64_store16: return "i64_store16";
    651 		case i_i64_store32: return "i64_store32";
    652 		case i_memory_size: return "memory_size";
    653 		case i_memory_grow: return "memory_grow";
    654 		case i_i32_const: return "i32_const";
    655 		case i_i64_const: return "i64_const";
    656 		case i_f32_const: return "f32_const";
    657 		case i_f64_const: return "f64_const";
    658 		case i_i32_eqz: return "i32_eqz";
    659 		case i_i32_eq: return "i32_eq";
    660 		case i_i32_ne: return "i32_ne";
    661 		case i_i32_lt_s: return "i32_lt_s";
    662 		case i_i32_lt_u: return "i32_lt_u";
    663 		case i_i32_gt_s: return "i32_gt_s";
    664 		case i_i32_gt_u: return "i32_gt_u";
    665 		case i_i32_le_s: return "i32_le_s";
    666 		case i_i32_le_u: return "i32_le_u";
    667 		case i_i32_ge_s: return "i32_ge_s";
    668 		case i_i32_ge_u: return "i32_ge_u";
    669 		case i_i64_eqz: return "i64_eqz";
    670 		case i_i64_eq: return "i64_eq";
    671 		case i_i64_ne: return "i64_ne";
    672 		case i_i64_lt_s: return "i64_lt_s";
    673 		case i_i64_lt_u: return "i64_lt_u";
    674 		case i_i64_gt_s: return "i64_gt_s";
    675 		case i_i64_gt_u: return "i64_gt_u";
    676 		case i_i64_le_s: return "i64_le_s";
    677 		case i_i64_le_u: return "i64_le_u";
    678 		case i_i64_ge_s: return "i64_ge_s";
    679 		case i_i64_ge_u: return "i64_ge_u";
    680 		case i_f32_eq: return "f32_eq";
    681 		case i_f32_ne: return "f32_ne";
    682 		case i_f32_lt: return "f32_lt";
    683 		case i_f32_gt: return "f32_gt";
    684 		case i_f32_le: return "f32_le";
    685 		case i_f32_ge: return "f32_ge";
    686 		case i_f64_eq: return "f64_eq";
    687 		case i_f64_ne: return "f64_ne";
    688 		case i_f64_lt: return "f64_lt";
    689 		case i_f64_gt: return "f64_gt";
    690 		case i_f64_le: return "f64_le";
    691 		case i_f64_ge: return "f64_ge";
    692 		case i_i32_clz: return "i32_clz";
    693 		case i_i32_ctz: return "i32_ctz";
    694 		case i_i32_popcnt: return "i32_popcnt";
    695 		case i_i32_add: return "i32_add";
    696 		case i_i32_sub: return "i32_sub";
    697 		case i_i32_mul: return "i32_mul";
    698 		case i_i32_div_s: return "i32_div_s";
    699 		case i_i32_div_u: return "i32_div_u";
    700 		case i_i32_rem_s: return "i32_rem_s";
    701 		case i_i32_rem_u: return "i32_rem_u";
    702 		case i_i32_and: return "i32_and";
    703 		case i_i32_or: return "i32_or";
    704 		case i_i32_xor: return "i32_xor";
    705 		case i_i32_shl: return "i32_shl";
    706 		case i_i32_shr_s: return "i32_shr_s";
    707 		case i_i32_shr_u: return "i32_shr_u";
    708 		case i_i32_rotl: return "i32_rotl";
    709 		case i_i32_rotr: return "i32_rotr";
    710 		case i_i64_clz: return "i64_clz";
    711 		case i_i64_ctz: return "i64_ctz";
    712 		case i_i64_popcnt: return "i64_popcnt";
    713 		case i_i64_add: return "i64_add";
    714 		case i_i64_sub: return "i64_sub";
    715 		case i_i64_mul: return "i64_mul";
    716 		case i_i64_div_s: return "i64_div_s";
    717 		case i_i64_div_u: return "i64_div_u";
    718 		case i_i64_rem_s: return "i64_rem_s";
    719 		case i_i64_rem_u: return "i64_rem_u";
    720 		case i_i64_and: return "i64_and";
    721 		case i_i64_or: return "i64_or";
    722 		case i_i64_xor: return "i64_xor";
    723 		case i_i64_shl: return "i64_shl";
    724 		case i_i64_shr_s: return "i64_shr_s";
    725 		case i_i64_shr_u: return "i64_shr_u";
    726 		case i_i64_rotl: return "i64_rotl";
    727 		case i_i64_rotr: return "i64_rotr";
    728 		case i_f32_abs: return "f32_abs";
    729 		case i_f32_neg: return "f32_neg";
    730 		case i_f32_ceil: return "f32_ceil";
    731 		case i_f32_floor: return "f32_floor";
    732 		case i_f32_trunc: return "f32_trunc";
    733 		case i_f32_nearest: return "f32_nearest";
    734 		case i_f32_sqrt: return "f32_sqrt";
    735 		case i_f32_add: return "f32_add";
    736 		case i_f32_sub: return "f32_sub";
    737 		case i_f32_mul: return "f32_mul";
    738 		case i_f32_div: return "f32_div";
    739 		case i_f32_min: return "f32_min";
    740 		case i_f32_max: return "f32_max";
    741 		case i_f32_copysign: return "f32_copysign";
    742 		case i_f64_abs: return "f64_abs";
    743 		case i_f64_neg: return "f64_neg";
    744 		case i_f64_ceil: return "f64_ceil";
    745 		case i_f64_floor: return "f64_floor";
    746 		case i_f64_trunc: return "f64_trunc";
    747 		case i_f64_nearest: return "f64_nearest";
    748 		case i_f64_sqrt: return "f64_sqrt";
    749 		case i_f64_add: return "f64_add";
    750 		case i_f64_sub: return "f64_sub";
    751 		case i_f64_mul: return "f64_mul";
    752 		case i_f64_div: return "f64_div";
    753 		case i_f64_min: return "f64_min";
    754 		case i_f64_max: return "f64_max";
    755 		case i_f64_copysign: return "f64_copysign";
    756 		case i_i32_wrap_i64: return "i32_wrap_i64";
    757 		case i_i32_trunc_f32_s: return "i32_trunc_f32_s";
    758 		case i_i32_trunc_f32_u: return "i32_trunc_f32_u";
    759 		case i_i32_trunc_f64_s: return "i32_trunc_f64_s";
    760 		case i_i32_trunc_f64_u: return "i32_trunc_f64_u";
    761 		case i_i64_extend_i32_s: return "i64_extend_i32_s";
    762 		case i_i64_extend_i32_u: return "i64_extend_i32_u";
    763 		case i_i64_trunc_f32_s: return "i64_trunc_f32_s";
    764 		case i_i64_trunc_f32_u: return "i64_trunc_f32_u";
    765 		case i_i64_trunc_f64_s: return "i64_trunc_f64_s";
    766 		case i_i64_trunc_f64_u: return "i64_trunc_f64_u";
    767 		case i_f32_convert_i32_s: return "f32_convert_i32_s";
    768 		case i_f32_convert_i32_u: return "f32_convert_i32_u";
    769 		case i_f32_convert_i64_s: return "f32_convert_i64_s";
    770 		case i_f32_convert_i64_u: return "f32_convert_i64_u";
    771 		case i_f32_demote_f64: return "f32_demote_f64";
    772 		case i_f64_convert_i32_s: return "f64_convert_i32_s";
    773 		case i_f64_convert_i32_u: return "f64_convert_i32_u";
    774 		case i_f64_convert_i64_s: return "f64_convert_i64_s";
    775 		case i_f64_convert_i64_u: return "f64_convert_i64_u";
    776 		case i_f64_promote_f32: return "f64_promote_f32";
    777 		case i_i32_reinterpret_f32: return "i32_reinterpret_f32";
    778 		case i_i64_reinterpret_f64: return "i64_reinterpret_f64";
    779 		case i_f32_reinterpret_i32: return "f32_reinterpret_i32";
    780 		case i_f64_reinterpret_i64: return "f64_reinterpret_i64";
    781 		case i_i32_extend8_s: return "i32_extend8_s";
    782 		case i_i32_extend16_s: return "i32_extend16_s";
    783 		case i_i64_extend8_s: return "i64_extend8_s";
    784 		case i_i64_extend16_s: return "i64_extend16_s";
    785 		case i_i64_extend32_s: return "i64_extend32_s";
    786 		case i_ref_null: return "ref_null";
    787 		case i_ref_func: return "ref_func";
    788 		case i_ref_is_null: return "ref_is_null";
    789 		case i_bulk_op: return "bulk_op";
    790 		case i_table_get: return "table_get";
    791 		case i_table_set: return "table_set";
    792 		case i_selects: return "selects";
    793 	}
    794 
    795 	snprintf(unk, sizeof(unk), "0x%02x", tag);
    796 	return unk;
    797 }
    798 
    799 static INLINE int was_section_parsed(struct module *module,
    800 	enum section_tag section)
    801 {
    802 	if (section == section_custom)
    803 		return module->custom_sections > 0;
    804 
    805 	return module->parsed & (1 << section);
    806 }
    807 
    808 static INLINE int was_name_section_parsed(struct module *module,
    809 		enum name_subsection_tag subsection)
    810 {
    811 	if (!was_section_parsed(module, section_name)) {
    812 		return 0;
    813 	}
    814 
    815 	return module->name_section.parsed & (1 << subsection);
    816 }
    817 
    818 //static int callframe_cnt = 0;
    819 
    820 static INLINE int cursor_push_callframe(struct cursor *cur, struct callframe *frame)
    821 {
    822 	//debug("pushing callframe %d fn:%d\n", ++callframe_cnt, frame->fn);
    823 	return cursor_push(cur, (u8*)frame, sizeof(*frame));
    824 }
    825 
    826 static INLINE int count_resolvers(struct wasm_interp *interp)
    827 {
    828 	return cursor_count(&interp->resolver_stack, sizeof(struct resolver));
    829 }
    830 
    831 static INLINE int push_callframe(struct wasm_interp *interp, struct callframe *frame)
    832 {
    833 	u32 offset;
    834 
    835 	offset = count_resolvers(interp);
    836 	/* push label resolver offsets, used to keep track of per-func resolvers */
    837 	/* TODO: maybe move this data to struct func? */
    838 	if (unlikely(!cursor_push_int(&interp->resolver_offsets, offset)))
    839 		return interp_error(interp, "push resolver offset");
    840 
    841 	return cursor_push_callframe(&interp->callframes, frame);
    842 }
    843 
    844 static INLINE int cursor_drop_callframe(struct cursor *cur)
    845 {
    846 	//debug("dropping callframe %d fn:%d\n", callframe_cnt--, top_callframe(cur)->fn);
    847 	return cursor_drop(cur, sizeof(struct callframe));
    848 }
    849 
    850 static INLINE int cursor_dropval(struct cursor *stack)
    851 {
    852 	return cursor_drop(stack, sizeof(struct val));
    853 }
    854 
    855 static INLINE int cursor_popint(struct cursor *cur, int *i)
    856 {
    857 	return cursor_pop(cur, (u8 *)i, sizeof(int));
    858 }
    859 
    860 
    861 void print_error_backtrace(struct errors *errors)
    862 {
    863 	struct cursor errs;
    864 	struct error err;
    865 
    866 	copy_cursor(&errors->cur, &errs);
    867 	errs.p = errs.start;
    868 
    869 	while (errs.p < errors->cur.p) {
    870 		if (!cursor_pull_error(&errs, &err)) {
    871 			printf("backtrace: couldn't pull error\n");
    872 			return;
    873 		}
    874 		printf("%08x:%s\n", err.pos, err.msg);
    875 	}
    876 }
    877 
    878 static void _functype_str(struct functype *ft, struct cursor *buf)
    879 {
    880 	u32 i;
    881 
    882 	cursor_push_str(buf, "(");
    883 
    884 	for (i = 0; i < ft->params.num_valtypes; i++) {
    885 		cursor_push_str(buf, valtype_name(ft->params.valtypes[i]));
    886 
    887 		if (i != ft->params.num_valtypes-1) {
    888 			cursor_push_str(buf, ", ");
    889 		}
    890 	}
    891 
    892 	cursor_push_str(buf, ") -> (");
    893 
    894 	for (i = 0; i < ft->result.num_valtypes; i++) {
    895 		cursor_push_str(buf, valtype_name(ft->result.valtypes[i]));
    896 
    897 		if (i != ft->result.num_valtypes-1) {
    898 			cursor_push_str(buf, ", ");
    899 		}
    900 	}
    901 
    902 	cursor_push_c_str(buf, ")");
    903 }
    904 
    905 static const char *functype_str(struct functype *ft, char *buf, int buflen)
    906 {
    907 	struct cursor cur;
    908 	if (buflen == 0)
    909 		return "";
    910 
    911 	buf[buflen-1] = 0;
    912 	make_cursor((u8*)buf, (u8*)buf + buflen-1, &cur);
    913 
    914 	_functype_str(ft, &cur);
    915 
    916 	return (const char*)buf;
    917 }
    918 
    919 static void print_functype(struct functype *ft)
    920 {
    921 	static char buf[0xFF];
    922 	printf("%s\n", functype_str(ft, buf, sizeof(buf)));
    923 }
    924 
    925 static void print_type_section(struct typesec *typesec)
    926 {
    927 	u32 i;
    928 	printf("%d functypes:\n", typesec->num_functypes);
    929 	for (i = 0; i < typesec->num_functypes; i++) {
    930 		printf("    ");
    931 		print_functype(&typesec->functypes[i]);
    932 	}
    933 }
    934 
    935 static void print_func_section(struct funcsec *funcsec)
    936 {
    937 	printf("%d functions\n", funcsec->num_indices);
    938 	/*
    939 	printf("    ");
    940 	for (i = 0; i < funcsec->num_indices; i++) {
    941 		printf("%d ", funcsec->type_indices[i]);
    942 	}
    943 	printf("\n");
    944 	*/
    945 }
    946 
    947 __attribute__((unused))
    948 static const char *exportdesc_name(enum exportdesc desc)
    949 {
    950 	switch (desc) {
    951 		case export_func: return "function";
    952 		case export_table: return "table";
    953 		case export_mem: return "memory";
    954 		case export_global: return "global";
    955 	}
    956 
    957 	return "unknown";
    958 }
    959 
    960 static void print_import(struct import *import)
    961 {
    962 	(void)import;
    963 	printf("%s %s\n", import->module_name, import->name);
    964 }
    965 
    966 static void print_import_section(struct importsec *importsec)
    967 {
    968 	u32 i;
    969 	printf("%d imports:\n", importsec->num_imports);
    970 	for (i = 0; i < importsec->num_imports; i++) {
    971 		printf("    ");
    972 		print_import(&importsec->imports[i]);
    973 	}
    974 }
    975 
    976 static void print_limits(struct limits *limits)
    977 {
    978 	switch (limits->type) {
    979 	case limit_min:
    980 		printf("%d", limits->min);
    981 		break;
    982 	case limit_min_max:
    983 		printf("%d-%d", limits->min, limits->max);
    984 		break;
    985 	}
    986 }
    987 
    988 static void print_memory_section(struct memsec *memory)
    989 {
    990 	u32 i;
    991 	struct limits *mem;
    992 
    993 	printf("%d memory:\n", memory->num_mems);
    994 	for (i = 0; i < memory->num_mems; i++) {
    995 		mem = &memory->mems[i];
    996 		printf("    ");
    997 		print_limits(mem);
    998 		printf("\n");
    999 	}
   1000 }
   1001 
   1002 static void print_table_section(struct tablesec *section)
   1003 {
   1004 	u32 i;
   1005 	struct table *table;
   1006 
   1007 	printf("%d tables:\n", section->num_tables);
   1008 	for (i = 0; i < section->num_tables; i++) {
   1009 		table = &section->tables[i];
   1010 		printf("    ");
   1011 		printf("%s: ", reftype_name(table->reftype));
   1012 		print_limits(&table->limits);
   1013 		printf("\n");
   1014 	}
   1015 }
   1016 
   1017 static int count_imports(struct module *module, enum import_type *typ)
   1018 {
   1019 	u32 i, count = 0;
   1020 	struct import *import;
   1021 	struct importsec *imports;
   1022 
   1023 	if (!was_section_parsed(module, section_import))
   1024 		return 0;
   1025 
   1026 	imports = &module->import_section;
   1027 
   1028 	if (typ == NULL)
   1029 		return imports->num_imports;
   1030 
   1031 	for (i = 0; i < imports->num_imports; i++) {
   1032 		import = &imports->imports[i];
   1033 		if (import->desc.type == *typ) {
   1034 			count++;
   1035 		}
   1036 	}
   1037 
   1038 	return count;
   1039 }
   1040 
   1041 static INLINE int count_imported_functions(struct module *module)
   1042 {
   1043 	enum import_type typ = import_func;
   1044 	return count_imports(module, &typ);
   1045 }
   1046 
   1047 static void print_element_section(struct elemsec *section)
   1048 {
   1049 	printf("%d elements\n", section->num_elements);
   1050 }
   1051 
   1052 static void print_start_section(struct module *module)
   1053 {
   1054 	u32 fn = module->start_section.start_fn;
   1055 	printf("start function: %d <%s>\n", fn, get_function_name(module, fn));
   1056 }
   1057 
   1058 static void print_export_section(struct exportsec *exportsec)
   1059 {
   1060 	u32 i;
   1061 	printf("%d exports:\n", exportsec->num_exports);
   1062 	for (i = 0; i < exportsec->num_exports; i++) {
   1063 		printf("    ");
   1064 		printf("%s %s %d\n", exportdesc_name(exportsec->exports[i].desc),
   1065 				exportsec->exports[i].name,
   1066 				exportsec->exports[i].index);
   1067 	}
   1068 }
   1069 
   1070 /*
   1071 static void print_local(struct local *local)
   1072 {
   1073 	debug("%d %s\n", local->n, valtype_name(local->valtype));
   1074 }
   1075 
   1076 static void print_func(struct wasm_func *func)
   1077 {
   1078 	int i;
   1079 
   1080 	debug("func locals (%d): \n", func->num_locals);
   1081 	for (i = 0; i < func->num_locals; i++) {
   1082 		print_local(&func->locals[i]);
   1083 	}
   1084 	debug("%d bytes of code\n", func->code_len);
   1085 }
   1086 */
   1087 
   1088 static void print_global_section(struct globalsec *section)
   1089 {
   1090 	printf("%d globals\n", section->num_globals);
   1091 }
   1092 
   1093 
   1094 static void print_code_section(struct codesec *codesec)
   1095 {
   1096 	printf("%d code segments\n", codesec->num_funcs);
   1097 	/*
   1098 	for (i = 0; i < codesec->num_funcs; i++) {
   1099 		print_func(&codesec->funcs[i]);
   1100 	}
   1101 	*/
   1102 }
   1103 
   1104 static void print_data_section(struct datasec *section)
   1105 {
   1106 	printf("%d data segments\n", section->num_datas);
   1107 }
   1108 
   1109 static void print_custom_section(struct customsec *section)
   1110 {
   1111 	printf("custom (%s) %d bytes\n", section->name, section->data_len);
   1112 }
   1113 
   1114 static void print_section(struct module *module, enum section_tag section)
   1115 {
   1116 	u32 i;
   1117 
   1118 	switch (section) {
   1119 	case section_custom:
   1120 		for (i = 0; i < module->custom_sections; i++) {
   1121 			print_custom_section(&module->custom_section[i]);
   1122 		}
   1123 		break;
   1124 	case section_type:
   1125 		print_type_section(&module->type_section);
   1126 		break;
   1127 	case section_import:
   1128 		print_import_section(&module->import_section);
   1129 		break;
   1130 	case section_function:
   1131 		print_func_section(&module->func_section);
   1132 		break;
   1133 	case section_table:
   1134 		print_table_section(&module->table_section);
   1135 		break;
   1136 	case section_memory:
   1137 		print_memory_section(&module->memory_section);
   1138 		break;
   1139 	case section_global:
   1140 		print_global_section(&module->global_section);
   1141 		break;
   1142 	case section_export:
   1143 		print_export_section(&module->export_section);
   1144 		break;
   1145 	case section_start:
   1146 		print_start_section(module);
   1147 		break;
   1148 	case section_element:
   1149 		print_element_section(&module->element_section);
   1150 		break;
   1151 	case section_code:
   1152 		print_code_section(&module->code_section);
   1153 		break;
   1154 	case section_data:
   1155 		print_data_section(&module->data_section);
   1156 		break;
   1157 	case section_data_count:
   1158 		printf("data count %d\n", module->data_section.num_datas);
   1159 		break;
   1160 	case section_name:
   1161 		printf("todo: print name section\n");
   1162 		break;
   1163 	case num_sections:
   1164 		assert(0);
   1165 		break;
   1166 	}
   1167 }
   1168 
   1169 static void print_module(struct module *module)
   1170 {
   1171 	u32 i;
   1172 	enum section_tag section;
   1173 
   1174 	for (i = 0; i < num_sections; i++) {
   1175 		section = (enum section_tag)i;
   1176 		if (was_section_parsed(module, section)) {
   1177 			print_section(module, section);
   1178 		}
   1179 	}
   1180 }
   1181 
   1182 
   1183 static int leb128_write(struct cursor *write, unsigned int value)
   1184 {
   1185 	unsigned char byte;
   1186 	while (1) {
   1187 		byte = value & 0x7F;
   1188 		value >>= 7;
   1189 		if (value == 0) {
   1190 			if (!cursor_push_byte(write, byte))
   1191 				return 0;
   1192 			return 1;
   1193 		} else {
   1194 			if (!cursor_push_byte(write, byte | 0x80))
   1195 				return 0;
   1196 		}
   1197 	}
   1198 }
   1199 
   1200 #define BYTE_AT(type, i, shift) (((type)(p[i]) & 0x7f) << (shift))
   1201 #define LEB128_1(type) (BYTE_AT(type, 0, 0))
   1202 #define LEB128_2(type) (BYTE_AT(type, 1, 7) | LEB128_1(type))
   1203 #define LEB128_3(type) (BYTE_AT(type, 2, 14) | LEB128_2(type))
   1204 #define LEB128_4(type) (BYTE_AT(type, 3, 21) | LEB128_3(type))
   1205 #define LEB128_5(type) (BYTE_AT(type, 4, 28) | LEB128_4(type))
   1206 
   1207 static inline int shiftmask32(u32 val)
   1208 {
   1209 	return val & 31;
   1210 }
   1211 
   1212 static inline int shiftmask64(u64 val)
   1213 {
   1214 	return val & 63;
   1215 }
   1216 
   1217 
   1218 static INLINE int parse_i64(struct cursor *read, uint64_t *val)
   1219 {
   1220 	u8 shift;
   1221 	u8 byte;
   1222 
   1223 	*val = 0;
   1224 	shift = 0;
   1225 
   1226 	do {
   1227 		if (!pull_byte(read, &byte))
   1228 			return 0;
   1229 		*val |= (byte & 0x7FULL) << shift;
   1230 		shift += 7;
   1231 	} while ((byte & 0x80) != 0);
   1232 
   1233 	/* sign bit of byte is second high-order bit (0x40) */
   1234 	if ((shift < 64) && (byte & 0x40))
   1235 		*val |= (0xFFFFFFFFFFFFFFFF << shift);
   1236 
   1237 	return 1;
   1238 }
   1239 
   1240 static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
   1241 {
   1242 	unsigned int shift = 0;
   1243 	u8 byte;
   1244 	*val = 0;
   1245 
   1246 	for (;;) {
   1247 		if (!pull_byte(read, &byte))
   1248 			return 0;
   1249 
   1250 		*val |= (0x7F & byte) << shift;
   1251 
   1252 		if ((0x80 & byte) == 0)
   1253 			break;
   1254 
   1255 		shift += 7;
   1256 	}
   1257 
   1258 	return 1;
   1259 }
   1260 
   1261 static INLINE int sleb128_read(struct cursor *read, signed int *val)
   1262 {
   1263 	int shift;
   1264 	u8 byte;
   1265 
   1266 	*val = 0;
   1267 	shift = 0;
   1268 
   1269 	do {
   1270 		if (!pull_byte(read, &byte))
   1271 			return 0;
   1272 		*val |= ((byte & 0x7F) << shift);
   1273 		shift += 7;
   1274 	} while ((byte & 0x80) != 0);
   1275 
   1276 	/* sign bit of byte is second high-order bit (0x40) */
   1277 	if ((shift < 32) && (byte & 0x40))
   1278 		*val |= (0xFFFFFFFF << shift);
   1279 
   1280 	return 1;
   1281 }
   1282 
   1283 /*
   1284 static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
   1285 {
   1286 	unsigned char p[6] = {0};
   1287 	*val = 0;
   1288 
   1289 	if (pull_byte(read, &p[0]) && (p[0] & 0x80) == 0) {
   1290 		*val = LEB128_1(unsigned int);
   1291 		if (p[0] == 0x7F)
   1292 			assert((int)*val == -1);
   1293 		return 1;
   1294 	} else if (pull_byte(read, &p[1]) && (p[1] & 0x80) == 0) {
   1295 		*val = LEB128_2(unsigned int);
   1296 		return 2;
   1297 	} else if (pull_byte(read, &p[2]) && (p[2] & 0x80) == 0) {
   1298 		*val = LEB128_3(unsigned int);
   1299 		return 3;
   1300 	} else if (pull_byte(read, &p[3]) && (p[3] & 0x80) == 0) {
   1301 		*val = LEB128_4(unsigned int);
   1302 		return 4;
   1303 	} else if (pull_byte(read, &p[4]) && (p[4] & 0x80) == 0) {
   1304 		if (!(p[4] & 0xF0)) {
   1305 			*val = LEB128_5(unsigned int);
   1306 			return 5;
   1307 		}
   1308 		//printf("%02X & 0xF0\n", p[4] & 0xF0);
   1309 	}
   1310 
   1311 	return 0;
   1312 }
   1313 */
   1314 
   1315 static INLINE int parse_int(struct cursor *read, int *val)
   1316 {
   1317 	return sleb128_read(read, val);
   1318 }
   1319 
   1320 
   1321 static INLINE int parse_u32(struct cursor *read, u32 *val)
   1322 {
   1323 	return uleb128_read(read, val);
   1324 }
   1325 
   1326 static INLINE int read_f32(struct cursor *read, float *val)
   1327 {
   1328 	return cursor_pull(read, (u8*)val, 4);
   1329 }
   1330 
   1331 static INLINE int read_f64(struct cursor *read, double *val)
   1332 {
   1333 	return cursor_pull(read, (u8*)val, 8);
   1334 }
   1335 
   1336 static int parse_section_tag(struct cursor *cur, enum section_tag *section)
   1337 {
   1338 	unsigned char byte;
   1339 	unsigned char *start;
   1340 	assert(section);
   1341 
   1342 	start = cur->p;
   1343 
   1344 	if (!pull_byte(cur, &byte)) {
   1345 		return 0;
   1346 	}
   1347 
   1348 	if (byte >= num_sections) {
   1349 		cur->p = start;
   1350 		return 0;
   1351 	}
   1352 
   1353 	*section = (enum section_tag)byte;
   1354 	return 1;
   1355 }
   1356 
   1357 static int parse_valtype(struct wasm_parser *p, enum valtype *valtype)
   1358 {
   1359 	unsigned char *start;
   1360 
   1361 	start = p->cur.p;
   1362 
   1363 	if (unlikely(!pull_byte(&p->cur, (unsigned char*)valtype))) {
   1364 		return parse_err(p, "valtype tag oob");
   1365 	}
   1366 
   1367 	if (unlikely(!is_valtype((unsigned char)*valtype))) {
   1368 		cursor_print_around(&p->cur, 10);
   1369 		p->cur.p = start;
   1370 		return parse_err(p, "0x%02x is not a valid valtype tag", *valtype);
   1371 	}
   1372 
   1373 	return 1;
   1374 }
   1375 
   1376 static int parse_result_type(struct wasm_parser *p, struct resulttype *rt)
   1377 {
   1378 	u32 i, elems;
   1379 	enum valtype valtype;
   1380 	unsigned char *start;
   1381 
   1382 	rt->num_valtypes = 0;
   1383 	rt->valtypes = 0;
   1384 	start = p->mem.p;
   1385 
   1386 	if (unlikely(!parse_u32(&p->cur, &elems))) {
   1387 		parse_err(p, "vec len");
   1388 		return 0;
   1389 	}
   1390 
   1391 	for (i = 0; i < elems; i++)
   1392 	{
   1393 		if (unlikely(!parse_valtype(p, &valtype))) {
   1394 			parse_err(p, "valtype #%d", i);
   1395 			p->mem.p = start;
   1396 			return 0;
   1397 		}
   1398 
   1399 		if (unlikely(!cursor_push_byte(&p->mem, (unsigned char)valtype))) {
   1400 			parse_err(p, "valtype push data OOM #%d", i);
   1401 			p->mem.p = start;
   1402 			return 0;
   1403 		}
   1404 	}
   1405 
   1406 	rt->num_valtypes = elems;
   1407 	rt->valtypes = start;
   1408 
   1409 	return 1;
   1410 }
   1411 
   1412 
   1413 static int parse_func_type(struct wasm_parser *p, struct functype *func)
   1414 {
   1415 	if (unlikely(!consume_byte(&p->cur, FUNC_TYPE_TAG))) {
   1416 		parse_err(p, "type tag");
   1417 		return 0;
   1418 	}
   1419 
   1420 	if (unlikely(!parse_result_type(p, &func->params))) {
   1421 		parse_err(p, "params");
   1422 		return 0;
   1423 	}
   1424 
   1425 	if (unlikely(!parse_result_type(p, &func->result))) {
   1426 		parse_err(p, "result");
   1427 		return 0;
   1428 	}
   1429 
   1430 	return 1;
   1431 }
   1432 
   1433 static int parse_name(struct wasm_parser *p, const char **name)
   1434 {
   1435 	u32 bytes;
   1436 	if (unlikely(!parse_u32(&p->cur, &bytes))) {
   1437 		parse_err(p, "name len");
   1438 		return 0;
   1439 	}
   1440 
   1441 	if (unlikely(!pull_data_into_cursor(&p->cur, &p->mem, (unsigned char**)name,
   1442 				bytes))) {
   1443 		parse_err(p, "name string");
   1444 		return 0;
   1445 	}
   1446 
   1447 	if (unlikely(!cursor_push_byte(&p->mem, 0))) {
   1448 		parse_err(p, "name null byte");
   1449 		return 0;
   1450 	}
   1451 
   1452 	return 1;
   1453 }
   1454 
   1455 static INLINE int is_valid_name_subsection(u8 tag)
   1456 {
   1457 	return tag < num_name_subsections;
   1458 }
   1459 
   1460 static int parse_export_desc(struct wasm_parser *p, enum exportdesc *desc)
   1461 {
   1462 	unsigned char byte;
   1463 
   1464 	if (!pull_byte(&p->cur, &byte)) {
   1465 		parse_err(p, "export desc byte eof");
   1466 		return 0;
   1467 	}
   1468 
   1469 	switch((enum exportdesc)byte) {
   1470 	case export_func:
   1471 	case export_table:
   1472 	case export_mem:
   1473 	case export_global:
   1474 		*desc = (enum exportdesc)byte;
   1475 		return 1;
   1476 	}
   1477 
   1478 	parse_err(p, "invalid tag: %x", byte);
   1479 	return 0;
   1480 }
   1481 
   1482 static int parse_export(struct wasm_parser *p, struct wexport *export)
   1483 {
   1484 	if (!parse_name(p, &export->name)) {
   1485 		parse_err(p, "export name");
   1486 		return 0;
   1487 	}
   1488 
   1489 	if (!parse_export_desc(p, &export->desc)) {
   1490 		parse_err(p, "export desc");
   1491 		return 0;
   1492 	}
   1493 
   1494 	if (!parse_u32(&p->cur, &export->index)) {
   1495 		parse_err(p, "export index");
   1496 		return 0;
   1497 	}
   1498 
   1499 	return 1;
   1500 }
   1501 
   1502 static int parse_local_def(struct wasm_parser *p, struct local_def *def)
   1503 {
   1504 	if (unlikely(!parse_u32(&p->cur, &def->num_types))) {
   1505 		debug("fail parse local def\n");
   1506 		return parse_err(p, "n");
   1507 	}
   1508 
   1509 	if (unlikely(!parse_valtype(p, &def->type))) {
   1510 		debug("fail parse valtype\n");
   1511 		return parse_err(p, "valtype");
   1512 	}
   1513 
   1514 	return 1;
   1515 }
   1516 
   1517 static int parse_vector(struct wasm_parser *p, int item_size,
   1518 			u32 *elems, void **items)
   1519 {
   1520 	if (!parse_u32(&p->cur, elems)) {
   1521 		return parse_err(p, "len");
   1522 	}
   1523 
   1524 	*items = cursor_alloc(&p->mem, *elems * item_size);
   1525 
   1526 	if (*items == NULL) {
   1527 		parse_err(p, "vector alloc oom");
   1528 		return 0;
   1529 	}
   1530 
   1531 	return 1;
   1532 }
   1533 
   1534 static int parse_nameassoc(struct wasm_parser *p, struct nameassoc *assoc)
   1535 {
   1536 	if (!parse_u32(&p->cur, &assoc->index))
   1537 		return parse_err(p, "index");
   1538 
   1539 	if (!parse_name(p, &assoc->name))
   1540 		return parse_err(p, "name");
   1541 
   1542 	//debug("parsed nameassoc %d %s\n", assoc->index, assoc->name);
   1543 
   1544 	return 1;
   1545 }
   1546 
   1547 static int parse_namemap(struct wasm_parser *p, struct namemap *map)
   1548 {
   1549 	u32 i;
   1550 
   1551 	if (!parse_vector(p, sizeof(struct nameassoc), &map->num_names,
   1552 			  (void**)&map->names)) {
   1553 		return parse_err(p, "parse funcmap vec");
   1554 	}
   1555 
   1556 	for (i = 0; i < map->num_names; i++) {
   1557 		if (!parse_nameassoc(p, &map->names[i])) {
   1558 			return parse_err(p, "name assoc %d/%d", i+1,
   1559 					 map->num_names);
   1560 		}
   1561 	}
   1562 
   1563 	return 1;
   1564 }
   1565 
   1566 static int parse_name_subsection(struct wasm_parser *p, struct namesec *sec, u32 *size)
   1567 {
   1568 	u8 tag;
   1569 	u8 *start = p->cur.p;
   1570 
   1571 	if (!pull_byte(&p->cur, &tag))
   1572 		return parse_err(p, "name subsection tag oob?");
   1573 
   1574 	if (!is_valid_name_subsection(tag))
   1575 		return parse_err(p, "invalid subsection tag 0x%02x", tag);
   1576 
   1577 	if (!parse_u32(&p->cur, size))
   1578 		return parse_err(p, "subsection size");
   1579 
   1580 	// include tag and size in size
   1581 	*size += p->cur.p - start;
   1582 
   1583 	switch((enum name_subsection_tag)tag) {
   1584 	case name_subsection_module:
   1585 		if (!parse_name(p, &sec->module_name))
   1586 			return parse_err(p, "parse module name");
   1587 		sec->parsed |= 1 << name_subsection_module;
   1588 		return 1;
   1589 
   1590 	case name_subsection_funcs:
   1591 		if (!parse_namemap(p, &sec->func_names))
   1592 			return parse_err(p, "func namemap");
   1593 		sec->parsed |= 1 << name_subsection_funcs;
   1594 		return 1;
   1595 
   1596 	case name_subsection_locals:
   1597 		debug("TODO: parse local name subsection\n");
   1598 		return 1;
   1599 
   1600 	case num_name_subsections:
   1601 		return parse_err(p, "impossibru");
   1602 	}
   1603 
   1604 	return parse_err(p, "unknown name subsection: 0x%02x", tag);
   1605 
   1606 }
   1607 
   1608 static int parse_name_section(struct wasm_parser *p, struct namesec *sec,
   1609 		struct customsec *customsec)
   1610 {
   1611 	int i;
   1612 	u32 size, subsection_size;
   1613 
   1614 	subsection_size = 0;
   1615 	size = 0;
   1616 	i = 0;
   1617 
   1618 	for (; i < 3; i++) {
   1619 		if (size == customsec->data_len) {
   1620 			break;
   1621 		} else if (size > customsec->data_len) {
   1622 			return parse_err(p, "parse_name_section did not parse"
   1623 				"the correct number of bytes. It parsed %d bytes"
   1624 				" but %d was expected.",
   1625 				size, customsec->data_len);
   1626 		}
   1627 
   1628 		if (!parse_name_subsection(p, sec, &subsection_size))
   1629 			return parse_err(p, "name subsection %d", i);
   1630 
   1631 		size += subsection_size;
   1632 	}
   1633 
   1634 	p->module.parsed |= (1 << section_name);
   1635 
   1636 	return 1;
   1637 }
   1638 
   1639 
   1640 static int parse_func(struct wasm_parser *p, struct wasm_func *func)
   1641 {
   1642 	struct local_def *defs;
   1643 	u32 i, size;
   1644 	u8 *start;
   1645 
   1646 	if (!parse_u32(&p->cur, &size)) {
   1647 		return parse_err(p, "code size");
   1648 	}
   1649 
   1650 	start = p->cur.p;
   1651 	defs = (struct local_def*)p->mem.p;
   1652 
   1653 	if (!parse_u32(&p->cur, &func->num_local_defs))
   1654 		return parse_err(p, "read locals vec");
   1655 
   1656 	if (!cursor_alloc(&p->mem, sizeof(*defs) * func->num_local_defs))
   1657 		return parse_err(p, "oom alloc param locals");
   1658 
   1659 	if (p->cur.p > p->cur.end)
   1660 		return parse_err(p, "corrupt functype?");
   1661 
   1662 	for (i = 0; i < func->num_local_defs; i++) {
   1663 		if (!parse_local_def(p, &defs[i])) {
   1664 			return parse_err(p, "local #%d", i);
   1665 		}
   1666 	}
   1667 
   1668 	func->local_defs = defs;
   1669 	func->code.code_len = size - (p->cur.p - start);
   1670 
   1671 	if (!pull_data_into_cursor(&p->cur, &p->mem, &func->code.code,
   1672 				func->code.code_len)) {
   1673 		return parse_err(p, "code oom");
   1674 	}
   1675 
   1676 	if (!(func->code.code[func->code.code_len-1] == i_end)) {
   1677 		return parse_err(p, "no end tag (corruption?)");
   1678 	}
   1679 
   1680 	return 1;
   1681 }
   1682 
   1683 static INLINE int count_internal_functions(struct module *module)
   1684 {
   1685 	return !was_section_parsed(module, section_code) ? 0 :
   1686 		module->code_section.num_funcs;
   1687 }
   1688 
   1689 
   1690 static int parse_code_section(struct wasm_parser *p,
   1691 		struct codesec *code_section)
   1692 {
   1693 	struct wasm_func *funcs;
   1694 	u32 i;
   1695 
   1696 	if (!parse_vector(p, sizeof(*funcs), &code_section->num_funcs,
   1697 			  (void**)&funcs)) {
   1698 		return parse_err(p, "funcs");
   1699 	}
   1700 
   1701 	for (i = 0; i < code_section->num_funcs; i++) {
   1702 		if (!parse_func(p, &funcs[i])) {
   1703 			return parse_err(p, "func #%d", i);
   1704 		}
   1705 	}
   1706 
   1707 	code_section->funcs = funcs;
   1708 
   1709 	return 1;
   1710 }
   1711 
   1712 static int is_valid_reftype(unsigned char reftype)
   1713 {
   1714 	switch ((enum reftype)reftype) {
   1715 		case funcref: return 1;
   1716 		case externref: return 1;
   1717 	}
   1718 	return 0;
   1719 }
   1720 
   1721 static int parse_reftype(struct wasm_parser *p, enum reftype *reftype)
   1722 {
   1723 	u8 tag;
   1724 
   1725 	if (!pull_byte(&p->cur, &tag)) {
   1726 		parse_err(p, "reftype");
   1727 		return 0;
   1728 	}
   1729 
   1730 	if (!is_valid_reftype(tag)) {
   1731 		cursor_print_around(&p->cur, 10);
   1732 		parse_err(p, "invalid reftype: 0x%02x", tag);
   1733 		return 0;
   1734 	}
   1735 
   1736 	*reftype = (enum reftype)tag;
   1737 
   1738 	return 1;
   1739 }
   1740 
   1741 
   1742 static int parse_export_section(struct wasm_parser *p,
   1743 		struct exportsec *export_section)
   1744 {
   1745 	struct wexport *exports;
   1746 	u32 elems, i;
   1747 
   1748 	if (!parse_vector(p, sizeof(*exports), &elems, (void**)&exports)) {
   1749 		parse_err(p, "vector");
   1750 		return 0;
   1751 	}
   1752 
   1753 	for (i = 0; i < elems; i++) {
   1754 		if (!parse_export(p, &exports[i])) {
   1755 			parse_err(p, "export #%d", i);
   1756 			return 0;
   1757 		}
   1758 	}
   1759 
   1760 	export_section->num_exports = elems;
   1761 	export_section->exports = exports;
   1762 
   1763 	return 1;
   1764 }
   1765 
   1766 static int parse_limits(struct wasm_parser *p, struct limits *limits)
   1767 {
   1768 	unsigned char tag;
   1769 	if (!pull_byte(&p->cur, &tag)) {
   1770 		return parse_err(p, "oob");
   1771 	}
   1772 
   1773 	if (tag != limit_min && tag != limit_min_max) {
   1774 		return parse_err(p, "invalid tag %02x", tag);
   1775 	}
   1776 
   1777 	if (!parse_u32(&p->cur, &limits->min)) {
   1778 		return parse_err(p, "min");
   1779 	}
   1780 
   1781 	if (tag == limit_min)
   1782 		return 1;
   1783 
   1784 	if (!parse_u32(&p->cur, &limits->max)) {
   1785 		return parse_err(p, "max");
   1786 	}
   1787 
   1788 	return 1;
   1789 }
   1790 
   1791 static int parse_table(struct wasm_parser *p, struct table *table)
   1792 {
   1793 	if (!parse_reftype(p, &table->reftype)) {
   1794 		return parse_err(p, "reftype");
   1795 	}
   1796 
   1797 	if (!parse_limits(p, &table->limits)) {
   1798 		return parse_err(p, "limits");
   1799 	}
   1800 
   1801 	return 1;
   1802 }
   1803 
   1804 static int parse_mut(struct wasm_parser *p, enum mut *mut)
   1805 {
   1806 	if (consume_byte(&p->cur, mut_const)) {
   1807 		*mut = mut_const;
   1808 		return 1;
   1809 	}
   1810 
   1811 	if (consume_byte(&p->cur, mut_var)) {
   1812 		*mut = mut_var;
   1813 		return 1;
   1814 	}
   1815 
   1816 	return parse_err(p, "unknown mut %02x", *p->cur.p);
   1817 }
   1818 
   1819 static int parse_globaltype(struct wasm_parser *p, struct globaltype *g)
   1820 {
   1821 	if (!parse_valtype(p, &g->valtype)) {
   1822 		return parse_err(p, "valtype");
   1823 	}
   1824 
   1825 	return parse_mut(p, &g->mut);
   1826 }
   1827 
   1828 static INLINE void make_expr_parser(struct errors *errs, struct cursor *code,
   1829 		struct expr_parser *p)
   1830 {
   1831 	p->interp = NULL;
   1832 	p->code = code;
   1833 	p->errs = errs;
   1834 	p->stack = NULL;
   1835 }
   1836 
   1837 /*
   1838 static void print_code(u8 *code, int code_len)
   1839 {
   1840 	struct cursor c;
   1841 	struct expr_parser parser;
   1842 	struct errors errs;
   1843 	struct instr op;
   1844 	u8 tag;
   1845 
   1846 	errs.enabled = 0;
   1847 
   1848 	make_expr_parser(&errs, &c, &parser);
   1849 	make_cursor(code, code + code_len, &c);
   1850 
   1851 	for (;;) {
   1852 		if (!pull_byte(&c, &tag)) {
   1853 			break;
   1854 		}
   1855 
   1856 		printf("%s ", instr_name(tag));
   1857 
   1858 		if (!parse_instr(&parser, tag, &op)) {
   1859 			break;
   1860 		}
   1861 	}
   1862 
   1863 	printf("\n");
   1864 }
   1865 */
   1866 
   1867 static INLINE int is_const_instr(u8 tag)
   1868 {
   1869 	switch ((enum const_instr)tag) {
   1870 	case ci_global_get:
   1871 	case ci_ref_null:
   1872 	case ci_ref_func:
   1873 	case ci_const_i32:
   1874 	case ci_const_i64:
   1875 	case ci_const_f32:
   1876 	case ci_end:
   1877 	case ci_const_f64:
   1878 		return 1;
   1879 	}
   1880 	return 0;
   1881 }
   1882 
   1883 static INLINE int cursor_push_nullval(struct cursor *stack)
   1884 {
   1885 	struct val val;
   1886 	val.type = val_ref_null;
   1887 	return cursor_pushval(stack, &val);
   1888 }
   1889 
   1890 static INLINE const char *bulk_op_name(struct bulk_op *op)
   1891 {
   1892 	switch (op->tag) {
   1893 	case i_memory_fill: return "memory.fill";
   1894 	case i_memory_copy: return "memory.copy";
   1895 	case i_table_init:  return "table.init";
   1896 	case i_elem_drop:   return "elem.drop";
   1897 	case i_table_copy:  return "table.copy";
   1898 	case i_table_grow:  return "table.grow";
   1899 	case i_table_size:  return "table.size";
   1900 	case i_table_fill:  return "table.fill";
   1901 	}
   1902 
   1903 	return "?";
   1904 }
   1905 
   1906 static const char *show_instr(struct instr *instr)
   1907 {
   1908 	struct cursor buf;
   1909 	static char buffer[64];
   1910 	static char tmp[32];
   1911 	int len, i;
   1912 
   1913 	buffer[sizeof(buffer)-1] = 0;
   1914 	make_cursor((u8*)buffer, (u8*)buffer + sizeof(buffer) - 1, &buf);
   1915 
   1916 	cursor_push_str(&buf, instr_name(instr->tag));
   1917 	len = buf.p - buf.start;
   1918 
   1919 	for (i = 0; i < 14-len; i++)
   1920 		cursor_push_byte(&buf, ' ');
   1921 
   1922 	switch (instr->tag) {
   1923 		// two-byte instrs
   1924 		case i_memory_size:
   1925 		case i_memory_grow:
   1926 			sprintf(tmp, "0x%02x", instr->memidx);
   1927 			cursor_push_str(&buf, tmp);
   1928 			break;
   1929 
   1930 		case i_block:
   1931 		case i_loop:
   1932 		case i_if:
   1933 			break;
   1934 
   1935 		case i_else:
   1936 		case i_end:
   1937 			break;
   1938 
   1939 		case i_call:
   1940 		case i_local_get:
   1941 		case i_local_set:
   1942 		case i_local_tee:
   1943 		case i_global_get:
   1944 		case i_global_set:
   1945 		case i_br:
   1946 		case i_br_if:
   1947 		case i_i32_const:
   1948 		case i_ref_func:
   1949 		case i_table_set:
   1950 		case i_table_get:
   1951 			sprintf(tmp, "%d", instr->i32);
   1952 			cursor_push_str(&buf, tmp);
   1953 			break;
   1954 
   1955 		case i_i64_const:
   1956 			sprintf(tmp, "%" PRId64, instr->i64);
   1957 			cursor_push_str(&buf, tmp);
   1958 			break;
   1959 
   1960 		case i_ref_null:
   1961 			sprintf(tmp, "%s", reftype_name(instr->reftype));
   1962 			cursor_push_str(&buf, tmp);
   1963 			break;
   1964 
   1965 
   1966 		case i_i32_load:
   1967 		case i_i64_load:
   1968 		case i_f32_load:
   1969 		case i_f64_load:
   1970 		case i_i32_load8_s:
   1971 		case i_i32_load8_u:
   1972 		case i_i32_load16_s:
   1973 		case i_i32_load16_u:
   1974 		case i_i64_load8_s:
   1975 		case i_i64_load8_u:
   1976 		case i_i64_load16_s:
   1977 		case i_i64_load16_u:
   1978 		case i_i64_load32_s:
   1979 		case i_i64_load32_u:
   1980 		case i_i32_store:
   1981 		case i_i64_store:
   1982 		case i_f32_store:
   1983 		case i_f64_store:
   1984 		case i_i32_store8:
   1985 		case i_i32_store16:
   1986 		case i_i64_store8:
   1987 		case i_i64_store16:
   1988 		case i_i64_store32:
   1989 			sprintf(tmp, "%d %d", instr->memarg.offset, instr->memarg.align);
   1990 			cursor_push_str(&buf, tmp);
   1991 			break;
   1992 
   1993 		case i_selects:
   1994 			break;
   1995 
   1996 		case i_br_table:
   1997 			break;
   1998 
   1999 		case i_call_indirect:
   2000 			sprintf(tmp, "%d %d", instr->call_indirect.typeidx,
   2001 					instr->call_indirect.tableidx);
   2002 			cursor_push_str(&buf, tmp);
   2003 			break;
   2004 
   2005 		case i_f32_const:
   2006 			sprintf(tmp, "%f", instr->f32);
   2007 			cursor_push_str(&buf, tmp);
   2008 			break;
   2009 
   2010 		case i_f64_const:
   2011 			sprintf(tmp, "%f", instr->f64);
   2012 			cursor_push_str(&buf, tmp);
   2013 			break;
   2014 
   2015 		// single-tag ops
   2016 		case i_unreachable:
   2017 		case i_nop:
   2018 		case i_return:
   2019 		case i_drop:
   2020 		case i_select:
   2021 		case i_i32_eqz:
   2022 		case i_i32_eq:
   2023 		case i_i32_ne:
   2024 		case i_i32_lt_s:
   2025 		case i_i32_lt_u:
   2026 		case i_i32_gt_s:
   2027 		case i_i32_gt_u:
   2028 		case i_i32_le_s:
   2029 		case i_i32_le_u:
   2030 		case i_i32_ge_s:
   2031 		case i_i32_ge_u:
   2032 		case i_i64_eqz:
   2033 		case i_i64_eq:
   2034 		case i_i64_ne:
   2035 		case i_i64_lt_s:
   2036 		case i_i64_lt_u:
   2037 		case i_i64_gt_s:
   2038 		case i_i64_gt_u:
   2039 		case i_i64_le_s:
   2040 		case i_i64_le_u:
   2041 		case i_i64_ge_s:
   2042 		case i_i64_ge_u:
   2043 		case i_f32_eq:
   2044 		case i_f32_ne:
   2045 		case i_f32_lt:
   2046 		case i_f32_gt:
   2047 		case i_f32_le:
   2048 		case i_f32_ge:
   2049 		case i_f64_eq:
   2050 		case i_f64_ne:
   2051 		case i_f64_lt:
   2052 		case i_f64_gt:
   2053 		case i_f64_le:
   2054 		case i_f64_ge:
   2055 		case i_i32_clz:
   2056 		case i_i32_ctz:
   2057 		case i_i32_popcnt:
   2058 		case i_i32_add:
   2059 		case i_i32_sub:
   2060 		case i_i32_mul:
   2061 		case i_i32_div_s:
   2062 		case i_i32_div_u:
   2063 		case i_i32_rem_s:
   2064 		case i_i32_rem_u:
   2065 		case i_i32_and:
   2066 		case i_i32_or:
   2067 		case i_i32_xor:
   2068 		case i_i32_shl:
   2069 		case i_i32_shr_s:
   2070 		case i_i32_shr_u:
   2071 		case i_i32_rotl:
   2072 		case i_i32_rotr:
   2073 		case i_i64_clz:
   2074 		case i_i64_ctz:
   2075 		case i_i64_popcnt:
   2076 		case i_i64_add:
   2077 		case i_i64_sub:
   2078 		case i_i64_mul:
   2079 		case i_i64_div_s:
   2080 		case i_i64_div_u:
   2081 		case i_i64_rem_s:
   2082 		case i_i64_rem_u:
   2083 		case i_i64_and:
   2084 		case i_i64_or:
   2085 		case i_i64_xor:
   2086 		case i_i64_shl:
   2087 		case i_i64_shr_s:
   2088 		case i_i64_shr_u:
   2089 		case i_i64_rotl:
   2090 		case i_i64_rotr:
   2091 		case i_f32_abs:
   2092 		case i_f32_neg:
   2093 		case i_f32_ceil:
   2094 		case i_f32_floor:
   2095 		case i_f32_trunc:
   2096 		case i_f32_nearest:
   2097 		case i_f32_sqrt:
   2098 		case i_f32_add:
   2099 		case i_f32_sub:
   2100 		case i_f32_mul:
   2101 		case i_f32_div:
   2102 		case i_f32_min:
   2103 		case i_f32_max:
   2104 		case i_f32_copysign:
   2105 		case i_f64_abs:
   2106 		case i_f64_neg:
   2107 		case i_f64_ceil:
   2108 		case i_f64_floor:
   2109 		case i_f64_trunc:
   2110 		case i_f64_nearest:
   2111 		case i_f64_sqrt:
   2112 		case i_f64_add:
   2113 		case i_f64_sub:
   2114 		case i_f64_mul:
   2115 		case i_f64_div:
   2116 		case i_f64_min:
   2117 		case i_f64_max:
   2118 		case i_f64_copysign:
   2119 		case i_i32_wrap_i64:
   2120 		case i_i32_trunc_f32_s:
   2121 		case i_i32_trunc_f32_u:
   2122 		case i_i32_trunc_f64_s:
   2123 		case i_i32_trunc_f64_u:
   2124 		case i_i64_extend_i32_s:
   2125 		case i_i64_extend_i32_u:
   2126 		case i_i64_trunc_f32_s:
   2127 		case i_i64_trunc_f32_u:
   2128 		case i_i64_trunc_f64_s:
   2129 		case i_i64_trunc_f64_u:
   2130 		case i_f32_convert_i32_s:
   2131 		case i_f32_convert_i32_u:
   2132 		case i_f32_convert_i64_s:
   2133 		case i_f32_convert_i64_u:
   2134 		case i_f32_demote_f64:
   2135 		case i_f64_convert_i32_s:
   2136 		case i_f64_convert_i32_u:
   2137 		case i_f64_convert_i64_s:
   2138 		case i_f64_convert_i64_u:
   2139 		case i_f64_promote_f32:
   2140 		case i_i32_reinterpret_f32:
   2141 		case i_i64_reinterpret_f64:
   2142 		case i_f32_reinterpret_i32:
   2143 		case i_f64_reinterpret_i64:
   2144 		case i_i32_extend8_s:
   2145 		case i_i32_extend16_s:
   2146 		case i_i64_extend8_s:
   2147 		case i_i64_extend16_s:
   2148 		case i_i64_extend32_s:
   2149 		case i_ref_is_null:
   2150 			break;
   2151 		case i_bulk_op:
   2152 			cursor_push_str(&buf, bulk_op_name(&instr->bulk_op));
   2153 			break;
   2154 	}
   2155 
   2156 	cursor_push_byte(&buf, 0);
   2157 	return buffer;
   2158 }
   2159 
   2160 static int eval_const_instr(struct instr *instr, struct errors *errs,
   2161 		struct cursor *stack)
   2162 {
   2163 	//debug("eval_const_instr %s\n", show_instr(instr));
   2164 
   2165 	switch ((enum const_instr)instr->tag) {
   2166 	case ci_global_get:
   2167 		return note_error(errs, stack, "todo: global_get inside global");
   2168 	case ci_ref_null:
   2169 		if (unlikely(!cursor_push_nullval(stack))) {
   2170 			return note_error(errs, stack, "couldn't push null");
   2171 		}
   2172 		return 1;
   2173 	case ci_ref_func:
   2174 		if (unlikely(!cursor_push_funcref(stack, instr->i32))) {
   2175 			return note_error(errs, stack, "couldn't push funcref");
   2176 		}
   2177 		return 1;
   2178 	case ci_const_i32:
   2179 		if (unlikely(!cursor_push_i32(stack, instr->i32))) {
   2180 			return note_error(errs, stack,
   2181 					"global push i32 const");
   2182 		}
   2183 		return 1;
   2184 	case ci_const_i64:
   2185 		return note_error(errs, stack, "todo: global push const i64");
   2186 	case ci_const_f32:
   2187 		return note_error(errs, stack, "todo: global push const f32");
   2188 	case ci_end:
   2189 		return note_error(errs, stack, "unexpected end tag");
   2190 	case ci_const_f64:
   2191 		return note_error(errs, stack, "todo: global push const f64");
   2192 	}
   2193 
   2194 	return note_error(errs, stack, "non-const expr instr %s",
   2195 			instr_name(instr->tag));
   2196 }
   2197 
   2198 static int parse_const_expr(struct expr_parser *p, struct expr *expr)
   2199 {
   2200 	u8 tag;
   2201 	struct instr instr;
   2202 
   2203 	expr->code = p->code->p;
   2204 
   2205 	while (1) {
   2206 		if (unlikely(!pull_byte(p->code, &tag))) {
   2207 			return note_error(p->errs, p->code, "oob");
   2208 		}
   2209 
   2210 		if (unlikely(!is_const_instr(tag))) {
   2211 			return note_error(p->errs, p->code,
   2212 					"invalid const expr instruction: '%s'",
   2213 					instr_name(tag));
   2214 		}
   2215 
   2216 		if (tag == i_end) {
   2217 			expr->code_len = p->code->p - expr->code;
   2218 			return 1;
   2219 		}
   2220 
   2221 		if (unlikely(!parse_instr(p, tag, &instr))) {
   2222 			return note_error(p->errs, p->code,
   2223 					"couldn't parse const expr instr '%s'",
   2224 					instr_name(tag));
   2225 		}
   2226 
   2227 		if (p->stack &&
   2228 		    unlikely(!eval_const_instr(&instr, p->errs, p->stack))) {
   2229 			return note_error(p->errs, p->code, "eval const instr");
   2230 		}
   2231 	}
   2232 
   2233 	return 0;
   2234 }
   2235 
   2236 static INLINE void make_const_expr_evaluator(struct errors *errs,
   2237 		struct cursor *code, struct cursor *stack,
   2238 		struct expr_parser *parser)
   2239 {
   2240 	parser->interp = NULL;
   2241 	parser->stack = stack;
   2242 	parser->code = code;
   2243 	parser->errs = errs;
   2244 }
   2245 
   2246 static INLINE void make_const_expr_parser(struct wasm_parser *p,
   2247 		struct expr_parser *parser)
   2248 {
   2249 	parser->interp = NULL;
   2250 	parser->stack = NULL;
   2251 	parser->code = &p->cur;
   2252 	parser->errs = &p->errs;
   2253 }
   2254 
   2255 static INLINE int eval_const_expr(struct expr *expr, struct errors *errs,
   2256 		struct cursor *stack)
   2257 {
   2258 	struct cursor code;
   2259 	struct expr expr_out;
   2260 	struct expr_parser parser;
   2261 
   2262 	make_cursor(expr->code, expr->code + expr->code_len, &code);
   2263 	make_const_expr_evaluator(errs, &code, stack, &parser);
   2264 
   2265 	return parse_const_expr(&parser, &expr_out);
   2266 }
   2267 
   2268 static INLINE int eval_const_val(struct expr *expr, struct errors *errs,
   2269 		struct cursor *stack, struct val *val)
   2270 {
   2271 	if (!eval_const_expr(expr, errs, stack)) {
   2272 		return note_error(errs, stack, "eval const expr");
   2273 	}
   2274 
   2275 	if (!cursor_popval(stack, val)) {
   2276 		return note_error(errs, stack, "no val to pop?");
   2277 	}
   2278 
   2279 	if (cursor_dropval(stack))  {
   2280 		return note_error(errs, stack, "stack not empty");
   2281 	}
   2282 
   2283 	return 1;
   2284 }
   2285 
   2286 
   2287 static int parse_global(struct wasm_parser *p,
   2288 		struct global *global)
   2289 {
   2290 	struct expr_parser parser;
   2291 	struct cursor stack;
   2292 
   2293 	stack.start = p->mem.p;
   2294 	stack.p = p->mem.p;
   2295 	stack.end = p->mem.end;
   2296 
   2297 	make_const_expr_evaluator(&p->errs, &p->cur, &stack, &parser);
   2298 
   2299 	if (!parse_globaltype(p, &global->type)) {
   2300 		return parse_err(p, "type");
   2301 	}
   2302 
   2303 	if (!parse_const_expr(&parser, &global->init)) {
   2304 		return parse_err(p, "init code");
   2305 	}
   2306 
   2307 	if (!cursor_popval(&stack, &global->val)) {
   2308 		return parse_err(p, "couldn't eval global expr");
   2309 	}
   2310 
   2311 	return 1;
   2312 }
   2313 
   2314 static int parse_global_section(struct wasm_parser *p,
   2315 		struct globalsec *global_section)
   2316 {
   2317 	struct global *globals;
   2318 	u32 elems, i;
   2319 
   2320 	if (!parse_vector(p, sizeof(*globals), &elems, (void**)&globals)) {
   2321 		return parse_err(p, "globals vector");
   2322 	}
   2323 
   2324 	for (i = 0; i < elems; i++) {
   2325 		if (!parse_global(p, &globals[i])) {
   2326 			return parse_err(p, "global #%d/%d", i+1, elems);
   2327 		}
   2328 	}
   2329 
   2330 	global_section->num_globals = elems;
   2331 	global_section->globals = globals;
   2332 
   2333 	return 1;
   2334 }
   2335 
   2336 static INLINE void make_interp_expr_parser(struct wasm_interp *interp,
   2337 		struct expr_parser *p)
   2338 {
   2339 	assert(interp);
   2340 
   2341 	p->interp = interp;
   2342 	p->code = interp_codeptr(interp);
   2343 	p->errs = &interp->errors;
   2344 
   2345 	assert(p->code);
   2346 }
   2347 
   2348 static int push_label_checkpoint(struct wasm_interp *interp, struct label **label,
   2349 		u8 start_tag, u8 end_tag);
   2350 
   2351 static int parse_instrs_until_at(struct expr_parser *p, u8 stop_instr,
   2352                struct expr *expr, u8 *stopped_at)
   2353 {
   2354        u8 tag;
   2355        struct instr op;
   2356 #ifdef DEBUG
   2357        static int dbg = 0;
   2358        int dbg_inst = dbg++;
   2359 #endif
   2360 
   2361        expr->code = p->code->p;
   2362        expr->code_len = 0;
   2363 
   2364        debug("%04lX parse_instrs_until %d for %s starting\n",
   2365 		       p->code->p - p->code->start,
   2366 		       dbg_inst, instr_name(stop_instr));
   2367        for (;;) {
   2368                if (!pull_byte(p->code, &tag))
   2369                        return note_error(p->errs, p->code, "oob");
   2370 
   2371 	       if ((tag != i_if && tag == stop_instr) ||
   2372 		   (stop_instr == i_if && (tag == i_else || tag == i_end))) {
   2373 		       //debug("parse_instrs_until ending\n");
   2374 		       expr->code_len = p->code->p - expr->code;
   2375 
   2376 		       *stopped_at = tag;
   2377 
   2378 		       debug("%04lX parse_instrs_until @%s %d for %s done\n",
   2379 				       p->code->p - p->code->start,
   2380 				       instr_name(tag),
   2381 				       dbg_inst,
   2382 				       instr_name(stop_instr));
   2383 
   2384 #ifdef DEBUG
   2385 		       dbg--;
   2386 #endif
   2387 
   2388                        return 1;
   2389                }
   2390 
   2391 		debug("%04lX parsing instr %s (0x%02x)\n",
   2392 			p->code->p - 1 - p->code->start, instr_name(tag), tag);
   2393                if (!parse_instr(p, tag, &op)) {
   2394                        return note_error(p->errs, p->code,
   2395 			  "parse %s instr (0x%x)", instr_name(tag), tag);
   2396 	       }
   2397 
   2398        }
   2399 }
   2400 
   2401 static INLINE int parse_instrs_until(struct expr_parser *p, u8 stop_instr,
   2402                struct expr *expr)
   2403 {
   2404 	u8 at;
   2405 	return parse_instrs_until_at(p, stop_instr, expr, &at);
   2406 }
   2407 
   2408 static int parse_elem_func_inits(struct wasm_parser *p, struct elem *elem)
   2409 {
   2410 	u32 index, i;
   2411 	struct expr *expr;
   2412 
   2413 	if (!parse_u32(&p->cur, &elem->num_inits))
   2414 		return parse_err(p, "func indices vec read fail");
   2415 
   2416 	if (!(elem->inits = cursor_alloc(&p->mem, elem->num_inits *
   2417 					 sizeof(struct expr)))) {
   2418 		return parse_err(p, "couldn't alloc vec(funcidx) for elem");
   2419 	}
   2420 
   2421 	for (i = 0; i < elem->num_inits; i++) {
   2422 		expr = &elem->inits[i];
   2423 		expr->code = p->mem.p;
   2424 
   2425 		if (!parse_u32(&p->cur, &index))
   2426 			return parse_err(p, "func index %d read fail", i);
   2427 		if (!cursor_push_byte(&p->mem, i_ref_func))
   2428 			return parse_err(p, "push ref_func instr oob for %d", i);
   2429 		if (!leb128_write(&p->mem, index))
   2430 			return parse_err(p, "push ref_func u32 index oob for %d", i);
   2431 		if (!cursor_push_byte(&p->mem, i_end))
   2432 			return parse_err(p, "push i_end for init %d", i);
   2433 
   2434 		expr->code_len = p->mem.p - expr->code;
   2435 	}
   2436 
   2437 	return 1;
   2438 }
   2439 
   2440 
   2441 static int parse_element(struct wasm_parser *p, struct elem *elem)
   2442 {
   2443 	u8 tag = 0;
   2444 	struct expr_parser expr_parser;
   2445 	(void)elem;
   2446 
   2447 	make_expr_parser(&p->errs, &p->cur, &expr_parser);
   2448 
   2449 	if (!pull_byte(&p->cur, &tag))
   2450 		return parse_err(p, "tag");
   2451 
   2452 	if (tag > 7)
   2453 		return parse_err(p, "expected tag 0x00 to 0x07, got 0x%02x", tag);
   2454 
   2455 	switch (tag) {
   2456 	case 0x00:
   2457 		if (!parse_instrs_until(&expr_parser, i_end, &elem->offset))
   2458 			return parse_err(p, "elem 0x00 offset expr");
   2459 
   2460 		// func inits
   2461 		if (!parse_elem_func_inits(p, elem))
   2462 			return parse_err(p, "generate func index exprs");
   2463 
   2464 
   2465 		elem->mode = elem_mode_active;
   2466 		elem->tableidx = 0;
   2467 		elem->reftype = funcref;
   2468 		break;
   2469 
   2470 	default:
   2471 		return parse_err(p, "implement parse element 0x%02x", tag);
   2472 	}
   2473 
   2474 	return 1;
   2475 }
   2476 
   2477 static int parse_custom_section(struct wasm_parser *p, u32 size,
   2478 		struct customsec *section)
   2479 {
   2480 	u8 *start;
   2481 	start = p->cur.p;
   2482 
   2483 	if (p->module.custom_sections + 1 > MAX_CUSTOM_SECTIONS)
   2484 		return parse_err(p, "more than 32 custom sections!");
   2485 
   2486 	if (!parse_name(p, &section->name))
   2487 		return parse_err(p, "name");
   2488 
   2489 	section->data = p->cur.p;
   2490 	section->data_len = size - (p->cur.p - start);
   2491 
   2492 	debug("custom sec minus %ld\n", p->cur.p - start);
   2493 
   2494 	if (!strcmp(section->name, "name")) {
   2495 		if (!parse_name_section(p, &p->module.name_section, section)) {
   2496 			return parse_err(p,
   2497 					"failed to parse name custom section");
   2498 		}
   2499 	} else {
   2500 		p->cur.p += section->data_len;
   2501 	}
   2502 
   2503 	p->module.custom_sections++;
   2504 
   2505 	return 1;
   2506 }
   2507 
   2508 static int parse_element_section(struct wasm_parser *p, struct elemsec *elemsec)
   2509 {
   2510 	struct elem *elements;
   2511 	u32 count, i;
   2512 
   2513 	if (!parse_vector(p, sizeof(struct elem), &count, (void**)&elements))
   2514 		return parse_err(p, "elements vec");
   2515 
   2516 	for (i = 0; i < count; i++) {
   2517 		if (!parse_element(p, &elements[i]))
   2518 			return parse_err(p, "element %d of %d", i+1, count);
   2519 	}
   2520 
   2521 	elemsec->num_elements = count;
   2522 	elemsec->elements = elements;
   2523 
   2524 	return 1;
   2525 }
   2526 
   2527 static int parse_memory_section(struct wasm_parser *p,
   2528 		struct memsec *memory_section)
   2529 {
   2530 	struct limits *mems;
   2531 	u32 elems, i;
   2532 
   2533 	if (!parse_vector(p, sizeof(*mems), &elems, (void**)&mems)) {
   2534 		return parse_err(p, "mems vector");
   2535 	}
   2536 
   2537 	for (i = 0; i < elems; i++) {
   2538 		if (!parse_limits(p, &mems[i])) {
   2539 			return parse_err(p, "memory #%d/%d", i+1, elems);
   2540 		}
   2541 	}
   2542 
   2543 	memory_section->num_mems = elems;
   2544 	memory_section->mems = mems;
   2545 
   2546 	return 1;
   2547 }
   2548 
   2549 static int parse_start_section(struct wasm_parser *p,
   2550 		struct startsec *start_section)
   2551 {
   2552 	if (!parse_u32(&p->cur, &start_section->start_fn)) {
   2553 		return parse_err(p, "start_fn index");
   2554 	}
   2555 
   2556 	return 1;
   2557 }
   2558 
   2559 static INLINE int parse_byte_vector(struct wasm_parser *p, u8 **data,
   2560 		u32 *data_len)
   2561 {
   2562 	if (!parse_u32(&p->cur, data_len)) {
   2563 		return parse_err(p, "len");
   2564 	}
   2565 
   2566 	if (p->cur.p + *data_len > p->cur.end) {
   2567 		return parse_err(p, "byte vector overflow");
   2568 	}
   2569 
   2570 	*data = p->cur.p;
   2571 	p->cur.p += *data_len;
   2572 
   2573 	return 1;
   2574 }
   2575 
   2576 static int parse_wdata(struct wasm_parser *p, struct wdata *data)
   2577 {
   2578 	struct expr_parser parser;
   2579 	u8 tag;
   2580 
   2581 	if (!pull_byte(&p->cur, &tag)) {
   2582 		return parse_err(p, "tag");
   2583 	}
   2584 
   2585 	if (tag > 2) {
   2586 		cursor_print_around(&p->cur, 10);
   2587 		return parse_err(p, "invalid datasegment tag: 0x%x", tag);
   2588 	}
   2589 
   2590 	make_const_expr_parser(p, &parser);
   2591 
   2592 	switch (tag) {
   2593 	case 0:
   2594 		data->mode = datamode_active;
   2595 		data->active.mem_index = 0;
   2596 
   2597 		if (!parse_const_expr(&parser, &data->active.offset_expr)) {
   2598 			return parse_err(p, "const expr");
   2599 		}
   2600 
   2601 		if (!parse_byte_vector(p, &data->bytes, &data->bytes_len)) {
   2602 			return parse_err(p, "bytes vector");
   2603 		}
   2604 
   2605 		break;
   2606 
   2607 	case 1:
   2608 		data->mode = datamode_passive;
   2609 
   2610 		if (!parse_byte_vector(p, &data->bytes, &data->bytes_len)) {
   2611 			return parse_err(p, "passive bytes vector");
   2612 		}
   2613 
   2614 		break;
   2615 
   2616 	case 2:
   2617 		data->mode = datamode_active;
   2618 
   2619 		if (!parse_u32(&p->cur, &data->active.mem_index))  {
   2620 			return parse_err(p, "read active data mem_index");
   2621 		}
   2622 
   2623 		if (!parse_const_expr(&parser, &data->active.offset_expr)) {
   2624 			return parse_err(p, "read active data (w/ mem_index) offset_expr");
   2625 		}
   2626 
   2627 		if (!parse_byte_vector(p, &data->bytes, &data->bytes_len)) {
   2628 			return parse_err(p, "active (w/ mem_index) bytes vector");
   2629 		}
   2630 
   2631 		break;
   2632 	}
   2633 
   2634 	return 1;
   2635 }
   2636 
   2637 static int parse_data_count_section(struct wasm_parser *p, struct datasec *section)
   2638 {
   2639 	if (!parse_u32(&p->cur, &section->num_datas))
   2640 		return parse_err(p, "data count");
   2641 	return 1;
   2642 }
   2643 
   2644 static int parse_data_section(struct wasm_parser *p, struct datasec *section)
   2645 {
   2646 	struct wdata *data;
   2647 	u32 elems, i;
   2648 
   2649 	if (!parse_vector(p, sizeof(*data), &elems, (void**)&data))
   2650 		return parse_err(p, "datas vector");
   2651 
   2652 	if (was_section_parsed(&p->module, section_data_count) &&
   2653 			elems != section->num_datas) {
   2654 		return parse_err(p, "we got a data count section with %d "
   2655 				"elements but the data section says it has %d "
   2656 				"elements. what's up with that?",
   2657 				section->num_datas, elems);
   2658 	}
   2659 
   2660 	for (i = 0; i < elems; i++) {
   2661 		if (!parse_wdata(p, &data[i])) {
   2662 			return parse_err(p, "data segment #%d/%d", i+1, elems);
   2663 		}
   2664 	}
   2665 
   2666 	section->num_datas = elems;
   2667 	section->datas = data;
   2668 
   2669 	return 1;
   2670 }
   2671 
   2672 static int parse_table_section(struct wasm_parser *p,
   2673 		struct tablesec *table_section)
   2674 {
   2675 	struct table *tables;
   2676 	u32 elems, i;
   2677 
   2678 	if (!parse_vector(p, sizeof(*tables), &elems, (void**)&tables)) {
   2679 		return parse_err(p, "tables vector");
   2680 	}
   2681 
   2682 	for (i = 0; i < elems; i++) {
   2683 		if (!parse_table(p, &tables[i])) {
   2684 			parse_err(p, "table #%d/%d", i+1, elems);
   2685 			return 0;
   2686 		}
   2687 	}
   2688 
   2689 	table_section->num_tables = elems;
   2690 	table_section->tables = tables;
   2691 
   2692 	return 1;
   2693 }
   2694 
   2695 static int parse_function_section(struct wasm_parser *p,
   2696 		struct funcsec *funcsec)
   2697 {
   2698 	u32 i, elems, *indices;
   2699 
   2700 	if (!parse_vector(p, sizeof(*indices), &elems, (void**)&indices)) {
   2701 		return parse_err(p, "indices");
   2702 	}
   2703 
   2704 	for (i = 0; i < elems; i++) {
   2705 		if (!parse_u32(&p->cur, &indices[i])) {
   2706 			parse_err(p, "typeidx #%d", i);
   2707 			return 0;
   2708 		}
   2709 	}
   2710 
   2711 	funcsec->type_indices = indices;
   2712 	funcsec->num_indices = elems;
   2713 
   2714 	return 1;
   2715 }
   2716 
   2717 static int parse_import_table(struct wasm_parser *p, struct limits *limits)
   2718 {
   2719 	if (!consume_byte(&p->cur, 0x70)) {
   2720 		parse_err(p, "elemtype != 0x70");
   2721 		return 0;
   2722 	}
   2723 
   2724 	if (!parse_limits(p, limits)) {
   2725 		parse_err(p, "limits");
   2726 		return 0;
   2727 	}
   2728 
   2729 	return 1;
   2730 }
   2731 
   2732 static int parse_importdesc(struct wasm_parser *p, struct importdesc *desc)
   2733 {
   2734 	u8 tag;
   2735 
   2736 	if (!pull_byte(&p->cur, &tag)) {
   2737 		parse_err(p, "oom");
   2738 		return 0;
   2739 	}
   2740 
   2741 	desc->type = (enum import_type)tag;
   2742 
   2743 	switch (desc->type) {
   2744 	case import_func:
   2745 		if (!parse_u32(&p->cur, &desc->typeidx)) {
   2746 			parse_err(p, "typeidx");
   2747 			return 0;
   2748 		}
   2749 
   2750 		return 1;
   2751 
   2752 	case import_table:
   2753 		return parse_import_table(p, &desc->tabletype);
   2754 
   2755 	case import_mem:
   2756 		if (!parse_limits(p, &desc->memtype)) {
   2757 			parse_err(p, "memtype limits");
   2758 			return 0;
   2759 		}
   2760 
   2761 		return 1;
   2762 
   2763 	case import_global:
   2764 		if (!parse_globaltype(p, &desc->globaltype)) {
   2765 			parse_err(p, "globaltype");
   2766 			return 0;
   2767 		}
   2768 
   2769 		return 1;
   2770 	}
   2771 
   2772 	parse_err(p, "unknown importdesc tag %02x", tag);
   2773 	return 0;
   2774 }
   2775 
   2776 static int find_builtin(const char *name)
   2777 {
   2778 	struct builtin *b;
   2779 	u32 i;
   2780 
   2781 	for (i = 0; i < NUM_BUILTINS; i++) {
   2782 		b = &BUILTINS[i];
   2783 		if (!strcmp(b->name, name))
   2784 			return i;
   2785 	}
   2786 	return -1;
   2787 }
   2788 
   2789 static int parse_import(struct wasm_parser *p, struct import *import)
   2790 {
   2791 	import->resolved_builtin = -1;
   2792 
   2793 	if (!parse_name(p, &import->module_name))
   2794 		return parse_err(p, "module name");
   2795 
   2796 	if (!parse_name(p, &import->name))
   2797 		return parse_err(p, "name");
   2798 
   2799 	if (!parse_importdesc(p, &import->desc))
   2800 		return parse_err(p, "desc");
   2801 
   2802 	if (import->desc.type == import_func) {
   2803 		import->resolved_builtin =
   2804 			find_builtin(import->name);
   2805 	}
   2806 
   2807 	return 1;
   2808 }
   2809 
   2810 static int parse_import_section(struct wasm_parser *p, struct importsec *importsec)
   2811 {
   2812 	u32 elems, i;
   2813 	struct import *imports;
   2814 
   2815 	if (!parse_vector(p, sizeof(*imports), &elems, (void**)&imports)) {
   2816 		return parse_err(p, "imports");
   2817 	}
   2818 
   2819 	for (i = 0; i < elems; i++) {
   2820 		if (!parse_import(p, &imports[i])) {
   2821 			return parse_err(p, "import #%d", i);
   2822 		}
   2823 	}
   2824 
   2825 	importsec->imports = imports;
   2826 	importsec->num_imports = elems;
   2827 
   2828 	return 1;
   2829 }
   2830 
   2831 /* type section is just a vector of function types */
   2832 static int parse_type_section(struct wasm_parser *p, struct typesec *typesec)
   2833 {
   2834 	u32 elems, i;
   2835 	struct functype *functypes;
   2836 
   2837 	typesec->num_functypes = 0;
   2838 	typesec->functypes = NULL;
   2839 
   2840 	if (!parse_vector(p, sizeof(*functypes), &elems, (void**)&functypes)) {
   2841 		parse_err(p, "functypes");
   2842 		return 0;
   2843 	}
   2844 
   2845 	for (i = 0; i < elems; i++) {
   2846 		if (!parse_func_type(p, &functypes[i])) {
   2847 			parse_err(p, "functype #%d", i);
   2848 			return 0;
   2849 		}
   2850 	}
   2851 
   2852 	typesec->functypes = functypes;
   2853 	typesec->num_functypes = elems;
   2854 
   2855 	return 1;
   2856 }
   2857 
   2858 static int parse_section_by_tag(struct wasm_parser *p, enum section_tag tag,
   2859 				u32 size)
   2860 {
   2861 	(void)size;
   2862 	switch (tag) {
   2863 	case section_custom:
   2864 		if (!parse_custom_section(p, size,
   2865 			&p->module.custom_section[p->module.custom_sections]))
   2866 			return parse_err(p, "custom section");
   2867 		return 1;
   2868 	case section_type:
   2869 		if (!parse_type_section(p, &p->module.type_section)) {
   2870 			return parse_err(p, "type section");
   2871 		}
   2872 		return 1;
   2873 	case section_import:
   2874 		if (!parse_import_section(p, &p->module.import_section)) {
   2875 			return parse_err(p, "import section");
   2876 		}
   2877 		return 1;
   2878 	case section_function:
   2879 		if (!parse_function_section(p, &p->module.func_section)) {
   2880 			return parse_err(p, "function section");
   2881 		}
   2882 		return 1;
   2883 	case section_table:
   2884 		if (!parse_table_section(p, &p->module.table_section)) {
   2885 			return parse_err(p, "table section");
   2886 		}
   2887 		return 1;
   2888 	case section_memory:
   2889 		if (!parse_memory_section(p, &p->module.memory_section)) {
   2890 			return parse_err(p, "memory section");
   2891 		}
   2892 		return 1;
   2893 	case section_global:
   2894 		if (!parse_global_section(p, &p->module.global_section)) {
   2895 			return parse_err(p, "global section");
   2896 		}
   2897 		return 1;
   2898 	case section_export:
   2899 		if (!parse_export_section(p, &p->module.export_section)) {
   2900 			return parse_err(p, "export section");
   2901 		}
   2902 		return 1;
   2903 	case section_start:
   2904 		if (!parse_start_section(p, &p->module.start_section)) {
   2905 			return parse_err(p, "start section");
   2906 		}
   2907 		return 1;
   2908 
   2909 	case section_element:
   2910 		if (!parse_element_section(p, &p->module.element_section)) {
   2911 			return parse_err(p, "element section");
   2912 		}
   2913 		return 1;
   2914 
   2915 	case section_code:
   2916 		if (!parse_code_section(p, &p->module.code_section)) {
   2917 			return parse_err(p, "code section");
   2918 		}
   2919 		return 1;
   2920 
   2921 	case section_data:
   2922 		if (!parse_data_section(p, &p->module.data_section))
   2923 			return parse_err(p, "data section");
   2924 		return 1;
   2925 
   2926 	case section_data_count:
   2927 		if (!parse_data_count_section(p, &p->module.data_section))
   2928 			return parse_err(p, "data count section");
   2929 		return 1;
   2930 
   2931 	default:
   2932 		return parse_err(p, "invalid section tag %d", tag);
   2933 	}
   2934 
   2935 	return 1;
   2936 }
   2937 
   2938 static const char *section_str(enum section_tag tag)
   2939 {
   2940 	switch (tag) {
   2941 		case section_custom:
   2942 			return "custom";
   2943 		case section_type:
   2944 			return "type";
   2945 		case section_import:
   2946 			return "import";
   2947 		case section_function:
   2948 			return "function";
   2949 		case section_table:
   2950 			return "table";
   2951 		case section_memory:
   2952 			return "memory";
   2953 		case section_global:
   2954 			return "global";
   2955 		case section_export:
   2956 			return "export";
   2957 		case section_start:
   2958 			return "start";
   2959 		case section_element:
   2960 			return "element";
   2961 		case section_code:
   2962 			return "code";
   2963 		case section_data:
   2964 			return "data";
   2965 		default:
   2966 			return "invalid";
   2967 	}
   2968 
   2969 }
   2970 
   2971 static int parse_section(struct wasm_parser *p)
   2972 {
   2973 	enum section_tag tag;
   2974 	struct section;
   2975 	u32 bytes;
   2976 
   2977 	if (!parse_section_tag(&p->cur, &tag)) {
   2978 		parse_err(p, "section tag");
   2979 		return 2;
   2980 	}
   2981 
   2982 	if (!parse_u32(&p->cur, &bytes)) {
   2983 		return parse_err(p, "section len");
   2984 	}
   2985 
   2986 	if (!parse_section_by_tag(p, tag, bytes)) {
   2987 		return parse_err(p, "%s (%d bytes)", section_str(tag), bytes);
   2988 	}
   2989 
   2990 	p->module.parsed |= 1 << tag;
   2991 
   2992 	return 1;
   2993 }
   2994 
   2995 static struct builtin *builtin_func(u32 ind)
   2996 {
   2997 	if (unlikely(ind >= NUM_BUILTINS)) {
   2998 		printf("UNUSUAL: invalid builtin index %d (max %d)\n", ind,
   2999 				NUM_BUILTINS-1);
   3000 		return NULL;
   3001 	}
   3002 	return &BUILTINS[ind];
   3003 }
   3004 
   3005 static const char *find_exported_function_name(struct module *module, u32 fn)
   3006 {
   3007 	u32 i;
   3008 	struct wexport *export;
   3009 
   3010 	if (!was_section_parsed(module, section_export))
   3011 		return NULL;
   3012 
   3013 	for (i = 0; i < module->export_section.num_exports; i++) {
   3014 		export = &module->export_section.exports[i];
   3015 		if (export->desc == export_func &&
   3016 		    export->index == fn) {
   3017 			return export->name;
   3018 		}
   3019 	}
   3020 
   3021 	return NULL;
   3022 }
   3023 
   3024 static const char *find_debug_function_name(struct module *module, u32 fn)
   3025 {
   3026 	u32 i;
   3027 	struct nameassoc *assoc;
   3028 
   3029 	if (!was_name_section_parsed(module, name_subsection_funcs))
   3030 		return NULL;
   3031 
   3032 	for (i = 0; i < module->name_section.func_names.num_names; i++) {
   3033 		assoc = &module->name_section.func_names.names[i];
   3034 		if (fn == assoc->index) {
   3035 			//debug("found fn debug name %d -> %s\n", fn, assoc->name);
   3036 			return assoc->name;
   3037 		}
   3038 	}
   3039 
   3040 	debug("fn %d debug name not found\n", fn);
   3041 
   3042 	return NULL;
   3043 }
   3044 
   3045 static const char *find_function_name(struct module *module, u32 fn)
   3046 {
   3047 	const char *name;
   3048 
   3049 	if ((name = find_exported_function_name(module, fn))) {
   3050 		return name;
   3051 	}
   3052 
   3053 	if ((name = find_debug_function_name(module, fn))) {
   3054 		return name;
   3055 	}
   3056 
   3057 	return "unknown";
   3058 }
   3059 
   3060 static int count_fn_locals(struct func *func)
   3061 {
   3062 	u32 i, num_locals = 0;
   3063 
   3064 	num_locals += func->functype->params.num_valtypes;
   3065 
   3066 	if (func->type == func_type_wasm) {
   3067 		// counts locals of the same type
   3068 		for (i = 0; i < func->wasm_func->num_local_defs; i++) {
   3069 			num_locals += func->wasm_func->local_defs[i].num_types;
   3070 		}
   3071 	}
   3072 
   3073 	return num_locals;
   3074 }
   3075 
   3076 static void make_builtin_func(struct func *func, const char *name,
   3077 		struct functype *type, struct builtin *builtin, u32 idx)
   3078 {
   3079 	func->name = name;
   3080 	func->builtin = builtin;
   3081 	func->functype = type;
   3082 	func->type = func_type_builtin;
   3083 	func->num_locals = count_fn_locals(func);
   3084 	func->idx = idx;
   3085 }
   3086 
   3087 static int make_func_lookup_table(struct wasm_parser *parser)
   3088 {
   3089 	u32 i, num_imports, num_func_imports, num_internal_funcs, typeidx, fn;
   3090 	struct import *import;
   3091 	struct importsec *imports;
   3092 	struct func *func;
   3093 	struct builtin *builtin;
   3094 
   3095 	fn = 0;
   3096 
   3097 	imports = &parser->module.import_section;
   3098 	num_func_imports = count_imported_functions(&parser->module);
   3099 	num_internal_funcs = count_internal_functions(&parser->module);
   3100 	parser->module.num_funcs = num_func_imports + num_internal_funcs;
   3101 
   3102 	if (!(parser->module.funcs =
   3103 		cursor_alloc(&parser->mem, sizeof(struct func) *
   3104 			     parser->module.num_funcs))) {
   3105 		return parse_err(parser, "oom");
   3106 	}
   3107 
   3108 	/* imports */
   3109 	num_imports = count_imports(&parser->module, NULL);
   3110 
   3111 	for (i = 0; i < num_imports; i++) {
   3112 		import = &imports->imports[i];
   3113 
   3114 		if (import->desc.type != import_func)
   3115 			continue;
   3116 
   3117 		func = &parser->module.funcs[fn++];
   3118 
   3119 		if (import->resolved_builtin == -1) {
   3120 			debug("warning: %s not resolved\n", func->name);
   3121 			builtin = NULL;
   3122 		} else {
   3123 			builtin = builtin_func(import->resolved_builtin);
   3124 		}
   3125 
   3126 		make_builtin_func(
   3127 			func,
   3128 			import->name,
   3129 			&parser->module.type_section.functypes[import->desc.typeidx],
   3130 			builtin,
   3131 			fn
   3132 			);
   3133 	}
   3134 
   3135 	/* module fns */
   3136 	for (i = 0; i < num_internal_funcs; i++, fn++) {
   3137 		func = &parser->module.funcs[fn];
   3138 
   3139 		typeidx = parser->module.func_section.type_indices[i];
   3140 		func->type = func_type_wasm;
   3141 		func->wasm_func = &parser->module.code_section.funcs[i];
   3142 		func->functype = &parser->module.type_section.functypes[typeidx];
   3143 		func->name = find_function_name(&parser->module, fn);
   3144 		func->num_locals = count_fn_locals(func);
   3145 		func->idx = fn;
   3146 	}
   3147 
   3148 	assert(fn == parser->module.num_funcs);
   3149 
   3150 	return 1;
   3151 }
   3152 
   3153 
   3154 int parse_wasm(struct wasm_parser *p)
   3155 {
   3156 	p->module.parsed = 0;
   3157 	p->module.custom_sections = 0;
   3158 
   3159 	if (!consume_bytes(&p->cur, WASM_MAGIC, sizeof(WASM_MAGIC))) {
   3160 		parse_err(p, "magic");
   3161 		goto fail;
   3162 	}
   3163 
   3164 	if (!consume_u32(&p->cur, WASM_VERSION)) {
   3165 		parse_err(p, "version");
   3166 		goto fail;
   3167 	}
   3168 
   3169 	while (1) {
   3170 		if (cursor_eof(&p->cur))
   3171 			break;
   3172 
   3173 		if (!parse_section(p)) {
   3174 			parse_err(p, "section");
   3175 			goto fail;
   3176 		}
   3177 	}
   3178 
   3179 	if (!make_func_lookup_table(p)) {
   3180 		return parse_err(p, "failed making func lookup table");
   3181 	}
   3182 
   3183 	//print_module(&p->module);
   3184 	debug("module parse success!\n\n");
   3185 	return 1;
   3186 
   3187 fail:
   3188 	debug("\npartially parsed module:\n");
   3189 	print_module(&p->module);
   3190 	debug("parse failure backtrace:\n");
   3191 	print_error_backtrace(&p->errs);
   3192 	return 0;
   3193 }
   3194 
   3195 static INLINE int interp_prep_binop(struct wasm_interp *interp, struct val *lhs,
   3196 		struct val *rhs, struct val *c, enum valtype typ)
   3197 {
   3198 	c->type = typ;
   3199 
   3200 	if (unlikely(!cursor_popval(&interp->stack, rhs)))
   3201 		return interp_error(interp, "couldn't pop first val");
   3202 
   3203 	if (unlikely(!cursor_popval(&interp->stack, lhs)))
   3204 		return interp_error(interp, "couldn't pop second val");
   3205 
   3206 	if (unlikely(lhs->type != typ || rhs->type != typ)) {
   3207 	        return interp_error(interp, "type mismatch, %s or %s != %s",
   3208 			valtype_name(lhs->type),
   3209 			valtype_name(rhs->type),
   3210 			valtype_name(typ));
   3211 	}
   3212 
   3213 	return 1;
   3214 }
   3215 
   3216 static INLINE int set_local(struct wasm_interp *interp, u32 ind,
   3217 			    struct val *val)
   3218 {
   3219 	struct callframe *frame;
   3220 	struct val *local;
   3221 
   3222 	if (unlikely(!(frame = top_callframe(&interp->callframes))))
   3223 		return interp_error(interp, "no callframe?");
   3224 
   3225 	if (unlikely(!(local = get_local(interp, ind))))
   3226 		return interp_error(interp, "no local?");
   3227 
   3228 	memcpy(local, val, sizeof(*val));
   3229 	return 1;
   3230 }
   3231 
   3232 static INLINE int interp_local_tee(struct wasm_interp *interp, u32 index)
   3233 {
   3234 	struct val *val;
   3235 
   3236 	if (unlikely(!(val = stack_topval(interp))))
   3237 		return interp_error(interp, "pop");
   3238 
   3239 	if (unlikely(!set_local(interp, index, val)))
   3240 		return interp_error(interp, "set local");
   3241 
   3242 	return 1;
   3243 }
   3244 
   3245 static int interp_local_set(struct wasm_interp *interp, u32 index)
   3246 {
   3247 	struct val val;
   3248 
   3249 	if (unlikely(!interp_local_tee(interp, index)))
   3250 		return interp_error(interp, "tee set");
   3251 
   3252 	if (unlikely(!stack_popval(interp, &val)))
   3253 		return interp_error(interp, "pop");
   3254 
   3255 	return 1;
   3256 }
   3257 
   3258 static INLINE int interp_local_get(struct wasm_interp *interp, u32 index)
   3259 {
   3260 	struct val *val;
   3261 
   3262 	if (unlikely(!(val = get_local(interp, index)))) {
   3263 		return interp_error(interp, "get local");
   3264 	}
   3265 
   3266 	return stack_pushval(interp, val);
   3267 }
   3268 
   3269 static INLINE void make_i64_val(struct val *val, s64 v)
   3270 {
   3271 	val->type = val_i64;
   3272 	val->num.i64 = v;
   3273 }
   3274 
   3275 static INLINE int interp_i64_xor(struct wasm_interp *interp)
   3276 {
   3277 	struct val lhs, rhs, c;
   3278 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   3279 		return interp_error(interp, "binop prep");
   3280 	c.num.i64 = lhs.num.i64 ^ rhs.num.i64;
   3281 	return stack_pushval(interp, &c);
   3282 }
   3283 
   3284 static INLINE int interp_f32_min(struct wasm_interp *interp)
   3285 {
   3286 	struct val lhs, rhs, c;
   3287 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_f32)))
   3288 		return interp_error(interp, "binop prep");
   3289 	c.num.f32 = lhs.num.f32 < rhs.num.f32 ? lhs.num.f32 : rhs.num.f32;
   3290 	return stack_pushval(interp, &c);
   3291 }
   3292 
   3293 static INLINE int interp_f32_max(struct wasm_interp *interp)
   3294 {
   3295 	struct val lhs, rhs, c;
   3296 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_f32)))
   3297 		return interp_error(interp, "binop prep");
   3298 	c.num.f32 = lhs.num.f32 > rhs.num.f32 ? lhs.num.f32 : rhs.num.f32;
   3299 	return stack_pushval(interp, &c);
   3300 }
   3301 
   3302 static INLINE int interp_i64_div_u(struct wasm_interp *interp)
   3303 {
   3304 	struct val lhs, rhs, c;
   3305 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   3306 		return interp_error(interp, "binop prep");
   3307 	if (rhs.num.u64 == 0)
   3308 		return interp_error(interp, "congrats, you divided by zero");
   3309 	c.num.u64 = lhs.num.u64 / rhs.num.u64;
   3310 	return stack_pushval(interp, &c);
   3311 }
   3312 
   3313 static int interp_i64_eqz(struct wasm_interp *interp)
   3314 {
   3315 	struct val a, res;
   3316 	if (unlikely(!stack_pop_valtype(interp, val_i64, &a)))
   3317 		return interp_error(interp, "pop val");
   3318 	res.type = val_i32;
   3319 	res.num.u32 = a.num.i64 == 0;
   3320 	return cursor_pushval(&interp->stack, &res);
   3321 }
   3322 
   3323 static INLINE int interp_f32_sqrt(struct wasm_interp *interp)
   3324 {
   3325 	struct val *val;
   3326 	if (unlikely(!(val = stack_top_f32(interp))))
   3327 		return interp_error(interp, "pop");
   3328 	val->num.f32 = sqrt(val->num.f32);
   3329 	return 1;
   3330 }
   3331 
   3332 static INLINE int interp_f64_sqrt(struct wasm_interp *interp)
   3333 {
   3334 	struct val *val;
   3335 	if (unlikely(!(val = stack_top_f64(interp))))
   3336 		return interp_error(interp, "pop");
   3337 	val->num.f64 = sqrt(val->num.f64);
   3338 	return 1;
   3339 }
   3340 
   3341 static INLINE int interp_f64_floor(struct wasm_interp *interp)
   3342 {
   3343 	struct val *val;
   3344 	if (unlikely(!(val = stack_top_f64(interp))))
   3345 		return interp_error(interp, "pop");
   3346 	val->num.f64 = floor(val->num.f64);
   3347 	return 1;
   3348 }
   3349 
   3350 static INLINE int interp_f64_ceil(struct wasm_interp *interp)
   3351 {
   3352 	struct val *val;
   3353 	if (unlikely(!(val = stack_top_f64(interp))))
   3354 		return interp_error(interp, "pop");
   3355 	val->num.f64 = ceil(val->num.f64);
   3356 	return 1;
   3357 }
   3358 
   3359 static INLINE int interp_f32_abs(struct wasm_interp *interp)
   3360 {
   3361 	struct val *val;
   3362 	if (unlikely(!(val = stack_top_f32(interp))))
   3363 		return interp_error(interp, "pop");
   3364 	if (val->num.f32 >= 0)
   3365 		return 1;
   3366 	val->num.f32 = -val->num.f32;
   3367 	return 1;
   3368 }
   3369 
   3370 static INLINE int interp_f64_neg(struct wasm_interp *interp)
   3371 {
   3372 	struct val *val;
   3373 	if (unlikely(!(val = stack_top_f64(interp))))
   3374 		return interp_error(interp, "pop");
   3375 	val->num.f64 = -val->num.f64;
   3376 	return 1;
   3377 }
   3378 
   3379 static INLINE int interp_f64_abs(struct wasm_interp *interp)
   3380 {
   3381 	struct val *val;
   3382 	if (unlikely(!(val = stack_top_f64(interp))))
   3383 		return interp_error(interp, "pop");
   3384 	if (val->num.f64 >= 0)
   3385 		return 1;
   3386 	val->num.f64 = -val->num.f64;
   3387 	return 1;
   3388 }
   3389 
   3390 static INLINE int interp_f64_div(struct wasm_interp *interp)
   3391 {
   3392 	struct val lhs, rhs, c;
   3393 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_f64)))
   3394 		return interp_error(interp, "binop prep");
   3395 	if (rhs.num.f64 == 0)
   3396 		return interp_error(interp, "congrats, you divided by zero");
   3397 	c.num.f64 = lhs.num.f64 / rhs.num.f64;
   3398 	return stack_pushval(interp, &c);
   3399 }
   3400 
   3401 static INLINE int interp_f32_div(struct wasm_interp *interp)
   3402 {
   3403 	struct val lhs, rhs, c;
   3404 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_f32)))
   3405 		return interp_error(interp, "binop prep");
   3406 	if (rhs.num.f32 == 0)
   3407 		return interp_error(interp, "congrats, you divided by zero");
   3408 	c.num.f32 = lhs.num.f32 / rhs.num.f32;
   3409 	return stack_pushval(interp, &c);
   3410 }
   3411 
   3412 static INLINE int interp_i32_div_s(struct wasm_interp *interp)
   3413 {
   3414 	struct val lhs, rhs, c;
   3415 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3416 		return interp_error(interp, "binop prep");
   3417 	if (rhs.num.i32 == 0)
   3418 		return interp_error(interp, "congrats, you divided by zero");
   3419 	c.num.i32 = lhs.num.i32 / rhs.num.i32;
   3420 	return stack_pushval(interp, &c);
   3421 }
   3422 
   3423 static INLINE int interp_i32_div_u(struct wasm_interp *interp)
   3424 {
   3425 	struct val lhs, rhs, c;
   3426 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3427 		return interp_error(interp, "binop prep");
   3428 	if (rhs.num.u32 == 0)
   3429 		return interp_error(interp, "congrats, you divided by zero");
   3430 	c.num.u32 = lhs.num.u32 / rhs.num.u32;
   3431 	return stack_pushval(interp, &c);
   3432 }
   3433 
   3434 const unsigned int ROTMASK = (CHAR_BIT*sizeof(uint32_t) - 1);  // assumes width is a power of 2.
   3435 
   3436 static inline uint32_t rotl32 (uint32_t n, unsigned int c)
   3437 {
   3438 	return (n << shiftmask32(c)) | (n >> shiftmask32(0 - c));
   3439 }
   3440 
   3441 static inline uint32_t rotr32 (uint32_t n, unsigned int c)
   3442 {
   3443 	return (n >> shiftmask32(c)) | (n << shiftmask32(0 - c));
   3444 }
   3445 
   3446 static INLINE int interp_i32_rotr(struct wasm_interp *interp)
   3447 {
   3448 	struct val lhs, rhs, c;
   3449 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3450 		return interp_error(interp, "binop prep");
   3451 	c.num.u32 = rotr32(lhs.num.u32, rhs.num.u32);
   3452 	return stack_pushval(interp, &c);
   3453 }
   3454 
   3455 static INLINE int interp_i32_rotl(struct wasm_interp *interp)
   3456 {
   3457 	struct val lhs, rhs, c;
   3458 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3459 		return interp_error(interp, "binop prep");
   3460 	c.num.u32 = rotl32(lhs.num.u32, rhs.num.u32);
   3461 	return stack_pushval(interp, &c);
   3462 }
   3463 
   3464 static INLINE int interp_i64_const(struct wasm_interp *interp, s64 c)
   3465 {
   3466 	struct val val;
   3467 	make_i64_val(&val, c);
   3468 	return cursor_pushval(&interp->stack, &val);
   3469 }
   3470 
   3471 static INLINE int interp_i32_const(struct wasm_interp *interp, u32 c)
   3472 {
   3473 	struct val val;
   3474 	make_i32_val(&val, c);
   3475 	return cursor_pushval(&interp->stack, &val);
   3476 }
   3477 
   3478 static INLINE int interp_f64_const(struct wasm_interp *interp, double c)
   3479 {
   3480 	struct val val;
   3481 	make_f64_val(&val, c);
   3482 	return stack_pushval(interp, &val);
   3483 }
   3484 
   3485 static INLINE int interp_i32_and(struct wasm_interp *interp)
   3486 {
   3487 	struct val lhs, rhs, c;
   3488 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3489 		return interp_error(interp, "binop prep");
   3490 	return stack_push_i32(interp, lhs.num.u32 & rhs.num.u32);
   3491 }
   3492 
   3493 static INLINE int interp_i64_and(struct wasm_interp *interp)
   3494 {
   3495 	struct val lhs, rhs, c;
   3496 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   3497 		return interp_error(interp, "binop prep");
   3498 	return stack_push_i64(interp, lhs.num.u64 & rhs.num.u64);
   3499 }
   3500 
   3501 
   3502 #define BINOP(type, name, op) \
   3503 static INLINE int interp_##type##_##name(struct wasm_interp *interp) \
   3504 { \
   3505 	struct val lhs, rhs, c; \
   3506 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_##type))) \
   3507 		return interp_error(interp, "binop prep"); \
   3508 	c.num.type = lhs.num.type op rhs.num.type; \
   3509 	return stack_pushval(interp, &c); \
   3510 }
   3511 
   3512 #define BINOP2(type, optype, name, op) \
   3513 static INLINE int interp_##type##_##name(struct wasm_interp *interp) \
   3514 { \
   3515 	struct val lhs, rhs, c; \
   3516 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_##type))) \
   3517 		return interp_error(interp, "binop prep"); \
   3518 	return stack_push_i32(interp, lhs.num.optype op rhs.num.optype); \
   3519 }
   3520 
   3521 BINOP(f64, mul, *)
   3522 BINOP(f32, mul, *)
   3523 BINOP(i32, mul, *)
   3524 BINOP(i64, mul, *)
   3525 
   3526 BINOP(f64, sub, -)
   3527 BINOP(f32, sub, -)
   3528 BINOP(i32, sub, -)
   3529 BINOP(i64, sub, -)
   3530 
   3531 BINOP(f64, add, +)
   3532 BINOP(f32, add, +)
   3533 BINOP(i32, add, +)
   3534 BINOP(i64, add, +)
   3535 
   3536 BINOP(i32, or, |)
   3537 BINOP(i64, or, |)
   3538 
   3539 BINOP2(i32, i32, lt_s, <)
   3540 BINOP2(i64, i64, lt_s, <)
   3541 BINOP2(i32, u32, lt_u, <)
   3542 BINOP2(i64, u64, lt_u, <)
   3543 BINOP2(f32, f32, lt, <)
   3544 BINOP2(f64, f64, lt, <)
   3545 
   3546 BINOP2(i32, i32, gt_s, >)
   3547 BINOP2(i64, i64, gt_s, >)
   3548 BINOP2(i32, u32, gt_u, >)
   3549 BINOP2(i64, u64, gt_u, >)
   3550 BINOP2(f32, f32, gt, >)
   3551 BINOP2(f64, f64, gt, >)
   3552 
   3553 BINOP2(i32, i32, le_s, <=)
   3554 BINOP2(i64, i64, le_s, <=)
   3555 BINOP2(i32, u32, le_u, <=)
   3556 BINOP2(i64, u64, le_u, <=)
   3557 BINOP2(f32, f32, le, <=)
   3558 BINOP2(f64, f64, le, <=)
   3559 
   3560 BINOP2(i32, i32, ge_s, >=)
   3561 BINOP2(i64, i64, ge_s, >=)
   3562 BINOP2(i32, u32, ge_u, >=)
   3563 BINOP2(i64, u64, ge_u, >=)
   3564 BINOP2(f32, f32, ge, >=)
   3565 BINOP2(f64, f64, ge, >=)
   3566 
   3567 BINOP2(f32, f32, eq, ==)
   3568 BINOP2(f64, f64, eq, ==)
   3569 BINOP2(f32, f32, ne, !=)
   3570 BINOP2(f64, f64, ne, !=)
   3571 
   3572 static int interp_i32_rem_s(struct wasm_interp *interp)
   3573 {
   3574     struct val lhs, rhs, c;
   3575     if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3576         return interp_error(interp, "binop prep");
   3577     c.num.i32 = lhs.num.i32 % rhs.num.i32;
   3578     return stack_pushval(interp, &c);
   3579 }
   3580 
   3581 static int interp_i32_rem_u(struct wasm_interp *interp)
   3582 {
   3583     struct val lhs, rhs, c;
   3584     if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   3585         return interp_error(interp, "binop prep");
   3586     c.num.u32 = lhs.num.u32 % rhs.num.u32;
   3587     return stack_pushval(interp, &c);
   3588 }
   3589 
   3590 
   3591 static INLINE int interp_f32_const(struct wasm_interp *interp, float c)
   3592 {
   3593 	struct val val;
   3594 	make_f32_val(&val, c);
   3595 	return cursor_pushval(&interp->stack, &val);
   3596 }
   3597 
   3598 static INLINE int interp_f32_neg(struct wasm_interp *interp)
   3599 {
   3600 	struct val *val;
   3601 	if (unlikely(!(val = stack_top_f32(interp))))
   3602 		return interp_error(interp, "pop");
   3603 	val->num.f32 = -val->num.f32;
   3604 	return 1;
   3605 }
   3606 
   3607 static INLINE int interp_f32_reinterpret_i32(struct wasm_interp *interp)
   3608 {
   3609 	struct val *val;
   3610 	if (unlikely(!(val = stack_top_i32(interp))))
   3611 		return interp_error(interp, "pop");
   3612 	val->type = val_f32;
   3613 	return 1;
   3614 }
   3615 
   3616 static INLINE int interp_f64_convert_i32_u(struct wasm_interp *interp)
   3617 {
   3618 	struct val *val;
   3619 	if (unlikely(!(val = stack_top_i32(interp))))
   3620 		return interp_error(interp, "pop");
   3621 	make_f64_val(val, (double)val->num.i32);
   3622 	return 1;
   3623 }
   3624 
   3625 static INLINE int interp_i32_trunc_f64_u(struct wasm_interp *interp)
   3626 {
   3627 	struct val *val;
   3628 	if (unlikely(!(val = stack_top_f64(interp))))
   3629 		return interp_error(interp, "pop");
   3630 	make_i32_val(val, (u32)val->num.f64);
   3631 	return 1;
   3632 }
   3633 
   3634 static INLINE int interp_f32_convert_i32_u(struct wasm_interp *interp)
   3635 {
   3636 	struct val *val;
   3637 	if (unlikely(!(val = stack_top_i32(interp))))
   3638 		return interp_error(interp, "pop");
   3639 	make_f32_val(val, (float)val->num.u32);
   3640 	return 1;
   3641 }
   3642 
   3643 static INLINE int interp_i32_trunc_f32_s(struct wasm_interp *interp)
   3644 {
   3645 	struct val *val;
   3646 	if (unlikely(!(val = stack_top_f32(interp))))
   3647 		return interp_error(interp, "pop");
   3648 	make_i32_val(val, (int)val->num.f32);
   3649 	return 1;
   3650 }
   3651 
   3652 static INLINE int interp_f64_reinterpret_i64(struct wasm_interp *interp)
   3653 {
   3654 	struct val *val;
   3655 	if (unlikely(!(val = stack_top_i64(interp))))
   3656 		return interp_error(interp, "pop");
   3657 	val->type = val_f64;
   3658 
   3659 	return 1;
   3660 }
   3661 
   3662 static INLINE int interp_i64_reinterpret_f64(struct wasm_interp *interp)
   3663 {
   3664 	struct val *val;
   3665 	if (unlikely(!(val = stack_top_f64(interp))))
   3666 		return interp_error(interp, "pop");
   3667 	val->type = val_i64;
   3668 	return 1;
   3669 }
   3670 
   3671 static INLINE int interp_f64_convert_i64_u(struct wasm_interp *interp)
   3672 {
   3673 	struct val *val;
   3674 	if (unlikely(!(val = stack_top_i64(interp))))
   3675 		return interp_error(interp, "pop");
   3676 	make_f64_val(val, (double)val->num.u64);
   3677 	return 1;
   3678 }
   3679 
   3680 static INLINE int interp_f64_convert_i32_s(struct wasm_interp *interp)
   3681 {
   3682 	struct val *val;
   3683 	if (unlikely(!(val = stack_top_i32(interp))))
   3684 		return interp_error(interp, "pop");
   3685 	make_f64_val(val, (double)val->num.i32);
   3686 	return 1;
   3687 }
   3688 
   3689 static INLINE int interp_f32_demote_f64(struct wasm_interp *interp)
   3690 {
   3691 	struct val *val;
   3692 	if (unlikely(!(val = stack_top_f64(interp))))
   3693 		return interp_error(interp, "pop");
   3694 	make_f32_val(val, (float)val->num.f64);
   3695 	return 1;
   3696 }
   3697 
   3698 static INLINE int interp_i32_trunc_f64_s(struct wasm_interp *interp)
   3699 {
   3700 	struct val *val;
   3701 	if (unlikely(!(val = stack_top_f64(interp))))
   3702 		return interp_error(interp, "pop");
   3703 	make_i32_val(val, (int)val->num.f64);
   3704 	return 1;
   3705 }
   3706 
   3707 static INLINE int interp_f64_promote_f32(struct wasm_interp *interp)
   3708 {
   3709 	struct val *val;
   3710 	if (unlikely(!(val = stack_top_f32(interp))))
   3711 		return interp_error(interp, "pop");
   3712 	make_f64_val(val, (double)val->num.f32);
   3713 	return 1;
   3714 }
   3715 
   3716 static INLINE int interp_i32_reinterpret_f32(struct wasm_interp *interp)
   3717 {
   3718 	struct val *val;
   3719 	if (unlikely(!(val = stack_top_f32(interp))))
   3720 		return interp_error(interp, "pop");
   3721 	val->type = val_i32;
   3722 	return 1;
   3723 }
   3724 
   3725 static INLINE int interp_f32_convert_i32_s(struct wasm_interp *interp)
   3726 {
   3727 	float f;
   3728 	struct val *val;
   3729 	if (unlikely(!(val = stack_top_i32(interp))))
   3730 		return interp_error(interp, "pop");
   3731 	f = (float)val->num.i32;
   3732 	make_f32_val(val, f);
   3733 	return 1;
   3734 }
   3735 
   3736 static INLINE int count_local_resolvers(struct wasm_interp *interp, int *count)
   3737 {
   3738 	int offset;
   3739 	u8 *p;
   3740 	*count = 0;
   3741 	if (unlikely(!cursor_top_int(&interp->resolver_offsets, &offset))) {
   3742 		return interp_error(interp, "no top resolver offset?");
   3743 	}
   3744 	p = interp->resolver_stack.start + offset * sizeof(struct resolver);
   3745 	if (unlikely(p < interp->resolver_stack.start ||
   3746 		     p >= interp->resolver_stack.end)) {
   3747 		return interp_error(interp, "resolver offset oob?");
   3748 	}
   3749 	*count = (interp->resolver_stack.p - p) / sizeof(struct resolver);
   3750 	//debug("offset %d count %d stack.p - p %ld\n", offset, *count, interp->resolver_stack.p - p);
   3751 	return 1;
   3752 }
   3753 
   3754 static INLINE u32 count_stack_vals(struct cursor *stack)
   3755 {
   3756 	return cursor_count(stack, sizeof(struct val));
   3757 }
   3758 
   3759 static INLINE int drop_callframe_return(struct wasm_interp *interp, int returning)
   3760 {
   3761 	int offset, drop;
   3762 	u32 cnt;
   3763 	struct callframe *frame;
   3764 	struct func *func;
   3765 
   3766 #ifdef DEBUG
   3767 	int count, from_fn, to_fn;
   3768 	const char *from, *to;
   3769 
   3770 	if (unlikely(!count_local_resolvers(interp, &count))) {
   3771 		return interp_error(interp, "count local resolvers");
   3772 	}
   3773 
   3774 	if (unlikely(count != 0)) {
   3775 		return interp_error(interp, "unclean callframe drop, still have"
   3776 				" %d unpopped labels", count);
   3777 	}
   3778 
   3779 	frame = top_callframe(&interp->callframes);
   3780 	if (!frame) {
   3781 		from = "(aux)";
   3782 		from_fn = -1;
   3783 	} else {
   3784 		from = get_function_name(interp->module, frame->func->idx);
   3785 		from_fn = frame->func->idx;
   3786 	}
   3787 
   3788 	if (!(frame = top_callframes(&interp->callframes, 1))) {
   3789 		to = "(aux)";
   3790 		to_fn = -1;
   3791 	} else {
   3792 		to = get_function_name(interp->module, frame->func->idx);
   3793 		to_fn = frame->func->idx;
   3794 	}
   3795 #endif
   3796 	frame = top_callframe(&interp->callframes);
   3797 	func = frame->func;
   3798 
   3799 	if (unlikely(!cursor_popint(&interp->resolver_offsets, &offset)))
   3800 		return interp_error(interp, "pop resolver_offsets");
   3801 
   3802 	cnt = count_stack_vals(&interp->stack);
   3803 
   3804 	if (returning)  {
   3805 		drop = cnt - frame->prev_stack_items - 
   3806 				func->functype->result.num_valtypes;
   3807 		if (drop > 0 &&
   3808 		    !cursor_dropn(&interp->stack, sizeof(struct val), drop)) {
   3809 			return interp_error(interp,
   3810 				"error dropping extra stack values in return. "
   3811 				"drop:%d vals:%d prev:%d ret:%d",
   3812 				drop, cnt, frame->prev_stack_items,
   3813 				func->functype->result.num_valtypes);
   3814 		}
   3815 
   3816 	} else if (unlikely(cnt - frame->prev_stack_items !=
   3817 				func->functype->result.num_valtypes)) {
   3818 		return interp_error(interp,
   3819 				"%s:%d extra values on stack: have %d-prev:%d=%d, expected %d",
   3820 				func->name, frame->func->idx, cnt,
   3821 				frame->prev_stack_items,
   3822 				cnt - frame->prev_stack_items,
   3823 				func->functype->result.num_valtypes);
   3824 	}
   3825 
   3826 	// free frame locals
   3827 	interp->locals.p = (u8*)frame->locals;
   3828 
   3829 	debug("returning from %s:%d to %s:%d\n", from, from_fn, to, to_fn);
   3830 
   3831 	return cursor_drop_callframe(&interp->callframes);
   3832 }
   3833 
   3834 static INLINE int drop_callframe(struct wasm_interp *interp)
   3835 {
   3836 	return drop_callframe_return(interp, 1);
   3837 }
   3838 
   3839 static void make_default_val(struct val *val)
   3840 {
   3841 	switch (val->type) {
   3842 	case val_i32:
   3843 		val->num.i32 = 0;
   3844 		break;
   3845 	case val_i64:
   3846 		val->num.i64 = 0;
   3847 		break;
   3848 	case val_f32:
   3849 		val->num.f32 = 0.0;
   3850 		break;
   3851 	case val_f64:
   3852 		val->num.f64 = 0.0;
   3853 		break;
   3854 	case val_ref_null:
   3855 	case val_ref_func:
   3856 	case val_ref_extern:
   3857 		val->ref.addr = 0;
   3858 		break;
   3859 	}
   3860 }
   3861 
   3862 static struct val *alloc_frame_locals(struct wasm_interp *interp,
   3863 		struct func *func)
   3864 {
   3865 	struct val *locals;
   3866 	u32 size;
   3867 
   3868 	size = func->num_locals * sizeof(struct val);
   3869 
   3870 	if (!(locals = cursor_malloc(&interp->locals, size))) {
   3871 		debug("alloc_locals err size %d\n", size);
   3872 		interp_error(interp, "could not alloc locals for %s",
   3873 				func->name);
   3874 		return NULL;
   3875 	}
   3876 
   3877 	return locals;
   3878 }
   3879 
   3880 static int prepare_call(struct wasm_interp *interp, struct func *func,
   3881 		struct val **locals, int *prev_items)
   3882 {
   3883 	static char buf[128];
   3884 	struct val *local;
   3885 	struct val val;
   3886 	u32 i, j, ind;
   3887 
   3888 	*prev_items = count_stack_vals(&interp->stack);
   3889 
   3890 	if (!(*locals = alloc_frame_locals(interp, func)))
   3891 		return interp_error(interp, "locals stack oom");
   3892 
   3893 	debug("new stack size %ld/%ld (%f%%)\n",
   3894 			((u8*)*locals) - interp->locals.start,
   3895 			interp->locals.end - interp->locals.start,
   3896 			100.0*((double)(((u8*)*locals) - interp->locals.start)/
   3897 			  (double)(interp->locals.end - interp->locals.start)));
   3898 
   3899 	/* push params as locals */
   3900 	for (i = 0; i < func->functype->params.num_valtypes; i++) {
   3901 		*prev_items = *prev_items - 1;
   3902 
   3903 		ind = func->functype->params.num_valtypes-1-i;
   3904 		local = &(*locals)[ind];
   3905 		local->type = (enum valtype)func->functype->params.valtypes[ind];
   3906 		//ind = i;
   3907 
   3908 		if (unlikely(!cursor_popval(&interp->stack, &val))) {
   3909 			return interp_error(interp,
   3910 				"not enough arguments for call to %s: [%s], needed %d args, got %d",
   3911 				func->name,
   3912 				functype_str(func->functype, buf, sizeof(buf)),
   3913 				func->functype->params.num_valtypes,
   3914 				ind);
   3915 		}
   3916 
   3917 		if (unlikely(val.type != local->type)) {
   3918 			return interp_error(interp,
   3919 				"call parameter %d type mismatch. got %s, expected %s",
   3920 				ind+1,
   3921 				valtype_name(val.type),
   3922 				valtype_name(local->type));
   3923 		}
   3924 
   3925 #ifdef DEBUG
   3926 		debug("setting param %d (%s) to ",
   3927 				ind, valtype_name(local->type));
   3928 		print_val(&val); printf("\n");
   3929 #endif
   3930 		memcpy(local, &val, sizeof(struct val));
   3931 	}
   3932 
   3933 	if (func->type == func_type_builtin)
   3934 		return 1;
   3935 
   3936 	ind = i;
   3937 
   3938 	for (i = 0; i < func->wasm_func->num_local_defs; i++) {
   3939 	for (j = 0; j < func->wasm_func->local_defs[i].num_types; j++, ind++) {
   3940 		assert(ind < func->num_locals);
   3941 		local = (*locals) + ind;
   3942 
   3943 		debug("initializing local %d to type %s\n",
   3944 			ind-func->functype->params.num_valtypes,
   3945 			valtype_name(func->wasm_func->local_defs[i].type));
   3946 
   3947 		local->type = func->wasm_func->local_defs[i].type;
   3948 		make_default_val(local);
   3949 	}
   3950 	}
   3951 
   3952 	return 1;
   3953 }
   3954 
   3955 static INLINE int call_wasm_func(struct wasm_interp *interp, struct func *func)
   3956 {
   3957 	struct callframe callframe;
   3958 	struct val *locals;
   3959 	int prev_items;
   3960 
   3961 	if (!prepare_call(interp, func, &locals, &prev_items))
   3962 		return interp_error(interp, "prepare args");
   3963 
   3964 	/* update current function and push it to the callframe as well */
   3965 	make_cursor(func->wasm_func->code.code,
   3966 			func->wasm_func->code.code + func->wasm_func->code.code_len,
   3967 			&callframe.code);
   3968 
   3969 	callframe.func = func;
   3970 	callframe.locals = locals;
   3971 	callframe.prev_stack_items = prev_items;
   3972 
   3973 	assert(func->wasm_func->code.code_len > 0);
   3974 
   3975 	if (unlikely(!push_callframe(interp, &callframe)))
   3976 		return interp_error(interp, "push callframe");
   3977 
   3978 	/*
   3979 	if (unlikely(!interp_code(interp))) {
   3980 		return interp_error(interp, "call %s:%d",
   3981 				get_function_name(interp->module, fn),
   3982 				fn);
   3983 	}
   3984 
   3985 	if (unlikely(!drop_callframe(interp)))
   3986 		return interp_error(interp, "drop callframe");
   3987 	*/
   3988 
   3989 	return 1;
   3990 }
   3991 
   3992 static INLINE int call_builtin_func(struct wasm_interp *interp, struct func *func)
   3993 {
   3994 	struct callframe callframe = {};
   3995 	struct val *locals;
   3996 	int prev_items;
   3997 
   3998 	if (!prepare_call(interp, func, &locals, &prev_items))
   3999 		return interp_error(interp, "prepare args");
   4000 
   4001 	/* update current function and push it to the callframe as well */
   4002 	callframe.func = func;
   4003 	callframe.locals = locals;
   4004 	callframe.prev_stack_items = prev_items;
   4005 
   4006 	if (unlikely(!push_callframe(interp, &callframe)))
   4007 		return interp_error(interp, "oob cursor_pushcode");
   4008 
   4009 	if (!func->builtin->fn(interp))
   4010 		return interp_error(interp, "builtin trap");
   4011 
   4012 	if (unlikely(!drop_callframe(interp)))
   4013 		return interp_error(interp, "pop callframe");
   4014 
   4015 	return 1;
   4016 }
   4017 
   4018 static INLINE int call_func(struct wasm_interp *interp, struct func *func)
   4019 {
   4020 	switch (func->type) {
   4021 	case func_type_wasm:
   4022 		return call_wasm_func(interp, func);
   4023 	case func_type_builtin:
   4024 		if (func->builtin == NULL) {
   4025 			return interp_error(interp,
   4026 					"attempted to call unresolved fn: %s",
   4027 					func->name);
   4028 		}
   4029 		return call_builtin_func(interp, func);
   4030 	}
   4031 	return interp_error(interp, "corrupt func type: %02x", func->type);
   4032 }
   4033 
   4034 
   4035 static int call_function(struct wasm_interp *interp, int func_index)
   4036 {
   4037 	struct func *func;
   4038 
   4039 	debug("calling %s:%d\n", get_function_name(interp->module, func_index), func_index);
   4040 
   4041 	if (unlikely(!(func = get_fn(interp->module, func_index)))) {
   4042 		return interp_error(interp,
   4043 				"function %s (%d) not found (%d funcs)",
   4044 				get_function_name(interp->module, func_index),
   4045 				func_index,
   4046 				interp->module->code_section.num_funcs);
   4047 	}
   4048 
   4049 	return call_func(interp, func);
   4050 }
   4051 
   4052 static int interp_call(struct wasm_interp *interp, int func_index)
   4053 {
   4054 #ifdef DEBUG
   4055 	struct callframe prev_frame;
   4056 
   4057 	assert(top_callframe(&interp->callframes));
   4058 	memcpy(&prev_frame, top_callframe(&interp->callframes), sizeof(struct callframe));
   4059 #endif
   4060 
   4061 	if (unlikely(!call_function(interp, func_index)))
   4062 		return 0;
   4063 
   4064 	/*
   4065 	debug("returning from %s:%d to %s:%d\n",
   4066 			get_function_name(interp->module, func_index),
   4067 			func_index,
   4068 			get_function_name(interp->module, prev_frame.fn),
   4069 			prev_frame.fn);
   4070 			*/
   4071 
   4072 	return 1;
   4073 }
   4074 
   4075 static int interp_call_indirect(struct wasm_interp *interp, struct call_indirect *call)
   4076 {
   4077 	static char buf[128];
   4078 	static char buf2[128];
   4079 	struct functype *type;
   4080 	struct func *func, pfunc;
   4081 	struct table_inst *table;
   4082 	struct builtin *builtin;
   4083 	struct refval *ref;
   4084 	u32 ftidx;
   4085 	int i;
   4086 
   4087 	if (unlikely(!was_section_parsed(interp->module, section_table))) {
   4088 		return interp_error(interp, "no table section");
   4089 	}
   4090 
   4091 	if (unlikely(call->tableidx >= interp->module_inst.num_tables)) {
   4092 		return interp_error(interp, "invalid table index %d (max %d)",
   4093 				call->tableidx,
   4094 				interp->module_inst.num_tables-1);
   4095 	}
   4096 
   4097 	if (unlikely(call->typeidx >=
   4098 		     interp->module->type_section.num_functypes)) {
   4099 		return interp_error(interp, "invalid function type index: %d (max %d)",
   4100 			call->typeidx,
   4101 			interp->module->type_section.num_functypes);
   4102 	}
   4103 
   4104 	table = &interp->module_inst.tables[call->tableidx];
   4105 	type = &interp->module->type_section.functypes[call->typeidx];
   4106 
   4107 	if (unlikely(table->reftype != funcref)) {
   4108 		return interp_error(interp,
   4109 				"table[%d] is not a function reference table",
   4110 				call->tableidx
   4111 				);
   4112 	}
   4113 
   4114 	if (unlikely(!stack_pop_i32(interp, &i))) {
   4115 		return interp_error(interp, "pop i32");
   4116 	}
   4117 
   4118 	if (unlikely(i < 0 || i >= (int)table->num_refs)) {
   4119 		return interp_error(interp, "invalid index %d in table %d (max %d)",
   4120 				i, call->tableidx, table->num_refs-1);
   4121 	}
   4122 
   4123 	ref = &table->refs[i];
   4124 
   4125 	if (ref->addr == 0) {
   4126 		return interp_error(interp, "null ref in index %d of table %d",
   4127 				i, call->tableidx);
   4128 	}
   4129 
   4130 	// HACKY special case for indirect host builtins
   4131 	i = -((int)ref->addr);
   4132 	if (-i < 0 && i < NUM_BUILTINS) {
   4133 		builtin = &BUILTINS[i];
   4134 		make_builtin_func(&pfunc, builtin->name, type, builtin, -i);
   4135 		debug("calling indirect builtin %s\n", pfunc.name);
   4136 		return call_builtin_func(interp, &pfunc);
   4137 	}
   4138 
   4139 	func = &interp->module->funcs[ref->addr];
   4140 
   4141 	if (func->functype != type) {
   4142 		ftidx = (func->functype -
   4143 			 interp->module->type_section.functypes
   4144 			) / sizeof(struct functype);
   4145 
   4146 		return interp_error(interp,
   4147 				"functype mismatch, expected %d `%s`, got %d `%s`",
   4148 				ftidx,
   4149 				functype_str(func->functype, buf, sizeof(buf)),
   4150 				call->typeidx,
   4151 				functype_str(type, buf2, sizeof(buf2)),
   4152 				ref, interp->module->num_funcs-1);
   4153 	}
   4154 
   4155 	debug("calling %s:%d indirectly\n",
   4156 			get_function_name(interp->module, ref->addr),
   4157 			ref->addr);
   4158 
   4159 	return interp_call(interp, ref->addr);
   4160 }
   4161 
   4162 static int parse_blocktype(struct cursor *cur, struct errors *errs, struct blocktype *blocktype)
   4163 {
   4164 	unsigned char byte;
   4165 
   4166 	if (unlikely(!pull_byte(cur, &byte))) {
   4167 		return note_error(errs, cur, "parse_blocktype: oob\n");
   4168 	}
   4169 
   4170 	if (byte == 0x40) {
   4171 		blocktype->tag = blocktype_empty;
   4172 	} else if (is_valtype(byte)) {
   4173 		blocktype->tag = blocktype_valtype;
   4174 		blocktype->valtype = (enum valtype)byte;
   4175 	} else {
   4176 		blocktype->tag = blocktype_index;
   4177 		cur->p--;
   4178 
   4179 		if (!parse_int(cur, &blocktype->type_index))
   4180 			return note_error(errs, cur, "parse_blocktype: read type_index\n");
   4181 	}
   4182 
   4183 	return 1;
   4184 }
   4185 
   4186 static INLINE struct label *index_label(struct cursor *a, u32 fn, u32 ind)
   4187 {
   4188 	return index_cursor(a, ((MAX_LABELS * fn) + ind), sizeof(struct label));
   4189 }
   4190 
   4191 static INLINE u32 label_instr_pos(struct label *label)
   4192 {
   4193 	return label->instr_pos & 0x7FFFFFFF;
   4194 }
   4195 
   4196 static INLINE int is_label_resolved(struct label *label)
   4197 {
   4198 	return label->instr_pos & 0x80000000;
   4199 }
   4200 
   4201 static struct label *index_frame_label(struct wasm_interp *interp, u32 ind)
   4202 {
   4203 	struct callframe *frame;
   4204 
   4205 	frame = top_callframe(&interp->callframes);
   4206 	if (unlikely(!frame)) {
   4207 		interp_error(interp, "no callframe?");
   4208 		return NULL;
   4209 	}
   4210 
   4211 	return index_label(&interp->labels, frame->func->idx, ind);
   4212 }
   4213 
   4214 static INLINE int resolve_label(struct label *label, struct cursor *code)
   4215 {
   4216 	if (is_label_resolved(label)) {
   4217 		return 1;
   4218 	}
   4219 
   4220 	label->jump = code->p - code->start;
   4221 	label->instr_pos |= 0x80000000;
   4222 
   4223 	/*
   4224 	debug("resolving label %04x to %04x\n",
   4225 			label_instr_pos(label),
   4226 			label->jump);
   4227 			*/
   4228 
   4229 	return 1;
   4230 }
   4231 
   4232 static INLINE int pop_resolver(struct wasm_interp *interp,
   4233 		struct resolver *resolver)
   4234 {
   4235 #if 0
   4236 	int num_resolvers;
   4237 	struct label *label;
   4238 #endif
   4239 
   4240 	if (!cursor_pop(&interp->resolver_stack, (u8*)resolver, sizeof(*resolver))) {
   4241 		return interp_error(interp, "pop resolver");
   4242 	}
   4243 
   4244 #if 0
   4245 	if (unlikely(!count_local_resolvers(interp, &num_resolvers))) {
   4246 		return interp_error(interp, "local resolvers fn start");
   4247 	};
   4248 
   4249 	label = index_label(&interp->labels,
   4250 			    top_callframe(&interp->callframes)->func->idx,
   4251 			    resolver->label);
   4252 
   4253 	debug("%04lX popped resolver label:%d %04x-%04x i_%s i_%s %d local_resolvers:%d\n",
   4254 			interp_codeptr(interp)->p - interp_codeptr(interp)->start,
   4255 			resolver->label,
   4256 			label_instr_pos(label),
   4257 			label->jump,
   4258 			instr_name(resolver->start_tag),
   4259 			instr_name(resolver->end_tag),
   4260 			count_resolvers(interp),
   4261 			num_resolvers
   4262 			);
   4263 #endif
   4264 	return 1;
   4265 }
   4266 
   4267 static int pop_label(struct wasm_interp *interp,
   4268 		struct resolver *resolver,
   4269 		struct callframe **frame,
   4270 		struct label **label)
   4271 {
   4272 	if (unlikely(!pop_resolver(interp, resolver)))
   4273 		return interp_error(interp, "couldn't pop jump resolver stack");
   4274 
   4275 	if (unlikely(!(*frame = top_callframe(&interp->callframes))))
   4276 		return interp_error(interp, "no callframe?");
   4277 
   4278 	if (unlikely(!(*label = index_label(&interp->labels, (*frame)->func->idx,
   4279 					    resolver->label))))
   4280 		return interp_error(interp, "index label");
   4281 
   4282 	if (unlikely(!resolve_label(*label, &(*frame)->code)))
   4283 		return interp_error(interp, "resolve label");
   4284 
   4285 	return 1;
   4286 }
   4287 
   4288 static INLINE int pop_label_checkpoint(struct wasm_interp *interp)
   4289 {
   4290 	struct resolver resolver;
   4291 	struct callframe *frame;
   4292 	struct label *label;
   4293 
   4294 	return pop_label(interp, &resolver, &frame, &label);
   4295 }
   4296 
   4297 static INLINE u16 *func_num_labels(struct wasm_interp *interp, u32 fn)
   4298 {
   4299 	u16 *num = index_cursor(&interp->num_labels, fn, sizeof(u16));
   4300 	assert(num);
   4301 	assert(*num <= MAX_LABELS);
   4302 	return num;
   4303 }
   4304 
   4305 static int find_label(struct wasm_interp *interp, u32 fn, u32 instr_pos)
   4306 {
   4307 	u16 *num_labels;
   4308 	int i;
   4309 	struct label *label;
   4310 
   4311 	num_labels = func_num_labels(interp, fn);
   4312 
   4313 	if (!(label = index_label(&interp->labels, fn, *num_labels-1)))
   4314 		return interp_error(interp, "index label");
   4315 
   4316 	for (i = *num_labels-1; i >= 0; label--) {
   4317 		if (label_instr_pos(label) == instr_pos)
   4318 			return i;
   4319 		i--;
   4320 	}
   4321 
   4322 	return -1;
   4323 }
   4324 
   4325 static INLINE void set_label_pos(struct label *label, u32 pos)
   4326 {
   4327 	assert(!(pos & 0x80000000));
   4328 	label->instr_pos = pos;
   4329 }
   4330 
   4331 // upsert an unresolved label
   4332 static int upsert_label(struct wasm_interp *interp, u32 fn,
   4333 			u32 instr_pos, int *ind)
   4334 {
   4335 	struct label *label;
   4336 	u16 *num_labels;
   4337 
   4338 	num_labels = func_num_labels(interp, fn);
   4339 
   4340 	if (*num_labels > 0 && ((*ind = find_label(interp, fn, instr_pos)) != -1)) {
   4341 		// we already have the label
   4342 		return 1;
   4343 	}
   4344 
   4345 	if (*num_labels + 1 >= MAX_LABELS) {
   4346 		interp_error(interp, "too many labels in %s (> %d)",
   4347 			get_function_name(interp->module, fn), MAX_LABELS);
   4348 		return 0;
   4349 	}
   4350 
   4351 	/*
   4352 	debug("upsert_label: %d labels for %s:%d\n",
   4353 	      *num_labels, get_function_name(interp->module, fn), fn);
   4354 	      */
   4355 
   4356 	*ind = *num_labels;
   4357 	if (unlikely(!(label = index_label(&interp->labels, fn, *ind))))
   4358 		return interp_error(interp, "index label");
   4359 
   4360 	set_label_pos(label, instr_pos);
   4361 	*num_labels = *num_labels + 1;
   4362 
   4363 	return 2;
   4364 }
   4365 
   4366 static INLINE int cursor_push_resolver(struct cursor *stack, struct resolver *resolver)
   4367 {
   4368 	return cursor_push(stack, (u8*)resolver, sizeof(*resolver));
   4369 }
   4370 
   4371 struct tag_info {
   4372 	u8 flags;
   4373 	u8 end_tag;
   4374 };
   4375 
   4376 // when we encounter a control instruction, try to resolve the label, otherwise
   4377 // push the label index to the resolver stack for resolution later
   4378 static int push_label_checkpoint(struct wasm_interp *interp, struct label **label,
   4379 		u8 start_tag, u8 end_tag)
   4380 {
   4381 	u32 instr_pos, fns;
   4382 	int ind;
   4383 	struct resolver resolver;
   4384 	struct callframe *frame;
   4385 
   4386 #if 0
   4387 	int num_resolvers;
   4388 #endif
   4389 
   4390 	resolver.start_tag = start_tag;
   4391 	resolver.end_tag = end_tag;
   4392 	resolver.label = 0;
   4393 
   4394 	*label = NULL;
   4395 
   4396 	fns = interp->module->num_funcs;
   4397 	frame = top_callframe(&interp->callframes);
   4398 
   4399 	if (unlikely(!frame)) {
   4400 		return interp_error(interp, "no callframes available?");
   4401 	} else if (unlikely(frame->func->idx >= fns)) {
   4402 		return interp_error(interp, "invalid fn index?");
   4403 	}
   4404 
   4405 	instr_pos = frame->code.p - frame->code.start;
   4406 	if (unlikely(!upsert_label(interp, frame->func->idx, instr_pos, &ind))) {
   4407 		return interp_error(interp, "upsert label");
   4408 	}
   4409 
   4410 	if (unlikely(!(*label = index_label(&interp->labels, frame->func->idx, ind)))) {
   4411 		return interp_error(interp, "couldn't index label");
   4412 	}
   4413 
   4414 	resolver.label = ind;
   4415 
   4416 	if (unlikely(!cursor_push_resolver(&interp->resolver_stack, &resolver))) {
   4417 		return interp_error(interp, "push label index to resolver stack oob");
   4418 	}
   4419 
   4420 #if 0
   4421 	if (unlikely(!count_local_resolvers(interp, &num_resolvers))) {
   4422 		return interp_error(interp, "local resolvers fn start");
   4423 	};
   4424 
   4425 	debug("%04x pushed resolver label:%d 0x%04X-0x%04X i_%s i_%s %ld local_resolvers:%d \n",
   4426 			instr_pos,
   4427 			resolver.label,
   4428 			label_instr_pos(*label),
   4429 			(*label)->jump,
   4430 			instr_name(resolver.start_tag),
   4431 			instr_name(resolver.end_tag),
   4432 			cursor_count(&interp->resolver_stack, sizeof(resolver)),
   4433 			num_resolvers);
   4434 #endif
   4435 
   4436 	return 1;
   4437 }
   4438 
   4439 static int interp_jump(struct wasm_interp *interp, int jmp)
   4440 {
   4441 	struct callframe *frame;
   4442 
   4443 	frame = top_callframe(&interp->callframes);
   4444 	if (unlikely(!frame)) {
   4445 		return interp_error(interp, "no callframe?");
   4446 	}
   4447 
   4448 	//debug("jumping to %04x\n", jmp);
   4449 	frame->code.p = frame->code.start + jmp;
   4450 
   4451 	if (unlikely(frame->code.p >= frame->code.end)) {
   4452 		return interp_error(interp,
   4453 			"code pointer at or past end, evil jump?");
   4454 	}
   4455 
   4456 	return 1;
   4457 }
   4458 
   4459 static INLINE struct resolver *top_resolver_stack(struct cursor *stack, int index)
   4460 {
   4461 	struct resolver *p = (struct resolver*)stack->p;
   4462 	p = &p[-(index+1)];
   4463 	if (p < (struct resolver*)stack->start)
   4464 		return NULL;
   4465 	return p;
   4466 }
   4467 
   4468 static INLINE struct resolver *top_resolver(struct wasm_interp *interp, u32 index)
   4469 {
   4470 	return top_resolver_stack(&interp->resolver_stack, index);
   4471 }
   4472 
   4473 static int pop_label_and_skip(struct wasm_interp *interp, struct label *label,
   4474 		int times)
   4475 {
   4476 	int i;
   4477 	struct resolver resolver;
   4478 	assert(is_label_resolved(label));
   4479 
   4480 	for (i = 0; i < times; i++) {
   4481 		if (!pop_resolver(interp, &resolver)) {
   4482 			return interp_error(interp, "top resolver");
   4483 		}
   4484 	}
   4485 
   4486 	return interp_jump(interp, label->jump);
   4487 }
   4488 
   4489 static int unresolved_break(struct wasm_interp *interp, int index);
   4490 
   4491 static int break_if(struct wasm_interp *interp, struct label *label)
   4492 {
   4493 	struct cursor *code;
   4494 	struct label *else_label;
   4495 	struct expr_parser parser;
   4496 	struct expr expr;
   4497 
   4498 	if (!interp_jump(interp, label->jump))
   4499 		return interp_error(interp, "if break failed");
   4500 
   4501 	if (!(code = interp_codeptr(interp)))
   4502 		return interp_error(interp, "if break codeptr");
   4503 
   4504 	if (code->p - 1 < code->start)
   4505 		return interp_error(interp, "oob");
   4506 
   4507 	if (*(code->p - 1) != i_else)
   4508 		return 1;
   4509 
   4510 	if (!push_label_checkpoint(interp, &else_label, i_else, i_end))
   4511 		return interp_error(interp, "push else label");
   4512 
   4513 	if (is_label_resolved(else_label))
   4514 		return pop_label_and_skip(interp, else_label, 1);
   4515 
   4516 	make_interp_expr_parser(interp, &parser);
   4517 
   4518 	if (!parse_instrs_until(&parser, i_end, &expr))
   4519 		return interp_error(interp, "skip else instrs");
   4520 
   4521 	if (!pop_label_checkpoint(interp))
   4522 		return interp_error(interp, "op else skip");
   4523 
   4524 	return 1;
   4525 }
   4526 
   4527 
   4528 static int break_label(struct wasm_interp *interp, struct resolver *resolver,
   4529 		struct label *label)
   4530 {
   4531 
   4532 	// we have a loop, push the popped resolver
   4533 	if (resolver->start_tag == i_loop) {
   4534 		//debug("repushing resolver for loop\n");
   4535 		if (unlikely(!cursor_push_resolver(&interp->resolver_stack, resolver))) {
   4536 			return interp_error(interp, "re-push loop resolver");
   4537 		}
   4538 
   4539 		// loop jump
   4540 		return interp_jump(interp, label_instr_pos(label));
   4541 
   4542 	} else if (resolver->start_tag == i_if) {
   4543 		return break_if(interp, label);
   4544 	}
   4545 
   4546 	return interp_jump(interp, label->jump);
   4547 }
   4548 
   4549 static int pop_label_and_break(struct wasm_interp *interp, int times)
   4550 {
   4551 	int i;
   4552 	struct resolver resolver;
   4553 	struct label *label;
   4554 	struct callframe *frame;
   4555 
   4556 	if (unlikely(times == 0))
   4557 		return interp_error(interp, "can't pop label 0 times");
   4558 
   4559 	for (i = 0; i < times; i++) {
   4560 		if (!pop_label(interp, &resolver, &frame, &label)) {
   4561 			return interp_error(interp, "pop resolver");
   4562 		}
   4563 	}
   4564 
   4565 	return break_label(interp, &resolver, label);
   4566 }
   4567 
   4568 static int parse_block_instrs_at(struct expr_parser *p,
   4569 		struct expr *exprs, u8 start_tag, u8 end_tag, u8 *stopped_at)
   4570 {
   4571 	struct label *label = NULL;
   4572 
   4573 	// if we don't have an interpreter instance, we don't care about
   4574 	// label resolution (NOT TRUE ANYMORE!)
   4575 	if (p->interp && !push_label_checkpoint(p->interp, &label, start_tag,
   4576 						end_tag)) {
   4577 		return note_error(p->errs, p->code, "push checkpoint");
   4578 	}
   4579 
   4580 	if (label && is_label_resolved(label)) {
   4581 		debug("label is resolved, skipping block parse\n");
   4582 		// TODO verify this is correct
   4583 		exprs->code     = p->code->start + label_instr_pos(label);
   4584 		exprs->code_len = (p->code->start + label->jump) - exprs->code;
   4585 
   4586 		return pop_label_and_skip(p->interp, label, 1);
   4587 	}
   4588 
   4589 	if (!parse_instrs_until_at(p, end_tag, exprs, stopped_at))
   4590 		return note_error(p->errs, p->code, "parse instrs");
   4591 
   4592 	if (!pop_label_checkpoint(p->interp))
   4593 		return note_error(p->errs, p->code, "pop label");
   4594 
   4595 	return 1;
   4596 
   4597 }
   4598 
   4599 static INLINE int parse_block_instrs(struct expr_parser *p, struct expr *exprs,
   4600 			      u8 start_tag, u8 end_tag)
   4601 {
   4602 	u8 stopped_at;
   4603 	return parse_block_instrs_at(p, exprs, start_tag, end_tag, &stopped_at);
   4604 }
   4605 
   4606 static int parse_block_at(struct expr_parser *p, struct block *block, u8 start_tag,
   4607 		u8 end_tag, u8 *stopped_at)
   4608 {
   4609 	if (!parse_blocktype(p->code, p->errs, &block->type))
   4610 		return note_error(p->errs, p->code, "blocktype");
   4611 
   4612 	if (!parse_block_instrs_at(p, &block->instrs, start_tag, end_tag,
   4613 				stopped_at))
   4614 		return note_error(p->errs, p->code, "block instrs");
   4615 
   4616 	debug("%04lX parse block ended\n",
   4617 			p->interp ? p->code->p - p->code->start : 0L);
   4618 
   4619 	return 1;
   4620 }
   4621 
   4622 static INLINE int parse_block(struct expr_parser *p, struct block *block,
   4623 		u8 start_tag, u8 end_tag)
   4624 {
   4625 	u8 stopped_at;
   4626 	return parse_block_at(p, block, start_tag, end_tag, &stopped_at);
   4627 }
   4628 
   4629 static INLINE int parse_else(struct expr_parser *p, struct expr *instrs)
   4630 {
   4631 	if (p->interp && !pop_label_checkpoint(p->interp))
   4632 		return note_error(p->errs, p->code, "pop if checkpoint");
   4633 
   4634 	debug("parsing else...\n");
   4635 	return parse_block_instrs(p, instrs, i_else, i_end);
   4636 }
   4637 
   4638 static INLINE int parse_memarg(struct cursor *code, struct memarg *memarg)
   4639 {
   4640 	return parse_u32(code, &memarg->align) &&
   4641 	       parse_u32(code, &memarg->offset);
   4642 }
   4643 
   4644 static int parse_call_indirect(struct cursor *code,
   4645 		struct call_indirect *call_indirect)
   4646 {
   4647 	return parse_u32(code, &call_indirect->typeidx) &&
   4648 	       parse_u32(code, &call_indirect->tableidx);
   4649 }
   4650 
   4651 static int parse_bulk_op(struct cursor *code, struct errors *errs,
   4652 		struct bulk_op *bulk_op)
   4653 {
   4654 	u8 tag;
   4655 
   4656 	if (unlikely(!pull_byte(code, &tag)))
   4657 		return note_error(errs, code, "oob");
   4658 
   4659 	if (unlikely(tag < 10 || tag > 17))
   4660 		return note_error(errs, code, "invalid bulk op %d", tag);
   4661 
   4662 	bulk_op->tag = tag;
   4663 
   4664 	switch ((enum bulk_tag)tag) {
   4665 	case i_memory_copy:
   4666 		if (unlikely(!consume_byte(code, 0)))
   4667 			return note_error(errs, code, "mem idx dst 0");
   4668 		if (unlikely(!consume_byte(code, 0)))
   4669 			return note_error(errs, code, "mem idx src 0");
   4670 		return 1;
   4671 
   4672 	case i_memory_fill:
   4673 		if (unlikely(!consume_byte(code, 0)))
   4674 			return note_error(errs, code, "mem idx 0");
   4675 		return 1;
   4676 
   4677 	case i_table_init:
   4678 		if (unlikely(!parse_u32(code, &bulk_op->table_init.elemidx)))
   4679 			return note_error(errs, code, "elemidx");
   4680 		if (unlikely(!parse_u32(code, &bulk_op->table_init.tableidx)))
   4681 			return note_error(errs, code, "tableidx");
   4682 		return 1;
   4683 
   4684 	case i_elem_drop:
   4685 		if (unlikely(!parse_u32(code, &bulk_op->idx)))
   4686 			return note_error(errs, code, "elemidx");
   4687 		return 1;
   4688 
   4689 	case i_table_copy:
   4690 		if (unlikely(!parse_u32(code, &bulk_op->table_copy.from)))
   4691 			return note_error(errs, code, "elemidx");
   4692 		if (unlikely(!parse_u32(code, &bulk_op->table_copy.to)))
   4693 			return note_error(errs, code, "tableidx");
   4694 		return 1;
   4695 
   4696 	case i_table_grow:
   4697 	case i_table_size:
   4698 	case i_table_fill:
   4699 		if (unlikely(!parse_u32(code, &bulk_op->idx)))
   4700 			return note_error(errs, code, "tableidx");
   4701 		return 1;
   4702 	}
   4703 
   4704 	return note_error(errs, code, "unhandled table op 0x%02x", tag);
   4705 }
   4706 
   4707 static int parse_br_table(struct cursor *code, struct errors *errs,
   4708 		struct br_table *br_table)
   4709 {
   4710 	u32 i;
   4711 
   4712 	if (unlikely(!parse_u32(code, &br_table->num_label_indices))) {
   4713 		return note_error(errs, code, "fail read br_table num_indices");
   4714 	}
   4715 
   4716 	if (br_table->num_label_indices > ARRAY_SIZE(br_table->label_indices)) {
   4717 		return note_error(errs, code, "whoa slow down on that one chief. "
   4718 			"This br_table has %d indices but we only have room "
   4719 			"in our tiny struct for %d indices",
   4720 			br_table->num_label_indices,
   4721 			ARRAY_SIZE(br_table->label_indices));
   4722 	}
   4723 
   4724 	for (i = 0; i < br_table->num_label_indices; i++) {
   4725 		if (unlikely(!parse_u32(code, &br_table->label_indices[i]))) {
   4726 			return note_error(errs, code,
   4727 					  "failed to read br_table label %d/%d",
   4728 					  i+1, br_table->num_label_indices);
   4729 		}
   4730 	}
   4731 
   4732 	if (unlikely(!parse_u32(code, &br_table->default_label))) {
   4733 		return note_error(errs, code, "failed to parse default label");
   4734 	}
   4735 
   4736 	return 1;
   4737 }
   4738 
   4739 static int parse_select(struct cursor *code, struct errors *errs, u8 tag,
   4740 		struct select_instr *select)
   4741 {
   4742 	if (tag == i_select) {
   4743 		select->num_valtypes = 0;
   4744 		select->valtypes = NULL;
   4745 		return 1;
   4746 	}
   4747 
   4748 	if (unlikely(!parse_u32(code, &select->num_valtypes))) {
   4749 		return note_error(errs, code,
   4750 				"couldn't parse select valtype vec count");
   4751 	}
   4752 
   4753 	select->valtypes = code->p;
   4754 	code->p += select->num_valtypes;
   4755 
   4756 	return 1;
   4757 }
   4758 
   4759 static int parse_if(struct expr_parser *p, struct block *block)
   4760 {
   4761 	struct label *label;
   4762 	struct expr expr;
   4763 	u8 stopped_at;
   4764 
   4765 	if (!parse_block_at(p, block, i_if, i_if, &stopped_at))
   4766 		return note_error(p->errs, p->code, "parse if block");
   4767 
   4768 	if (p->interp == NULL || stopped_at != i_else)
   4769 		return 1;
   4770 
   4771 	// else
   4772 	if (!push_label_checkpoint(p->interp, &label, i_else, i_end))
   4773 		return note_error(p->errs, p->code, "push else checkpoint");
   4774 
   4775 	if (is_label_resolved(label))
   4776 		return pop_label_and_skip(p->interp, label, 1);
   4777 
   4778 	if (!parse_instrs_until(p, i_end, &expr))
   4779 		return note_error(p->errs, p->code, "parse else instrs");
   4780 
   4781 	if (!pop_label_checkpoint(p->interp))
   4782 		return note_error(p->errs, p->code, "pop else checkpoint");
   4783 
   4784 	return 1;
   4785 }
   4786 
   4787 static int parse_instr(struct expr_parser *p, u8 tag, struct instr *op)
   4788 {
   4789 	op->pos = p->code->p - 1 - p->code->start;
   4790 	op->tag = tag;
   4791 
   4792 	switch ((enum instr_tag)tag) {
   4793 		// two-byte instrs
   4794 		case i_select:
   4795 		case i_selects:
   4796 			return parse_select(p->code, p->errs, tag, &op->select);
   4797 
   4798 		case i_memory_size:
   4799 		case i_memory_grow:
   4800 			return consume_byte(p->code, 0);
   4801 
   4802 		case i_block:
   4803 			return parse_block(p, &op->block, i_block, i_end);
   4804 		case i_loop:
   4805 			return parse_block(p, &op->block, i_loop, i_end);
   4806 		case i_if:
   4807 			return parse_if(p, &op->block);
   4808 		case i_else:
   4809 			return parse_else(p, &op->else_block);
   4810 
   4811 		case i_call:
   4812 		case i_local_get:
   4813 		case i_local_set:
   4814 		case i_local_tee:
   4815 		case i_global_get:
   4816 		case i_global_set:
   4817 		case i_br:
   4818 		case i_br_if:
   4819 		case i_ref_func:
   4820 		case i_table_set:
   4821 		case i_table_get:
   4822 			if (unlikely(!parse_u32(p->code, &op->u32))) {
   4823 				return note_error(p->errs, p->code,
   4824 						"couldn't read int");
   4825 			}
   4826 			return 1;
   4827 
   4828 		case i_i32_const:
   4829 			if (unlikely(!parse_int(p->code, &op->i32))) {
   4830 				return note_error(p->errs, p->code,
   4831 						"couldn't read int");
   4832 			}
   4833 			return 1;
   4834 
   4835 		case i_i64_const:
   4836 			if (unlikely(!parse_i64(p->code, &op->u64))) {
   4837 				return note_error(p->errs, p->code,
   4838 						"couldn't read i64");
   4839 			}
   4840 			return 1;
   4841 
   4842 		case i_ref_is_null:
   4843 		case i_i32_load:
   4844 		case i_i64_load:
   4845 		case i_f32_load:
   4846 		case i_f64_load:
   4847 		case i_i32_load8_s:
   4848 		case i_i32_load8_u:
   4849 		case i_i32_load16_s:
   4850 		case i_i32_load16_u:
   4851 		case i_i64_load8_s:
   4852 		case i_i64_load8_u:
   4853 		case i_i64_load16_s:
   4854 		case i_i64_load16_u:
   4855 		case i_i64_load32_s:
   4856 		case i_i64_load32_u:
   4857 		case i_i32_store:
   4858 		case i_i64_store:
   4859 		case i_f32_store:
   4860 		case i_f64_store:
   4861 		case i_i32_store8:
   4862 		case i_i32_store16:
   4863 		case i_i64_store8:
   4864 		case i_i64_store16:
   4865 		case i_i64_store32:
   4866 			return parse_memarg(p->code, &op->memarg);
   4867 
   4868 		case i_br_table:
   4869 			return parse_br_table(p->code, p->errs, &op->br_table);
   4870 
   4871 		case i_bulk_op:
   4872 			return parse_bulk_op(p->code, p->errs, &op->bulk_op);
   4873 
   4874 		case i_call_indirect:
   4875 			return parse_call_indirect(p->code, &op->call_indirect);
   4876 
   4877 		case i_f32_const:
   4878 			return read_f32(p->code, &op->f32);
   4879 
   4880 		case i_f64_const:
   4881 			return read_f64(p->code, &op->f64);
   4882 
   4883 		// single-tag ops
   4884 		case i_end:
   4885 		case i_ref_null:
   4886 		case i_unreachable:
   4887 		case i_nop:
   4888 		case i_return:
   4889 		case i_drop:
   4890 		case i_i32_eqz:
   4891 		case i_i32_eq:
   4892 		case i_i32_ne:
   4893 		case i_i32_lt_s:
   4894 		case i_i32_lt_u:
   4895 		case i_i32_gt_s:
   4896 		case i_i32_gt_u:
   4897 		case i_i32_le_s:
   4898 		case i_i32_le_u:
   4899 		case i_i32_ge_s:
   4900 		case i_i32_ge_u:
   4901 		case i_i64_eqz:
   4902 		case i_i64_eq:
   4903 		case i_i64_ne:
   4904 		case i_i64_lt_s:
   4905 		case i_i64_lt_u:
   4906 		case i_i64_gt_s:
   4907 		case i_i64_gt_u:
   4908 		case i_i64_le_s:
   4909 		case i_i64_le_u:
   4910 		case i_i64_ge_s:
   4911 		case i_i64_ge_u:
   4912 		case i_f32_eq:
   4913 		case i_f32_ne:
   4914 		case i_f32_lt:
   4915 		case i_f32_gt:
   4916 		case i_f32_le:
   4917 		case i_f32_ge:
   4918 		case i_f64_eq:
   4919 		case i_f64_ne:
   4920 		case i_f64_lt:
   4921 		case i_f64_gt:
   4922 		case i_f64_le:
   4923 		case i_f64_ge:
   4924 		case i_i32_clz:
   4925 		case i_i32_ctz:
   4926 		case i_i32_popcnt:
   4927 		case i_i32_add:
   4928 		case i_i32_sub:
   4929 		case i_i32_mul:
   4930 		case i_i32_div_s:
   4931 		case i_i32_div_u:
   4932 		case i_i32_rem_s:
   4933 		case i_i32_rem_u:
   4934 		case i_i32_and:
   4935 		case i_i32_or:
   4936 		case i_i32_xor:
   4937 		case i_i32_shl:
   4938 		case i_i32_shr_s:
   4939 		case i_i32_shr_u:
   4940 		case i_i32_rotl:
   4941 		case i_i32_rotr:
   4942 		case i_i64_clz:
   4943 		case i_i64_ctz:
   4944 		case i_i64_popcnt:
   4945 		case i_i64_add:
   4946 		case i_i64_sub:
   4947 		case i_i64_mul:
   4948 		case i_i64_div_s:
   4949 		case i_i64_div_u:
   4950 		case i_i64_rem_s:
   4951 		case i_i64_rem_u:
   4952 		case i_i64_and:
   4953 		case i_i64_or:
   4954 		case i_i64_xor:
   4955 		case i_i64_shl:
   4956 		case i_i64_shr_s:
   4957 		case i_i64_shr_u:
   4958 		case i_i64_rotl:
   4959 		case i_i64_rotr:
   4960 		case i_f32_abs:
   4961 		case i_f32_neg:
   4962 		case i_f32_ceil:
   4963 		case i_f32_floor:
   4964 		case i_f32_trunc:
   4965 		case i_f32_nearest:
   4966 		case i_f32_sqrt:
   4967 		case i_f32_add:
   4968 		case i_f32_sub:
   4969 		case i_f32_mul:
   4970 		case i_f32_div:
   4971 		case i_f32_min:
   4972 		case i_f32_max:
   4973 		case i_f32_copysign:
   4974 		case i_f64_abs:
   4975 		case i_f64_neg:
   4976 		case i_f64_ceil:
   4977 		case i_f64_floor:
   4978 		case i_f64_trunc:
   4979 		case i_f64_nearest:
   4980 		case i_f64_sqrt:
   4981 		case i_f64_add:
   4982 		case i_f64_sub:
   4983 		case i_f64_mul:
   4984 		case i_f64_div:
   4985 		case i_f64_min:
   4986 		case i_f64_max:
   4987 		case i_f64_copysign:
   4988 		case i_i32_wrap_i64:
   4989 		case i_i32_trunc_f32_s:
   4990 		case i_i32_trunc_f32_u:
   4991 		case i_i32_trunc_f64_s:
   4992 		case i_i32_trunc_f64_u:
   4993 		case i_i64_extend_i32_s:
   4994 		case i_i64_extend_i32_u:
   4995 		case i_i64_trunc_f32_s:
   4996 		case i_i64_trunc_f32_u:
   4997 		case i_i64_trunc_f64_s:
   4998 		case i_i64_trunc_f64_u:
   4999 		case i_f32_convert_i32_s:
   5000 		case i_f32_convert_i32_u:
   5001 		case i_f32_convert_i64_s:
   5002 		case i_f32_convert_i64_u:
   5003 		case i_f32_demote_f64:
   5004 		case i_f64_convert_i32_s:
   5005 		case i_f64_convert_i32_u:
   5006 		case i_f64_convert_i64_s:
   5007 		case i_f64_convert_i64_u:
   5008 		case i_f64_promote_f32:
   5009 		case i_i32_reinterpret_f32:
   5010 		case i_i64_reinterpret_f64:
   5011 		case i_f32_reinterpret_i32:
   5012 		case i_f64_reinterpret_i64:
   5013 		case i_i32_extend8_s:
   5014 		case i_i32_extend16_s:
   5015 		case i_i64_extend8_s:
   5016 		case i_i64_extend16_s:
   5017 		case i_i64_extend32_s:
   5018 			return 1;
   5019 	}
   5020 
   5021 	return note_error(p->errs, p->code, "unhandled tag: 0x%x", tag);
   5022 }
   5023 
   5024 // end or else
   5025 static int if_jump(struct wasm_interp *interp, struct label *label)
   5026 {
   5027 	struct expr expr;
   5028 	struct expr_parser parser;
   5029 	struct label *else_label;
   5030 	u8 stopped_at;
   5031 
   5032 	if (!label) {
   5033 		return interp_error(interp, "no label?");
   5034 	}
   5035 
   5036 	if (is_label_resolved(label)) {
   5037 		return pop_label_and_skip(interp, label, 1);
   5038 	}
   5039 
   5040 	make_interp_expr_parser(interp, &parser);
   5041 
   5042 	// consume instructions, use resolver stack to resolve jumps
   5043 	if (!parse_instrs_until_at(&parser, i_if, &expr, &stopped_at))
   5044 		return interp_error(interp, "parse instrs start (if)");
   5045 
   5046 	if (!pop_label_checkpoint(interp))
   5047 		return interp_error(interp, "pop label");
   5048 
   5049 	if (stopped_at == i_else && !push_label_checkpoint(interp, &else_label,
   5050 							   i_else, i_end)) {
   5051 		return interp_error(interp, "push else label");
   5052 	}
   5053 
   5054 	debug("%04lX if_jump ended\n",
   5055 		parser.code->p - parser.code->start);
   5056 
   5057 	return 1;
   5058 }
   5059 
   5060 static int interp_block(struct wasm_interp *interp)
   5061 {
   5062 	struct cursor *code;
   5063 	struct label *label;
   5064 	struct blocktype blocktype;
   5065 
   5066 	if (unlikely(!(code = interp_codeptr(interp))))
   5067 		return interp_error(interp, "empty callstack?");
   5068 
   5069 	if (unlikely(!parse_blocktype(code, &interp->errors, &blocktype)))
   5070 		return interp_error(interp, "couldn't parse blocktype");
   5071 
   5072 	if (unlikely(!push_label_checkpoint(interp, &label, i_block, i_end)))
   5073 		return interp_error(interp, "block label checkpoint");
   5074 
   5075 	return 1;
   5076 }
   5077 
   5078 static INLINE struct label *top_label(struct wasm_interp *interp, u32 index)
   5079 {
   5080 	struct resolver *resolver;
   5081 
   5082 	if (unlikely(!(resolver = top_resolver(interp, index)))) {
   5083 		interp_error(interp, "invalid resolver index %d", index);
   5084 		return NULL;
   5085 	}
   5086 
   5087 	return index_frame_label(interp, resolver->label);
   5088 }
   5089 
   5090 static INLINE int interp_else(struct wasm_interp *interp)
   5091 {
   5092 	(void)interp;
   5093 	/*
   5094 	struct label *label;
   5095 	struct expr expr;
   5096 	struct expr_parser parser;
   5097 
   5098 	if (!(label = top_label(interp, 0)))
   5099 		return interp_error(interp, "no label?");
   5100 
   5101 	if (!push_label_checkpoint(interp, &label, i_else, i_end)) {
   5102 		return interp_error(interp, "label checkpoint");
   5103 	}
   5104 
   5105 	if (!is_label_resolved(label)) {
   5106 		return interp_error(interp, "expected label to be parsed");
   5107 	}
   5108 	*/
   5109 
   5110 	return 1;
   5111 }
   5112 
   5113 static int interp_if(struct wasm_interp *interp)
   5114 {
   5115 	struct val cond;
   5116 	struct blocktype blocktype;
   5117 	struct cursor *code;
   5118 	struct label *label;
   5119 
   5120 	if (unlikely(!(code = interp_codeptr(interp)))) {
   5121 		return interp_error(interp, "empty callstack?");
   5122 	}
   5123 
   5124 	if (unlikely(!parse_blocktype(code, &interp->errors, &blocktype))) {
   5125 		return interp_error(interp, "couldn't parse blocktype");
   5126 	}
   5127 
   5128 	if (unlikely(!cursor_popval(&interp->stack, &cond))) {
   5129 		return interp_error(interp, "if pop val");
   5130 	}
   5131 
   5132 	if (!push_label_checkpoint(interp, &label, i_if, i_if)) {
   5133 		return interp_error(interp, "label checkpoint");
   5134 	}
   5135 
   5136 	if (cond.num.i32 != 0) {
   5137 		return 1;
   5138 	}
   5139 
   5140 	if (unlikely(!if_jump(interp, label))) {
   5141 		return interp_error(interp, "jump");
   5142 	}
   5143 
   5144 	return 1;
   5145 }
   5146 
   5147 static INLINE int clz32(u32 x)
   5148 {
   5149 	return x ? __builtin_clz(x) : sizeof(x) * 8;
   5150 }
   5151 
   5152 static INLINE int clz64(u64 x)
   5153 {
   5154 	return x ? __builtin_clz(x) : sizeof(x) * 8;
   5155 }
   5156 
   5157 static INLINE int ctz(u32 x)
   5158 {
   5159 	return x ? __builtin_ctz(x) : (int)sizeof(x) * 8;
   5160 }
   5161 
   5162 static INLINE int popcnt(u32 x)
   5163 {
   5164 	return x ? __builtin_popcount(x) : 0;
   5165 }
   5166 
   5167 static INLINE int interp_i32_popcnt(struct wasm_interp *interp)
   5168 {
   5169 	struct val a;
   5170 	if (unlikely(!stack_pop_valtype(interp, val_i32, &a)))
   5171 		return interp_error(interp, "pop val");
   5172 	return stack_push_i32(interp, popcnt(a.num.u32));
   5173 }
   5174 
   5175 static INLINE int interp_i32_ctz(struct wasm_interp *interp)
   5176 {
   5177 	struct val a;
   5178 	if (unlikely(!stack_pop_valtype(interp, val_i32, &a)))
   5179 		return interp_error(interp, "pop val");
   5180 	return stack_push_i32(interp, ctz(a.num.u32));
   5181 }
   5182 
   5183 static INLINE int interp_i64_clz(struct wasm_interp *interp)
   5184 {
   5185 	struct val a;
   5186 	if (unlikely(!stack_pop_valtype(interp, val_i64, &a)))
   5187 		return interp_error(interp, "pop val");
   5188 	return stack_push_i64(interp, clz64(a.num.u64));
   5189 }
   5190 
   5191 static INLINE int interp_i32_clz(struct wasm_interp *interp)
   5192 {
   5193 	struct val a;
   5194 	if (unlikely(!stack_pop_valtype(interp, val_i32, &a)))
   5195 		return interp_error(interp, "pop val");
   5196 	return stack_push_i32(interp, clz32(a.num.u32));
   5197 }
   5198 
   5199 static INLINE int interp_i32_eqz(struct wasm_interp *interp)
   5200 {
   5201 	struct val a;
   5202 	if (unlikely(!stack_pop_valtype(interp, val_i32, &a)))
   5203 		return interp_error(interp, "pop val");
   5204 	return stack_push_i32(interp, a.num.i32 == 0);
   5205 }
   5206 
   5207 static int unresolved_break(struct wasm_interp *interp, int index)
   5208 {
   5209 	struct expr_parser parser;
   5210 	struct callframe *frame;
   5211 	struct expr expr;
   5212 
   5213 	struct resolver *resolver = NULL;
   5214 	struct label *label = NULL;
   5215 
   5216 #if DEBUG
   5217 	int times;
   5218 #endif
   5219 
   5220 	make_interp_expr_parser(interp, &parser);
   5221 
   5222 	if (unlikely(!(frame = top_callframe(&interp->callframes)))) {
   5223 		return interp_error(interp, "no top callframe?");
   5224 	}
   5225 
   5226 
   5227 #if DEBUG
   5228 	times = index+1;
   5229 #endif
   5230 	debug("breaking %d times from unresolved label\n", times);
   5231 
   5232 	while (index-- >= 0) {
   5233 		if (unlikely(!(resolver = top_resolver(interp, 0)))) {
   5234 			return interp_error(interp, "invalid resolver index %d",
   5235 					index);
   5236 		}
   5237 
   5238 		if (unlikely(!(label = index_frame_label(interp, resolver->label)))) {
   5239 			return interp_error(interp, "no label");
   5240 		}
   5241 
   5242 		// TODO: breaking from functions (return)
   5243 		if (is_label_resolved(label)) {
   5244 			if (index == -1)
   5245 				return pop_label_and_break(interp, 1);
   5246 			else if (!pop_label_and_skip(interp, label, 1))
   5247 				return interp_error(interp, "pop and jump");
   5248 			else
   5249 				continue;
   5250 		}
   5251 
   5252 		if (unlikely(!parse_instrs_until(&parser, resolver->end_tag, &expr)))
   5253 			return interp_error(interp, "parsing instrs");
   5254 
   5255 		if (index == -1)
   5256 			return pop_label_and_break(interp, 1);
   5257 
   5258 		if (!pop_label_checkpoint(interp))
   5259 			return interp_error(interp, "pop label");
   5260 	}
   5261 
   5262 	/*
   5263 	debug("finished breaking %d times from unresolved label (it was a %s)\n",
   5264 			times,
   5265 			instr_name(resolver->start_tag));
   5266 
   5267 	assert(resolver);
   5268 	assert(label);
   5269 
   5270 	if (resolver->start_tag == i_loop) {
   5271 		debug("jumping to start of loop\n");
   5272 		if (unlikely(!cursor_push_resolver(&interp->resolver_stack,
   5273 						   resolver))) {
   5274 			return interp_error(interp, "re-push loop resolver");
   5275 		}
   5276 		return interp_jump(interp, label_instr_pos(label));
   5277 	}
   5278 
   5279 	*/
   5280 	return interp_error(interp, "shouldn't get here");
   5281 }
   5282 
   5283 static int interp_return(struct wasm_interp *interp)
   5284 {
   5285 	int count;
   5286 
   5287 	if (unlikely(!count_local_resolvers(interp, &count))) {
   5288 		return interp_error(interp, "failed to count fn labels?");
   5289 	}
   5290 
   5291 	if (unlikely(!cursor_dropn(&interp->resolver_stack,
   5292 					sizeof(struct resolver), count))) {
   5293 		return interp_error(interp, "failed to drop %d local labels",
   5294 				count);
   5295 	}
   5296 
   5297 	return drop_callframe_return(interp, 1);
   5298 }
   5299 
   5300 
   5301 static int interp_br_jump(struct wasm_interp *interp, u32 index)
   5302 {
   5303 	struct label *label;
   5304 
   5305 	if (unlikely(!(label = top_label(interp, index)))) {
   5306 		return interp_return(interp);
   5307 	}
   5308 
   5309 	if (is_label_resolved(label)) {
   5310 		return pop_label_and_break(interp, index+1);
   5311 	}
   5312 
   5313 	return unresolved_break(interp, index);
   5314 }
   5315 
   5316 static INLINE int interp_br(struct wasm_interp *interp, u32 ind)
   5317 {
   5318 	return interp_br_jump(interp, ind);
   5319 }
   5320 
   5321 static INLINE int interp_br_table(struct wasm_interp *interp,
   5322 				  struct br_table *br_table)
   5323 {
   5324 	int i;
   5325 
   5326 	if (!stack_pop_i32(interp, &i)) {
   5327 		return interp_error(interp, "pop br_table index");
   5328 	}
   5329 
   5330 	if ((u32)i < br_table->num_label_indices) {
   5331 		return interp_br_jump(interp, br_table->label_indices[i]);
   5332 	}
   5333 
   5334 	return interp_br_jump(interp, br_table->default_label);
   5335 }
   5336 
   5337 static INLINE int interp_br_if(struct wasm_interp *interp, u32 ind)
   5338 {
   5339 	int cond = 0;
   5340 
   5341 	// TODO: can this be something other than an i32?
   5342 	if (unlikely(!stack_pop_i32(interp, &cond))) {
   5343 		return interp_error(interp, "pop br_if i32");
   5344 	}
   5345 
   5346 	if (cond != 0)
   5347 		return interp_br_jump(interp, ind);
   5348 
   5349 	return 1;
   5350 }
   5351 
   5352 static struct val *get_global_inst(struct wasm_interp *interp, u32 ind)
   5353 {
   5354 	struct global_inst *global_inst;
   5355 
   5356 	if (unlikely(!was_section_parsed(interp->module, section_global))) {
   5357 		interp_error(interp,
   5358 			"can't get global %d, no global section parsed!", ind);
   5359 		return NULL;
   5360 	}
   5361 
   5362 	if (unlikely(ind >= interp->module_inst.num_globals)) {
   5363 		interp_error(interp, "invalid global index %d (max %d)", ind,
   5364 			     interp->module_inst.num_globals);
   5365 		return NULL;
   5366 	}
   5367 
   5368 	global_inst = &interp->module_inst.globals[ind];
   5369 
   5370 	/* copy initialized global from module to global instance */
   5371 	//memcpy(&global_inst->val, &global->val, sizeof(global_inst->val));
   5372 
   5373 	return &global_inst->val;
   5374 }
   5375 
   5376 static int interp_global_get(struct wasm_interp *interp, u32 ind)
   5377 {
   5378 	struct globalsec *section = &interp->module->global_section;
   5379 	struct val *global;
   5380 
   5381 	// TODO imported global indices?
   5382 	if (unlikely(ind >= section->num_globals)) {
   5383 		return interp_error(interp, "invalid global index %d / %d",
   5384 				ind, section->num_globals-1);
   5385 	}
   5386 
   5387 	if (!(global = get_global_inst(interp, ind))) {
   5388 		return interp_error(interp, "get global");
   5389 	}
   5390 
   5391 	return stack_pushval(interp, global);
   5392 }
   5393 
   5394 static INLINE int has_memory_section(struct module *module)
   5395 {
   5396 	return was_section_parsed(module, section_memory) &&
   5397 		module->memory_section.num_mems > 0;
   5398 }
   5399 
   5400 static INLINE int bitwidth(enum valtype vt)
   5401 {
   5402 	switch (vt) {
   5403 	case val_i32:
   5404 	case val_f32:
   5405 		return 32;
   5406 
   5407 	case val_i64:
   5408 	case val_f64:
   5409 		return 64;
   5410 
   5411 	/* invalid? */
   5412 	case val_ref_null:
   5413 	case val_ref_func:
   5414 	case val_ref_extern:
   5415 		return 0;
   5416 	}
   5417 
   5418 	return 0;
   5419 }
   5420 
   5421 struct memtarget {
   5422 	int size;
   5423 	u8 *pos;
   5424 };
   5425 
   5426 static int interp_mem_offset(struct wasm_interp *interp,
   5427 		int *N, int i, enum valtype c, struct memarg *memarg,
   5428 		struct memtarget *t)
   5429 {
   5430 	int offset, bw;
   5431 
   5432 	if (unlikely(!has_memory_section(interp->module))) {
   5433 		return interp_error(interp, "no memory section");
   5434 	}
   5435 
   5436 	offset = i + memarg->offset;
   5437 	bw = bitwidth(c);
   5438 
   5439 	if (*N == 0) {
   5440 		*N = bw;
   5441 	}
   5442 
   5443 	t->size = *N/8;
   5444 	t->pos = interp->memory.start + offset;
   5445 
   5446 	if (t->pos < interp->memory.start) {
   5447 		return interp_error(interp,
   5448 				"invalid memory offset %d\n", offset);
   5449 	}
   5450 
   5451 	if (t->pos + t->size > interp->memory.p) {
   5452 		return interp_error(interp,
   5453 			"mem store oob pos:%d size:%d mem:%d", offset, t->size,
   5454 				interp->memory.p - interp->memory.start);
   5455 	}
   5456 
   5457 	return 1;
   5458 }
   5459 
   5460 static int wrap_val(struct val *val, unsigned int size) {
   5461 	switch (val->type) {
   5462 	case val_i32:
   5463 		if (size == 32)
   5464 			return 1;
   5465 		//debug("before %d size %d (mask %lx)\n", val->num.i32, size, (1UL << size)-1);
   5466 		val->num.i32 &= (1UL << size)-1;
   5467 		//debug("after %d size %d (mask %lx)\n", val->num.i32, size, (1UL << size)-1);
   5468 		break;
   5469 	case val_i64:
   5470 		if (size == 64)
   5471 			return 1;
   5472 		val->num.i64 &= (1ULL << size)-1;
   5473 		break;
   5474 	case val_f32:
   5475 	case val_f64:
   5476 		return 1;
   5477 
   5478 	default:
   5479 		return 0;
   5480 	}
   5481 	return 1;
   5482 }
   5483 
   5484 static int store_val(struct wasm_interp *interp, int i,
   5485 		struct memarg *memarg, enum valtype type, struct val *val, int N)
   5486 {
   5487 	struct memtarget target;
   5488 	//struct cursor mem;
   5489 
   5490 	if (unlikely(!interp_mem_offset(interp, &N, i, type, memarg, &target)))
   5491 		return 0;
   5492 
   5493 	if (N != 0) {
   5494 		if (!wrap_val(val, N)) {
   5495 			return interp_error(interp,
   5496 				"implement wrap val (truncate?) for %s",
   5497 				valtype_name(val->type));
   5498 		}
   5499 	}
   5500 
   5501 	//make_cursor(target.pos, interp->memory.p, &mem);
   5502 
   5503 	debug("storing ");
   5504 #ifdef DEBUG
   5505 	print_val(val);
   5506 #endif 
   5507 	debug(" at %ld (%d bytes), N:%d\n", 
   5508 			target.pos - interp->memory.start,
   5509 			target.size, N);
   5510 
   5511 	//cursor_print_around(&mem, 20);
   5512 
   5513 	memcpy(target.pos, &val->num.i32, target.size);
   5514 
   5515 	return 1;
   5516 }
   5517 
   5518 static INLINE int store_simple(struct wasm_interp *interp, int offset, struct val *val)
   5519 {
   5520 	struct memarg memarg = {};
   5521 	return store_val(interp, offset, &memarg, val->type, val, 0);
   5522 }
   5523 
   5524 static INLINE int store_i32(struct wasm_interp *interp, int offset, int i)
   5525 {
   5526 	struct val val;
   5527 	make_i32_val(&val, i);
   5528 	return store_simple(interp, offset, &val);
   5529 }
   5530 
   5531 static int interp_load(struct wasm_interp *interp, struct memarg *memarg,
   5532 		enum valtype type, int N, int sign)
   5533 {
   5534 	struct memtarget target;
   5535 //	struct cursor mem;
   5536 	struct val out = {0};
   5537 	int i;
   5538 
   5539 	(void)sign;
   5540 
   5541 	out.type = type;
   5542 
   5543 	if (unlikely(!stack_pop_i32(interp, &i)))  {
   5544 		return interp_error(interp, "pop stack");
   5545 	}
   5546 
   5547 	if (unlikely(!interp_mem_offset(interp, &N, i, type, memarg, &target))) {
   5548 		return interp_error(interp, "memory target");
   5549 	}
   5550 
   5551 	memcpy(&out.num.i32, target.pos, target.size);
   5552 	wrap_val(&out, target.size * 8);
   5553 
   5554 	//make_cursor(target.pos, interp->memory.p, &mem);
   5555 	debug("loading %d from %ld (copying %d bytes)\n", out.num.i32,
   5556 			target.pos - interp->memory.start, target.size);
   5557 	//cursor_print_around(&mem, 20);
   5558 
   5559 	if (unlikely(!stack_pushval(interp, &out))) {
   5560 		return interp_error(interp,
   5561 			"push to stack after load %s", valtype_name(type));
   5562 	}
   5563 
   5564 	return 1;
   5565 }
   5566 
   5567 static INLINE int load_i32(struct wasm_interp *interp, int addr, int *i)
   5568 {
   5569 	struct memarg memarg = { .offset = 0, .align = 0 };
   5570 
   5571 	if (unlikely(!stack_push_i32(interp, addr)))
   5572 		return interp_error(interp, "push addr %d", addr);
   5573 
   5574 	if (unlikely(!interp_load(interp, &memarg, val_i32, 0, -1)))
   5575 		return interp_error(interp, "load");
   5576 
   5577 	return stack_pop_i32(interp, i);
   5578 }
   5579 
   5580 static int wasi_fd_close(struct wasm_interp *interp)
   5581 {
   5582 	struct val *params = NULL;
   5583 	if (!get_params(interp, &params, 1))
   5584 		return interp_error(interp, "param");
   5585 
   5586 	close(params[0].num.i32);
   5587 
   5588 	return stack_push_i32(interp, 0);
   5589 }
   5590 
   5591 static int wasi_fd_write(struct wasm_interp *interp)
   5592 {
   5593 	struct val *fd, *iovs_ptr, *iovs_len, *written;
   5594 	int i, ind, iovec_data, str_len, wrote, all;
   5595 
   5596 	if (unlikely(!(fd = get_local(interp, 0))))
   5597 		return interp_error(interp, "fd");
   5598 
   5599 	if (unlikely(!(iovs_ptr = get_local(interp, 1))))
   5600 		return interp_error(interp, "iovs_ptr");
   5601 
   5602 	if (unlikely(!(iovs_len = get_local(interp, 2))))
   5603 		return interp_error(interp, "iovs_len");
   5604 
   5605 	if (unlikely(!(written = get_local(interp, 3))))
   5606 		return interp_error(interp, "written");
   5607 
   5608 	if (unlikely(fd->num.i32 >= 10))
   5609 		return interp_error(interp, "weird fd %d", fd->num.i32);
   5610 
   5611 	all = 0;
   5612 	str_len = 0;
   5613 	i = 0;
   5614 	iovec_data = 0;
   5615 
   5616 	for (; i < iovs_len->num.i32; i++) {
   5617 		ind = 8*i;
   5618 
   5619 		if (unlikely(!load_i32(interp, iovs_ptr->num.i32 + ind,
   5620 				       &iovec_data))) {
   5621 			return interp_error(interp, "load iovec data");
   5622 		}
   5623 
   5624 		if (unlikely(!load_i32(interp,iovs_ptr->num.i32 + (ind+4),
   5625 				       &str_len))) {
   5626 			return interp_error(interp, "load iovec data");
   5627 		}
   5628 
   5629 		if (unlikely(interp->memory.start + iovec_data + str_len >=
   5630 				interp->memory.p)) {
   5631 			return interp_error(interp, "fd_write oob");
   5632 		}
   5633 
   5634 		debug("fd_write #iovec %d/%d len %d '%.*s'\n",
   5635 				i+1,
   5636 				iovs_len->num.i32,
   5637 				str_len,
   5638 				str_len,
   5639 				interp->memory.start + iovec_data);
   5640 
   5641 		wrote = write(fd->num.i32,
   5642 			interp->memory.start + iovec_data,
   5643 			str_len
   5644 			);
   5645 
   5646 		all += wrote;
   5647 
   5648 		if (wrote != str_len) {
   5649 			return interp_error(interp, "written %d != %d",
   5650 					written->num.i32, str_len);
   5651 		}
   5652 	}
   5653 
   5654 	if (!store_i32(interp, written->num.i32, all)) {
   5655 		return interp_error(interp, "store written");
   5656 	}
   5657 
   5658 	return stack_push_i32(interp, 0);
   5659 }
   5660 
   5661 static int wasi_get_strs(struct wasm_interp *interp, int count, const char **strs)
   5662 {
   5663 	struct val *argv, *argv_buf;
   5664 	struct cursor writer;
   5665 	int i, len;
   5666 
   5667 	if (!(argv = get_local(interp, 0)))
   5668 		return interp_error(interp, "strs");
   5669 
   5670 	if (!(argv_buf = get_local(interp, 1)))
   5671 		return interp_error(interp, "strs_buf");
   5672 
   5673 	make_cursor(interp->memory.start + argv_buf->num.i32,
   5674 		    interp->memory.p, &writer);
   5675 
   5676 	for (i = 0; i < count; i++) {
   5677 		if (!store_i32(interp, argv->num.i32 + i*4,
   5678 			       writer.p - interp->memory.start)) {
   5679 			return interp_error(interp, "store argv %d ptr\n", i);
   5680 		}
   5681 
   5682 		len = strlen(strs[i]) + 1;
   5683 
   5684 //		debug("get_str %d '%.*s'\n", i, len, strs[i]);
   5685 
   5686 		if (!cursor_push(&writer, (u8*)strs[i], len)) {
   5687 			return interp_error(interp,"write arg %d", i+1);
   5688 		}
   5689 	}
   5690 
   5691 	return stack_push_i32(interp, 0);
   5692 
   5693 }
   5694 
   5695 static int wasi_strs_sizes_get(struct wasm_interp *interp, int count,
   5696 		const char **strs)
   5697 {
   5698 	struct val *argc_addr, *argv_buf_size_addr;
   5699 	int i, size = 0;
   5700 
   5701 	if (!(argc_addr = get_local(interp, 0)))
   5702 		return interp_error(interp, "strs count");
   5703 
   5704 	if (!(argv_buf_size_addr = get_local(interp, 1)))
   5705 		return interp_error(interp, "strs buf_size");
   5706 
   5707 	if (!store_i32(interp, argc_addr->num.i32, count))
   5708 		return interp_error(interp, "store argc");
   5709 
   5710 	for (i = 0; i < count; i++)
   5711 		size += strlen(strs[i])+1;
   5712 
   5713 	if (!store_i32(interp, argv_buf_size_addr->num.i32, size)) {
   5714 		return interp_error(interp, "store strs size");
   5715 	}
   5716 
   5717 	return stack_push_i32(interp, 0);
   5718 }
   5719 
   5720 static int wasi_args_get(struct wasm_interp *interp)
   5721 {
   5722 	return wasi_get_strs(interp, interp->wasi.argc, interp->wasi.argv);
   5723 }
   5724 
   5725 static int wasi_environ_get(struct wasm_interp *interp)
   5726 {
   5727 	return wasi_get_strs(interp, interp->wasi.environc,
   5728 			interp->wasi.environ);
   5729 }
   5730 
   5731 static int wasi_args_sizes_get(struct wasm_interp *interp)
   5732 {
   5733 	return wasi_strs_sizes_get(interp, interp->wasi.argc,
   5734 			interp->wasi.argv);
   5735 }
   5736 
   5737 static int wasi_environ_sizes_get(struct wasm_interp *interp)
   5738 {
   5739 	return wasi_strs_sizes_get(interp, interp->wasi.environc,
   5740 			interp->wasi.environ);
   5741 }
   5742 
   5743 
   5744 static int interp_store(struct wasm_interp *interp, struct memarg *memarg,
   5745 		enum valtype type, int N)
   5746 {
   5747 	struct val c;
   5748 	int i;
   5749 
   5750 	if (unlikely(!stack_pop_valtype(interp, type, &c)))  {
   5751 		return interp_error(interp, "pop stack");
   5752 	}
   5753 
   5754 	if (unlikely(!stack_pop_i32(interp, &i)))  {
   5755 		return interp_error(interp, "pop stack");
   5756 	}
   5757 
   5758 	return store_val(interp, i, memarg, type, &c, N);
   5759 }
   5760 
   5761 
   5762 static INLINE int interp_global_set(struct wasm_interp *interp, int global_ind)
   5763 {
   5764 	struct val *global, setval;
   5765 
   5766 	if (unlikely(!(global = get_global_inst(interp, global_ind)))) {
   5767 		return interp_error(interp, "couldn't get global %d", global_ind);
   5768 	}
   5769 
   5770 	if (unlikely(!stack_popval(interp, &setval))) {
   5771 		return interp_error(interp, "couldn't pop stack value");
   5772 	}
   5773 
   5774 	memcpy(global, &setval, sizeof(setval));
   5775 
   5776 	return 1;
   5777 }
   5778 
   5779 static INLINE int active_pages(struct wasm_interp *interp)
   5780 {
   5781 	return cursor_count(&interp->memory, WASM_PAGE_SIZE);
   5782 }
   5783 
   5784 static int interp_memory_grow(struct wasm_interp *interp, u8 memidx)
   5785 {
   5786 	int pages = 0, prev_size, grow;
   5787 
   5788 	(void)memidx;
   5789 
   5790 	if (unlikely(!has_memory_section(interp->module))) {
   5791 		return interp_error(interp, "no memory section");
   5792 	}
   5793 
   5794 	if (!stack_pop_i32(interp, &pages)) {
   5795 		return interp_error(interp, "pop pages");
   5796 	}
   5797 
   5798 	grow = pages * WASM_PAGE_SIZE;
   5799 	prev_size = active_pages(interp);
   5800 
   5801 	if (interp->memory.p + grow <= interp->memory.end) {
   5802 		interp->memory.p += grow;
   5803 		pages = prev_size;
   5804 	} else {
   5805 		pages = -1;
   5806 	}
   5807 
   5808 	return stack_push_i32(interp, pages);
   5809 }
   5810 
   5811 static INLINE int interp_memory_size(struct wasm_interp *interp, u8 memidx)
   5812 {
   5813 	(void)memidx;
   5814 
   5815 	if (unlikely(!has_memory_section(interp->module))) {
   5816 		return interp_error(interp, "no memory section");
   5817 	}
   5818 
   5819 	if (!stack_push_i32(interp, active_pages(interp))) {
   5820 		return interp_error(interp, "push memory size");
   5821 	}
   5822 
   5823 	return 1;
   5824 }
   5825 
   5826 static INLINE int interp_i32_eq(struct wasm_interp *interp)
   5827 {
   5828 	struct val lhs, rhs, c;
   5829 
   5830 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) {
   5831 		return interp_error(interp, "binop prep");
   5832 	}
   5833 
   5834 	return stack_push_i32(interp, lhs.num.i32 == rhs.num.i32);
   5835 }
   5836 
   5837 static INLINE int interp_i32_wrap_i64(struct wasm_interp *interp)
   5838 {
   5839 	int64_t n;
   5840 	if (unlikely(!stack_pop_i64(interp, &n)))
   5841 		return interp_error(interp, "pop");
   5842 	return stack_push_i32(interp, (int)n);
   5843 }
   5844 
   5845 static INLINE int interp_i32_xor(struct wasm_interp *interp)
   5846 {
   5847 	struct val lhs, rhs, c;
   5848 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   5849 		return interp_error(interp, "binop prep");
   5850 	return stack_push_i32(interp, lhs.num.i32 ^ rhs.num.i32);
   5851 }
   5852 
   5853 static INLINE int interp_i32_ne(struct wasm_interp *interp)
   5854 {
   5855 	struct val lhs, rhs, c;
   5856 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   5857 		return interp_error(interp, "binop prep");
   5858 	return stack_push_i32(interp, lhs.num.i32 != rhs.num.i32);
   5859 }
   5860 
   5861 static int interp_i64_shl(struct wasm_interp *interp)
   5862 {
   5863 	struct val lhs, rhs, c;
   5864 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5865 		return interp_error(interp, "binop prep");
   5866 	c.num.i64 = lhs.num.i64 << shiftmask64(rhs.num.i64);
   5867 	return stack_pushval(interp, &c);
   5868 }
   5869 
   5870 static int interp_i64_ne(struct wasm_interp *interp)
   5871 {
   5872 	struct val lhs, rhs, c;
   5873 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5874 		return interp_error(interp, "binop prep");
   5875 	make_i32_val(&c, lhs.num.i64 != rhs.num.i64);
   5876 	return stack_pushval(interp, &c);
   5877 }
   5878 
   5879 static int interp_i64_eq(struct wasm_interp *interp)
   5880 {
   5881 	struct val lhs, rhs, c;
   5882 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5883 		return interp_error(interp, "binop prep");
   5884 	make_i32_val(&c, lhs.num.i64 == rhs.num.i64);
   5885 	return stack_pushval(interp, &c);
   5886 }
   5887 
   5888 static int interp_i64_rem_s(struct wasm_interp *interp)
   5889 {
   5890 	struct val lhs, rhs, c;
   5891 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5892 		return interp_error(interp, "binop prep");
   5893 	c.num.i64 = lhs.num.i64 % rhs.num.i64;
   5894 	return stack_pushval(interp, &c);
   5895 }
   5896 
   5897 static int interp_i64_rem_u(struct wasm_interp *interp)
   5898 {
   5899 	struct val lhs, rhs, c;
   5900 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5901 		return interp_error(interp, "binop prep");
   5902 	c.num.u64 = lhs.num.u64 % rhs.num.u64;
   5903 	return stack_pushval(interp, &c);
   5904 }
   5905 
   5906 static int interp_i32_shr_u(struct wasm_interp *interp)
   5907 {
   5908 	struct val lhs, rhs, c;
   5909 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   5910 		return interp_error(interp, "binop prep");
   5911 	c.num.u32 = lhs.num.u32 >> shiftmask32(rhs.num.u32);
   5912 	return stack_pushval(interp, &c);
   5913 }
   5914 
   5915 static int interp_i32_shr_s(struct wasm_interp *interp)
   5916 {
   5917 	struct val lhs, rhs, c;
   5918 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   5919 		return interp_error(interp, "binop prep");
   5920 	c.num.i32 = lhs.num.i32 >> shiftmask32(rhs.num.i32);
   5921 	return stack_pushval(interp, &c);
   5922 }
   5923 
   5924 static int interp_i64_shr_u(struct wasm_interp *interp)
   5925 {
   5926 	struct val lhs, rhs, c;
   5927 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5928 		return interp_error(interp, "binop prep");
   5929 	c.num.u64 = lhs.num.u64 >> shiftmask64(rhs.num.u64);
   5930 	return stack_pushval(interp, &c);
   5931 }
   5932 
   5933 static int interp_i64_shr_s(struct wasm_interp *interp)
   5934 {
   5935 	struct val lhs, rhs, c;
   5936 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i64)))
   5937 		return interp_error(interp, "binop prep");
   5938 	c.num.i64 = lhs.num.i64 >> shiftmask64(rhs.num.i64);
   5939 	return stack_pushval(interp, &c);
   5940 }
   5941 
   5942 
   5943 static int interp_i32_shl(struct wasm_interp *interp)
   5944 {
   5945 	struct val lhs, rhs, c;
   5946 	if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32)))
   5947 		return interp_error(interp, "binop prep");
   5948 	c.num.i32 = lhs.num.i32 << shiftmask32(rhs.num.i32);
   5949 	return stack_pushval(interp, &c);
   5950 }
   5951 
   5952 #ifdef DEBUG
   5953 static void print_linestack(struct cursor *stack)
   5954 {
   5955 	struct val *val;
   5956 	int first = 1;
   5957 
   5958 	val = (struct val*)stack->p;
   5959 
   5960 	while (--val >= (struct val*)stack->start) {
   5961 		if (first) {
   5962 			first = 0;
   5963 		} else {
   5964 			printf(", ");
   5965 		}
   5966 		print_val(val);
   5967 	}
   5968 
   5969 	printf("\n");
   5970 }
   5971 
   5972 #endif
   5973 
   5974 static int interp_extend(struct wasm_interp *interp, enum valtype to,
   5975 		enum valtype from, int sign)
   5976 {
   5977 	struct val *val;
   5978 	int64_t i64;
   5979 	int i32;
   5980 	(void)sign;
   5981 
   5982 	if (unlikely(!(val = stack_topval(interp)))) {
   5983 		return interp_error(interp, "no value on stack");
   5984 	}
   5985 
   5986 	if (val->type != from) {
   5987 		return interp_error(interp,
   5988 				"value on stack is of type %s, expected %s",
   5989 				valtype_name(val->type), valtype_name(from));
   5990 	}
   5991 
   5992 	switch (from) {
   5993 	case val_i32:
   5994 		i64 = val->num.i32;
   5995 		val->num.i64 = i64;
   5996 		break;
   5997 	case val_i64:
   5998 		i32 = val->num.i64;
   5999 		val->num.i32 = i32;
   6000 		break;
   6001 	default:
   6002 		return interp_error(interp, "unhandled extend from %s to %s",
   6003 				valtype_name(from), valtype_name(to));
   6004 	}
   6005 
   6006 	val->type = to;
   6007 	return 1;
   6008 }
   6009 
   6010 static INLINE int interp_drop(struct wasm_interp *interp)
   6011 {
   6012 	return cursor_drop(&interp->stack, sizeof(struct val));
   6013 }
   6014 
   6015 static int interp_loop(struct wasm_interp *interp)
   6016 {
   6017 	struct blocktype blocktype;
   6018 	struct cursor *code;
   6019 	struct label *label;
   6020 
   6021 	if (unlikely(!(code = interp_codeptr(interp)))) {
   6022 		return interp_error(interp, "empty callstack?");
   6023 	}
   6024 
   6025 	if (unlikely(!parse_blocktype(code, &interp->errors, &blocktype))) {
   6026 		return interp_error(interp, "couldn't parse blocktype");
   6027 	}
   6028 
   6029 	if (unlikely(!push_label_checkpoint(interp, &label, i_loop, i_end))) {
   6030 		return interp_error(interp, "block label checkpoint");
   6031 	}
   6032 
   6033 	return 1;
   6034 }
   6035 
   6036 static INLINE int table_set(struct wasm_interp *interp,
   6037 		struct table_inst *table, u32 ind, struct val *val)
   6038 {
   6039 
   6040 	if (unlikely(ind >= table->num_refs)) {
   6041 		return interp_error(interp, "invalid index %d (max %d)",
   6042 				ind,
   6043 				interp->module_inst.num_tables);
   6044 	}
   6045 
   6046 	if (unlikely(table->reftype != (enum reftype)val->type)) {
   6047 		return interp_error(interp, "can't store %s ref in %s table",
   6048 				valtype_name(val->type),
   6049 				valtype_name((enum valtype)table->reftype));
   6050 	}
   6051 
   6052 	debug("setting table[%ld] ref %d to ",
   6053 	      (table - interp->module_inst.tables) / sizeof (struct table_inst),
   6054 	      ind);
   6055 #ifdef DEBUG
   6056 	print_refval(&val->ref, table->reftype);
   6057 	printf("\n");
   6058 #endif
   6059 
   6060 	memcpy(&table->refs[ind], &val->ref, sizeof(struct refval));
   6061 
   6062 	return 1;
   6063 }
   6064 
   6065 static int interp_memory_copy(struct wasm_interp *interp)
   6066 {
   6067 	int dest, src, size;
   6068 	u8 *data_src, *data_dest;
   6069 
   6070 	if (unlikely(!stack_pop_i32(interp, &size)))
   6071 		return interp_error(interp, "size");
   6072 
   6073 	if (unlikely(!stack_pop_i32(interp, &src)))
   6074 		return interp_error(interp, "byte");
   6075 
   6076 	if (unlikely(!stack_pop_i32(interp, &dest)))
   6077 		return interp_error(interp, "destination");
   6078 
   6079 	if (!(data_dest = mem_ptr(interp, dest, size)))
   6080 		return interp_error(interp, "memory copy dest out of bounds");
   6081 
   6082 	if (!(data_src = mem_ptr(interp, src, size)))
   6083 		return interp_error(interp, "memory copy src out of bounds");
   6084 
   6085 	debug("memory.copy src:%d dst:%d size:%d\n",
   6086 			src, dest, size);
   6087 
   6088 	memcpy(data_dest, data_src, size);
   6089 
   6090 	return 1;
   6091 }
   6092 
   6093 static int interp_memory_fill(struct wasm_interp *interp)
   6094 {
   6095 	int dest, byte, size;
   6096 	u8 *data;
   6097 
   6098 	if (unlikely(!stack_pop_i32(interp, &size)))
   6099 		return interp_error(interp, "size");
   6100 
   6101 	if (unlikely(!stack_pop_i32(interp, &byte)))
   6102 		return interp_error(interp, "byte");
   6103 
   6104 	if (unlikely(!stack_pop_i32(interp, &dest)))
   6105 		return interp_error(interp, "destination");
   6106 
   6107 	if (!(data = mem_ptr(interp, dest, size)))
   6108 		return interp_error(interp, "memory fill out of bounds");
   6109 
   6110 	debug("memory.fill dst:%d byte:%d size:%d\n",
   6111 			dest, byte, size);
   6112 
   6113 	memset(data, byte, size);
   6114 
   6115 	return 1;
   6116 }
   6117 
   6118 static INLINE int interp_bulk_op(struct wasm_interp *interp, struct bulk_op *op)
   6119 {
   6120 	switch (op->tag) {
   6121 	case i_memory_fill: return interp_memory_fill(interp);
   6122 	case i_memory_copy: return interp_memory_copy(interp);
   6123 	case i_table_init:
   6124 	case i_elem_drop:
   6125 	case i_table_copy:
   6126 	case i_table_grow:
   6127 	case i_table_size:
   6128 	case i_table_fill:
   6129 		return interp_error(interp, "unhandled bulk op: %s",
   6130 				bulk_op_name(op));
   6131 	}
   6132 
   6133 	return interp_error(interp, "unhandled unknown bulk op: %d", op->tag);
   6134 }
   6135 
   6136 static int interp_table_set(struct wasm_interp *interp, u32 tableidx)
   6137 {
   6138 	struct table_inst *table;
   6139 	struct val val;
   6140 	int ind;
   6141 
   6142 	if (unlikely(tableidx >= interp->module_inst.num_tables)) {
   6143 		return interp_error(interp, "tableidx oob %d (max %d)",
   6144 				tableidx,
   6145 				interp->module_inst.num_tables + 1);
   6146 	}
   6147 
   6148 	table = &interp->module_inst.tables[tableidx];
   6149 
   6150 	if (unlikely(!stack_pop_ref(interp, &val))) {
   6151 		return interp_error(interp, "pop ref");
   6152 	}
   6153 
   6154 	if (unlikely(!stack_pop_i32(interp, &ind))) {
   6155 		return interp_error(interp, "pop elem index");
   6156 	}
   6157 
   6158 	return table_set(interp, table, ind, &val);
   6159 }
   6160 
   6161 static int interp_memory_init(struct wasm_interp *interp, u32 dataidx)
   6162 {
   6163 	struct wdata *data;
   6164 	int count, src, dst;
   6165 	u32 num_data;
   6166 
   6167 	num_data = interp->module->data_section.num_datas;
   6168 	if (unlikely(dataidx >= num_data)) {
   6169 		return interp_error(interp, "invalid data index %d / %d",
   6170 				dataidx, num_data-1);
   6171 	}
   6172 
   6173 	data = &interp->module->data_section.datas[dataidx];
   6174 
   6175 	if(unlikely(!stack_pop_i32(interp, &count)))
   6176 		return interp_error(interp, "pop count");
   6177 
   6178 	if(unlikely(!stack_pop_i32(interp, &src)))
   6179 		return interp_error(interp, "pop src");
   6180 
   6181 	if(unlikely(!stack_pop_i32(interp, &dst)))
   6182 		return interp_error(interp, "pop dst");
   6183 
   6184 	if (src + count > (int)data->bytes_len) {
   6185 		return interp_error(interp, "count %d > data len %d", count,
   6186 				data->bytes_len);
   6187 	}
   6188 
   6189 	if (interp->memory.start + dst + count >= interp->memory.p) {
   6190 		return interp_error(interp, "memory write oob %d > %d",
   6191 				count, interp->memory.p - interp->memory.start);
   6192 	}
   6193 
   6194 	debug("memory_init src:%d dst:%d count:%d\n",
   6195 			src, dst, count);
   6196 
   6197 	memcpy(interp->memory.start + dst,
   6198 	       data->bytes + src,
   6199 	       count);
   6200 
   6201 	return 1;
   6202 
   6203 	/*
   6204 	for (; count; count--; dst++, src++) {
   6205 		if (unlikely(src + count > data)) {
   6206 			return interp_error(interp,
   6207 				"src %d (max %d)",
   6208 				src + count, num_data + 1);
   6209 		}
   6210 
   6211 		if (unlikely(dst + count > active_pages(interp))) {
   6212 			return interp_error(interp, "dst oob",
   6213 					dst + count,
   6214 					table->num_refs + 1);
   6215 		}
   6216 	}
   6217 	*/
   6218 	return 1;
   6219 }
   6220 
   6221 static int interp_table_init(struct wasm_interp *interp,
   6222 				  struct table_init *t)
   6223 {
   6224 	struct table_inst *table;
   6225 	struct elem_inst *elem_inst;
   6226 	int num_inits, dst, src;
   6227 
   6228 	if (unlikely(t->tableidx >= interp->module_inst.num_tables)) {
   6229 		return interp_error(interp, "tableidx oob %d (max %d)",
   6230 				t->tableidx,
   6231 				interp->module_inst.num_tables + 1);
   6232 	}
   6233 
   6234 	table = &interp->module_inst.tables[t->tableidx];
   6235 
   6236 	// TODO: elem addr ?
   6237 	if (unlikely(t->elemidx >= interp->module->element_section.num_elements)) {
   6238 		return interp_error(interp, "elemidx oob %d (max %d)",
   6239 				t->elemidx,
   6240 				interp->module->element_section.num_elements + 1);
   6241 	}
   6242 
   6243 	if (unlikely(!stack_pop_i32(interp, &num_inits))) {
   6244 		return interp_error(interp, "pop num_inits");
   6245 	}
   6246 
   6247 	if (unlikely(!stack_pop_i32(interp, &src))) {
   6248 		return interp_error(interp, "pop src");
   6249 	}
   6250 
   6251 	if (unlikely(!stack_pop_i32(interp, &dst))) {
   6252 		return interp_error(interp, "pop dst");
   6253 	}
   6254 
   6255 	for (; num_inits; num_inits--, dst++, src++) {
   6256 		if (unlikely((u32)src + num_inits > interp->module_inst.num_elements)) {
   6257 			return interp_error(interp, "index oob elem.elem s+n %d (max %d)",
   6258 					src + num_inits,
   6259 					interp->module_inst.num_elements + 1);
   6260 		}
   6261 
   6262 		if (unlikely((u32)dst + num_inits > table->num_refs)) {
   6263 			return interp_error(interp, "index oob tab.elem d+n %d (max %d)",
   6264 					dst + num_inits,
   6265 					table->num_refs + 1);
   6266 		}
   6267 
   6268 		elem_inst = &interp->module_inst.elements[src];
   6269 
   6270 		if (!table_set(interp, table, dst, &elem_inst->val)) {
   6271 			return interp_error(interp,
   6272 					"table set failed for table %d ind %d");
   6273 		}
   6274 	}
   6275 
   6276 	return 1;
   6277 }
   6278 
   6279 static int interp_select(struct wasm_interp *interp, struct select_instr *select)
   6280 {
   6281 	struct val top, bottom;
   6282 	int c;
   6283 
   6284 	(void)select;
   6285 
   6286 	if (unlikely(!stack_pop_i32(interp, &c)))
   6287 		return interp_error(interp, "pop select");
   6288 
   6289 	if (unlikely(!stack_popval(interp, &top)))
   6290 		return interp_error(interp, "pop val top");
   6291 
   6292 	if (unlikely(!stack_popval(interp, &bottom)))
   6293 		return interp_error(interp, "pop val bottom");
   6294 
   6295 	if (unlikely(top.type != bottom.type))
   6296 		return interp_error(interp, "type mismatch, %s != %s",
   6297 				valtype_name(top.type),
   6298 				valtype_name(bottom.type));
   6299 
   6300 	if (c != 0)
   6301 		return stack_pushval(interp, &bottom);
   6302 	else
   6303 		return stack_pushval(interp, &top);
   6304 }
   6305 
   6306 enum interp_end {
   6307 	interp_end_err,
   6308 	interp_end_next,
   6309 	interp_end_done,
   6310 };
   6311 
   6312 // tricky...
   6313 static int interp_end(struct wasm_interp *interp)
   6314 {
   6315 	struct callframe *frame;
   6316 	int loc_resolvers;
   6317 
   6318 	if (unlikely(!(frame = top_callframe(&interp->callframes)))) {
   6319 		debug("no callframes, done.\n");
   6320 		// no more resolvers, we done.
   6321 		return interp_end_done;
   6322 	}
   6323 
   6324 	if (unlikely(!count_local_resolvers(interp, &loc_resolvers))) {
   6325 		return interp_error(interp, "count local resolvers");
   6326 	}
   6327 
   6328 	if (loc_resolvers == 0) {
   6329 		if (!drop_callframe(interp))
   6330 			return interp_error(interp, "drop callframe at end of fn");
   6331 		return interp_end_next;
   6332 	}
   6333 
   6334 	return pop_label_checkpoint(interp);
   6335 
   6336 }
   6337 
   6338 
   6339 static int interp_instr(struct wasm_interp *interp, struct instr *instr)
   6340 {
   6341 	interp->ops++;
   6342 
   6343 	debug("%04X %-30s | ", instr->pos, show_instr(instr));
   6344 
   6345 #if DEBUG
   6346 	print_linestack(&interp->stack);
   6347 #endif
   6348 
   6349 	switch (instr->tag) {
   6350 	case i_unreachable: return interp_error(interp, "unreachable");
   6351 	case i_nop:         return 1;
   6352 	case i_select:
   6353 	case i_selects:
   6354 		return interp_select(interp, &instr->select);
   6355 
   6356 	case i_local_get:   return interp_local_get(interp, instr->i32);
   6357 	case i_local_set:   return interp_local_set(interp, instr->i32);
   6358 	case i_local_tee:   return interp_local_tee(interp, instr->i32);
   6359 	case i_global_get:  return interp_global_get(interp, instr->i32);
   6360 	case i_global_set:  return interp_global_set(interp, instr->i32);
   6361 
   6362 	case i_f32_const:   return interp_f32_const(interp, instr->f32);
   6363 	case i_f32_abs:     return interp_f32_abs(interp);
   6364 	case i_f32_div:     return interp_f32_div(interp);
   6365 	case i_f32_mul:     return interp_f32_mul(interp);
   6366 	case i_f32_neg:     return interp_f32_neg(interp);
   6367 	case i_f32_add:     return interp_f32_add(interp);
   6368 	case i_f32_sub:     return interp_f32_sub(interp);
   6369 	case i_f32_lt:      return interp_f32_lt(interp);
   6370 	case i_f32_le:      return interp_f32_le(interp);
   6371 	case i_f32_gt:      return interp_f32_gt(interp);
   6372 	case i_f32_ge:      return interp_f32_ge(interp);
   6373 	case i_f32_eq:      return interp_f32_eq(interp);
   6374 	case i_f32_ne:      return interp_f32_ne(interp);
   6375 	case i_f32_max:     return interp_f32_max(interp);
   6376 	case i_f32_min:     return interp_f32_max(interp);
   6377 	case i_f32_sqrt:    return interp_f32_sqrt(interp);
   6378 
   6379 	case i_f32_convert_i32_s:   return interp_f32_convert_i32_s(interp);
   6380 	case i_i32_reinterpret_f32: return interp_i32_reinterpret_f32(interp);
   6381 	case i_f64_promote_f32:     return interp_f64_promote_f32(interp);
   6382 	case i_i32_trunc_f64_s:     return interp_i32_trunc_f64_s(interp);
   6383 	case i_f32_demote_f64:      return interp_f32_demote_f64(interp);
   6384 	case i_f64_convert_i32_s:   return interp_f64_convert_i32_s(interp);
   6385 	case i_f64_convert_i64_u:   return interp_f64_convert_i64_u(interp);
   6386 	case i_i64_reinterpret_f64: return interp_i64_reinterpret_f64(interp);
   6387 	case i_f64_reinterpret_i64: return interp_f64_reinterpret_i64(interp);
   6388 	case i_i32_trunc_f32_s:     return interp_i32_trunc_f32_s(interp);
   6389 	case i_f32_convert_i32_u:   return interp_f32_convert_i32_u(interp);
   6390 	case i_i32_trunc_f64_u:     return interp_i32_trunc_f64_u(interp);
   6391 	case i_f64_convert_i32_u:   return interp_f64_convert_i32_u(interp);
   6392 	case i_f32_reinterpret_i32: return interp_f32_reinterpret_i32(interp);
   6393 
   6394 	case i_f64_abs:     return interp_f64_abs(interp);
   6395 	case i_f64_eq:      return interp_f64_eq(interp);
   6396 	case i_f64_ne:      return interp_f64_ne(interp);
   6397 	case i_f64_add:     return interp_f64_add(interp);
   6398 	case i_f64_neg:     return interp_f64_neg(interp);
   6399 	case i_f64_ceil:    return interp_f64_ceil(interp);
   6400 	case i_f64_floor:   return interp_f64_floor(interp);
   6401 	case i_f64_sqrt:    return interp_f64_sqrt(interp);
   6402 	case i_f64_const:   return interp_f64_const(interp, instr->f64);
   6403 	case i_f64_div:     return interp_f64_div(interp);
   6404 	case i_f64_ge:      return interp_f64_ge(interp);
   6405 	case i_f64_gt:      return interp_f64_gt(interp);
   6406 	case i_f64_le:      return interp_f64_le(interp);
   6407 	case i_f64_lt:      return interp_f64_lt(interp);
   6408 	case i_f64_mul:     return interp_f64_mul(interp);
   6409 	case i_f64_sub:     return interp_f64_sub(interp);
   6410 
   6411 	case i_i32_clz:     return interp_i32_clz(interp);
   6412 	case i_i32_ctz:     return interp_i32_ctz(interp);
   6413 	case i_i32_popcnt:  return interp_i32_popcnt(interp);
   6414 	case i_i32_eqz:     return interp_i32_eqz(interp);
   6415 	case i_i32_add:     return interp_i32_add(interp);
   6416 	case i_i32_sub:     return interp_i32_sub(interp);
   6417 	case i_i32_const:   return interp_i32_const(interp, instr->i32);
   6418 	case i_i32_div_u:   return interp_i32_div_u(interp);
   6419 	case i_i32_div_s:   return interp_i32_div_s(interp);
   6420 	case i_i32_ge_u:    return interp_i32_ge_u(interp);
   6421 	case i_i32_rotl:    return interp_i32_rotl(interp);
   6422 	case i_i32_rotr:    return interp_i32_rotr(interp);
   6423 	case i_i32_ge_s:    return interp_i32_ge_s(interp);
   6424 	case i_i32_gt_u:    return interp_i32_gt_u(interp);
   6425 	case i_i32_gt_s:    return interp_i32_gt_s(interp);
   6426 	case i_i32_le_s:    return interp_i32_le_s(interp);
   6427 	case i_i32_le_u:    return interp_i32_le_u(interp);
   6428 	case i_i32_lt_s:    return interp_i32_lt_s(interp);
   6429 	case i_i32_lt_u:    return interp_i32_lt_u(interp);
   6430 	case i_i32_shl:     return interp_i32_shl(interp);
   6431 	case i_i32_shr_u:   return interp_i32_shr_u(interp);
   6432 	case i_i32_shr_s:   return interp_i32_shr_s(interp);
   6433 	case i_i32_or:      return interp_i32_or(interp);
   6434 	case i_i32_and:     return interp_i32_and(interp);
   6435 	case i_i32_mul:     return interp_i32_mul(interp);
   6436 	case i_i32_xor:     return interp_i32_xor(interp);
   6437 	case i_i32_ne:      return interp_i32_ne(interp);
   6438 	case i_i32_rem_u:   return interp_i32_rem_u(interp);
   6439 	case i_i32_rem_s:   return interp_i32_rem_s(interp);
   6440 	case i_i32_eq:      return interp_i32_eq(interp);
   6441 	case i_i32_wrap_i64:return interp_i32_wrap_i64(interp);
   6442 
   6443 	case i_i64_clz:     return interp_i64_clz(interp);
   6444 	case i_i64_add:     return interp_i64_add(interp);
   6445 	case i_i64_and:     return interp_i64_and(interp);
   6446 	case i_i64_eqz:     return interp_i64_eqz(interp);
   6447 	case i_i64_gt_s:    return interp_i64_gt_s(interp);
   6448 	case i_i64_lt_u:    return interp_i64_lt_u(interp);
   6449 	case i_i64_lt_s:    return interp_i64_lt_s(interp);
   6450 	case i_i64_le_u:    return interp_i64_le_u(interp);
   6451 	case i_i64_le_s:    return interp_i64_le_s(interp);
   6452 	case i_i64_gt_u:    return interp_i64_gt_u(interp);
   6453 	case i_i64_ge_u:    return interp_i64_ge_u(interp);
   6454 	case i_i64_ge_s:    return interp_i64_ge_s(interp);
   6455 	case i_i64_div_u:   return interp_i64_div_u(interp);
   6456 	case i_i64_xor:     return interp_i64_xor(interp);
   6457 	case i_i64_mul:     return interp_i64_mul(interp);
   6458 	case i_i64_shl:     return interp_i64_shl(interp);
   6459 	case i_i64_ne:      return interp_i64_ne(interp);
   6460 	case i_i64_eq:      return interp_i64_eq(interp);
   6461 	case i_i64_rem_u:   return interp_i64_rem_u(interp);
   6462 	case i_i64_rem_s:   return interp_i64_rem_s(interp);
   6463 	case i_i64_shr_u:   return interp_i64_shr_u(interp);
   6464 	case i_i64_shr_s:   return interp_i64_shr_s(interp);
   6465 	case i_i64_or:      return interp_i64_or(interp);
   6466 	case i_i64_sub:     return interp_i64_sub(interp);
   6467 
   6468 	case i_i64_const:   return interp_i64_const(interp, instr->i64);
   6469 	case i_i64_extend_i32_u: return interp_extend(interp, val_i64, val_i32, 0);
   6470 	case i_i64_extend_i32_s: return interp_extend(interp, val_i64, val_i32, 1);
   6471 
   6472 	case i_i32_store:   return interp_store(interp, &instr->memarg, val_i32, 0);
   6473 	case i_i32_store8:  return interp_store(interp, &instr->memarg, val_i32, 8);
   6474 	case i_i32_store16: return interp_store(interp, &instr->memarg, val_i32, 16);
   6475 	case i_f32_store:   return interp_store(interp, &instr->memarg, val_f32, 0);
   6476 	case i_f64_store:   return interp_store(interp, &instr->memarg, val_f64, 0);
   6477 	case i_i64_store:   return interp_store(interp, &instr->memarg, val_i64, 0);
   6478 	case i_i64_store8:  return interp_store(interp, &instr->memarg, val_i64, 8);
   6479 	case i_i64_store16: return interp_store(interp, &instr->memarg, val_i64, 16);
   6480 	case i_i64_store32: return interp_store(interp, &instr->memarg, val_i64, 32);
   6481 
   6482 	case i_i32_load:     return interp_load(interp, &instr->memarg, val_i32, 0, -1);
   6483 	case i_i32_load8_s:  return interp_load(interp, &instr->memarg, val_i32, 8, 1);
   6484 	case i_i32_load8_u:  return interp_load(interp, &instr->memarg, val_i32, 8, 0);
   6485 	case i_i32_load16_s: return interp_load(interp, &instr->memarg, val_i32, 16, 1);
   6486 	case i_i32_load16_u: return interp_load(interp, &instr->memarg, val_i32, 16, 0);
   6487 	case i_f32_load:     return interp_load(interp, &instr->memarg, val_f32, 0, -1);
   6488 	case i_f64_load:     return interp_load(interp, &instr->memarg, val_f64, 0, -1);
   6489 	case i_i64_load:     return interp_load(interp, &instr->memarg, val_i64, 0, -1);
   6490 	case i_i64_load8_s:  return interp_load(interp, &instr->memarg, val_i64, 8, 1);
   6491 	case i_i64_load8_u:  return interp_load(interp, &instr->memarg, val_i64, 8, 0);
   6492 	case i_i64_load16_s: return interp_load(interp, &instr->memarg, val_i64, 16, 1);
   6493 	case i_i64_load16_u: return interp_load(interp, &instr->memarg, val_i64, 16, 0);
   6494 	case i_i64_load32_s: return interp_load(interp, &instr->memarg, val_i64, 32, 1);
   6495 	case i_i64_load32_u: return interp_load(interp, &instr->memarg, val_i64, 32, 0);
   6496 
   6497 	case i_drop: return interp_drop(interp);
   6498 	case i_loop: return interp_loop(interp);
   6499 	case i_if: return interp_if(interp);
   6500 	case i_else: return interp_else(interp);
   6501 	case i_end: return interp_end(interp);
   6502 	case i_call: return interp_call(interp, instr->i32);
   6503 	case i_call_indirect: return interp_call_indirect(interp, &instr->call_indirect);
   6504 	case i_block: return interp_block(interp);
   6505 	case i_br: return interp_br(interp, instr->i32);
   6506 	case i_br_table: return interp_br_table(interp, &instr->br_table);
   6507 	case i_br_if: return interp_br_if(interp, instr->i32);
   6508 	case i_memory_size: return interp_memory_size(interp, instr->memidx);
   6509 	case i_memory_grow: return interp_memory_grow(interp, instr->memidx);
   6510 	case i_bulk_op: return interp_bulk_op(interp, &instr->bulk_op);
   6511 	case i_table_set: return interp_table_set(interp, instr->i32);
   6512 	case i_return: return interp_return(interp);
   6513 	default:
   6514 		    interp_error(interp, "unhandled instruction %s 0x%x",
   6515 				 instr_name(instr->tag), instr->tag);
   6516 		    return 0;
   6517 	}
   6518 
   6519 	return 0;
   6520 }
   6521 
   6522 static int is_control_instr(u8 tag)
   6523 {
   6524 	switch (tag) {
   6525 		case i_if:
   6526 		case i_block:
   6527 		case i_loop:
   6528 			return 1;
   6529 	}
   6530 	return 0;
   6531 }
   6532 
   6533 
   6534 static INLINE int interp_parse_instr(struct wasm_interp *interp,
   6535 		struct cursor *code, struct expr_parser *parser,
   6536 		struct instr *instr)
   6537 {
   6538 	u8 tag;
   6539 
   6540 	if (unlikely(!pull_byte(code, &tag))) {
   6541 		return interp_error(interp, "no more instrs to pull");
   6542 	}
   6543 
   6544 
   6545 	instr->tag = tag;
   6546 	instr->pos = code->p - 1 - code->start;
   6547 
   6548 	if (is_control_instr(tag)) {
   6549 		return 1;
   6550 	}
   6551 
   6552 	parser->code = code;
   6553 	if (!parse_instr(parser, instr->tag, instr)) {
   6554 		return interp_error(interp, "parse non-control instr %s", instr_name(tag));
   6555 	}
   6556 
   6557 	return 1;
   6558 }
   6559 
   6560 static int interp_elem_drop(struct wasm_interp *interp, int elemidx)
   6561 {
   6562 	(void)interp;
   6563 	(void)elemidx;
   6564 	// we don't really need to do anything here...
   6565 	return 1;
   6566 }
   6567 
   6568 static int interp_code(struct wasm_interp *interp)
   6569 {
   6570 	struct instr instr;
   6571 	struct expr_parser parser;
   6572 	struct callframe *frame;
   6573 	int ret;
   6574 
   6575 	parser.interp = interp;
   6576 	parser.errs = &interp->errors;
   6577 
   6578 	for (;;) {
   6579 		if (unlikely(!(frame = top_callframe(&interp->callframes)))) {
   6580 			return 1;
   6581 		}
   6582 
   6583 		if (unlikely(!interp_parse_instr(interp, &frame->code, &parser,
   6584 						&instr))) {
   6585 			return interp_error(interp, "parse instr");
   6586 		}
   6587 
   6588 		//cursor_print_around(&frame->code, 10);
   6589 
   6590 		if (unlikely(!(ret = interp_instr(interp, &instr)))) {
   6591 			return interp_error(interp, "interp instr %s",
   6592 					show_instr(&instr));
   6593 		}
   6594 
   6595 		if (instr.tag == i_end) {
   6596 			//cursor_print_around(&frame->code, 10);
   6597 			switch (ret) {
   6598 				case interp_end_err: return 0;
   6599 				case interp_end_done: return 1;
   6600 				case interp_end_next: break;
   6601 			}
   6602 		}
   6603 
   6604 	}
   6605 
   6606 	return 1;
   6607 }
   6608 
   6609 static int find_function(struct module *module, const char *name)
   6610 {
   6611 	struct wexport *export;
   6612 	u32 i;
   6613 
   6614 	for (i = 0; i < module->export_section.num_exports; i++) {
   6615 		export = &module->export_section.exports[i];
   6616 		if (!strcmp(name, export->name)) {
   6617 			return export->index;
   6618 		}
   6619 	}
   6620 
   6621 	return -1;
   6622 }
   6623 
   6624 static int find_start_function(struct module *module)
   6625 {
   6626 	int res;
   6627 
   6628 	if (was_section_parsed(module, section_start)) {
   6629 		debug("getting start function from start section\n");
   6630 		return module->start_section.start_fn;
   6631 	}
   6632 
   6633 	if ((res = find_function(module, "_start")) != -1) {
   6634 		return res;
   6635 	}
   6636 
   6637 	return find_function(module, "start");
   6638 }
   6639 
   6640 void wasm_parser_init(struct wasm_parser *p, u8 *wasm, size_t wasm_len, size_t arena_size)
   6641 {
   6642 	u8 *mem;
   6643 
   6644 	mem = calloc(1, arena_size);
   6645 	assert(mem);
   6646 
   6647 	make_cursor(wasm, wasm + wasm_len, &p->cur);
   6648 	make_cursor(mem, mem + arena_size, &p->mem);
   6649 
   6650 	p->errs.enabled = 1;
   6651 
   6652 	cursor_slice(&p->mem, &p->errs.cur, 0xFFFF);
   6653 }
   6654 
   6655 static int calculate_tables_size(struct module *module)
   6656 {
   6657 	u32 i, num_tables, size;
   6658 	struct table *tables;
   6659 
   6660 	if (!was_section_parsed(module, section_table))
   6661 		return 0;
   6662 
   6663 	tables = module->table_section.tables;
   6664 	num_tables = module->table_section.num_tables;
   6665 	size = num_tables * sizeof(struct table_inst);
   6666 
   6667 	for (i = 0; i < num_tables; i++) {
   6668 		size += sizeof(struct refval) * tables[i].limits.min;
   6669 	}
   6670 
   6671 	return size;
   6672 }
   6673 
   6674 static int alloc_tables(struct wasm_interp *interp)
   6675 {
   6676 	struct table *t;
   6677 	struct table_inst *inst;
   6678 	u32 i, size;
   6679 
   6680 	if (!was_section_parsed(interp->module, section_table))
   6681 		return 1;
   6682 
   6683 	interp->module_inst.num_tables =
   6684 		interp->module->table_section.num_tables;
   6685 
   6686 	if (!(interp->module_inst.tables =
   6687 		cursor_alloc(&interp->mem, interp->module_inst.num_tables *
   6688 			     sizeof(struct table_inst)))) {
   6689 		return interp_error(interp, "couldn't alloc table instances");
   6690 	}
   6691 
   6692 	for (i = 0; i < interp->module_inst.num_tables; i++) {
   6693 		t = &interp->module->table_section.tables[i];
   6694 		inst = &interp->module_inst.tables[i];
   6695 		inst->reftype = t->reftype;
   6696 		inst->num_refs = t->limits.min;
   6697 		size = sizeof(struct refval) * t->limits.min;
   6698 
   6699 		if (!(inst->refs = cursor_alloc(&interp->mem, size))) {
   6700 			return interp_error(interp,
   6701 				"couldn't alloc table inst %d/%d",
   6702 				i+1, interp->module->table_section.num_tables);
   6703 		}
   6704 	}
   6705 
   6706 	return 1;
   6707 }
   6708 
   6709 static int init_element(struct wasm_interp *interp, struct expr *init,
   6710 		struct elem_inst *elem_inst)
   6711 {
   6712 	if (!eval_const_val(init, &interp->errors, &interp->stack, &elem_inst->val)) {
   6713 		return interp_error(interp, "failed to eval element init expr");
   6714 	}
   6715 	return 1;
   6716 }
   6717 
   6718 static int init_table(struct wasm_interp *interp, struct elem *elem,
   6719 		int elemidx, int num_elems)
   6720 {
   6721 	struct table_init t;
   6722 
   6723 	if (elem->tableidx != 0) {
   6724 		return interp_error(interp,
   6725 			"tableidx should be 0 for elem %d", elemidx);
   6726 	}
   6727 
   6728 	if (!eval_const_expr(&elem->offset, &interp->errors, &interp->stack)) {
   6729 		return interp_error(interp, "failed to eval elem offset expr");
   6730 	}
   6731 
   6732 	if (!stack_push_i32(interp, 0)) {
   6733 		return interp_error(interp, "push 0 when init element");
   6734 	}
   6735 
   6736 	if (!stack_push_i32(interp, num_elems)) {
   6737 		return interp_error(interp, "push num_elems in init element");
   6738 	}
   6739 
   6740 	t.tableidx = elem->tableidx;
   6741 	t.elemidx  = elemidx;
   6742 
   6743 	if (!interp_table_init(interp, &t)) {
   6744 		return interp_error(interp, "table init");
   6745 	}
   6746 
   6747 	if (!interp_elem_drop(interp, elemidx)) {
   6748 		return interp_error(interp, "drop elem");
   6749 	}
   6750 
   6751 	return 1;
   6752 }
   6753 
   6754 static int init_global(struct wasm_interp *interp, struct global *global,
   6755 		struct global_inst *global_inst)
   6756 {
   6757 	if (!eval_const_val(&global->init, &interp->errors, &interp->stack,
   6758 			    &global_inst->val)) {
   6759 		return interp_error(interp, "eval const expr");
   6760 	}
   6761 
   6762 	debug("init global to %s %d\n", valtype_name(global_inst->val.type),
   6763 			global_inst->val.num.i32);
   6764 
   6765 	if (cursor_top(&interp->stack, sizeof(struct val))) {
   6766 		return interp_error(interp, "stack not empty");
   6767 	}
   6768 
   6769 	return 1;
   6770 }
   6771 
   6772 static int init_globals(struct wasm_interp *interp)
   6773 {
   6774 	struct global *globals, *global;
   6775 	struct global_inst *global_insts, *global_inst;
   6776 	u32 i;
   6777 
   6778 	if (!was_section_parsed(interp->module, section_global)) {
   6779 		// nothing to init
   6780 		return 1;
   6781 	}
   6782 
   6783 	globals = interp->module->global_section.globals;
   6784 	global_insts = interp->module_inst.globals;
   6785 
   6786 	for (i = 0; i < interp->module->global_section.num_globals; i++) {
   6787 		global = &globals[i];
   6788 		global_inst = &global_insts[i];
   6789 
   6790 		if (!init_global(interp, global, global_inst)) {
   6791 			return interp_error(interp, "global init");
   6792 		}
   6793 	}
   6794 
   6795 	return 1;
   6796 }
   6797 
   6798 static int count_element_insts(struct module *module)
   6799 {
   6800 	struct elem *elem;
   6801 	u32 i, size = 0;
   6802 
   6803 	if (!was_section_parsed(module, section_element))
   6804 		return 0;
   6805 
   6806 	for (i = 0; i < module->element_section.num_elements; i++) {
   6807 		elem = &module->element_section.elements[i];
   6808 		size += elem->num_inits;
   6809 	}
   6810 
   6811 	return size;
   6812 }
   6813 
   6814 static int init_memory(struct wasm_interp *interp, struct wdata *data, int dataidx)
   6815 {
   6816 	if (!eval_const_expr(&data->active.offset_expr, &interp->errors,
   6817 				&interp->stack)) {
   6818 		return interp_error(interp, "failed to eval data offset expr");
   6819 	}
   6820 
   6821 	if (!stack_push_i32(interp, 0)) {
   6822 		return interp_error(interp, "push 0 when init element");
   6823 	}
   6824 
   6825 	if (!stack_push_i32(interp, data->bytes_len)) {
   6826 		return interp_error(interp, "push num_elems in init element");
   6827 	}
   6828 
   6829 	if (!interp_memory_init(interp, dataidx)) {
   6830 		return interp_error(interp, "table init");
   6831 	}
   6832 
   6833 	/*
   6834 	if (!interp_data_drop(interp, elemidx)) {
   6835 		return interp_error(interp, "drop elem");
   6836 	}
   6837 	*/
   6838 
   6839 	return 1;
   6840 }
   6841 
   6842 static int init_memories(struct wasm_interp *interp)
   6843 {
   6844 	struct wdata *data;
   6845 	u32 i;
   6846 
   6847 	debug("init memories\n");
   6848 
   6849 	if (!was_section_parsed(interp->module, section_data))
   6850 		return 1;
   6851 
   6852 	if (!was_section_parsed(interp->module, section_memory))
   6853 		return 1;
   6854 
   6855 	for (i = 0; i < interp->module->data_section.num_datas; i++) {
   6856 		data = &interp->module->data_section.datas[i];
   6857 
   6858 		if (data->mode != datamode_active)
   6859 			continue;
   6860 
   6861 		if (!init_memory(interp, data, i)) {
   6862 			return interp_error(interp, "init memory %d failed", i);
   6863 		}
   6864 	}
   6865 
   6866 	return 1;
   6867 }
   6868 
   6869 static int init_tables(struct wasm_interp *interp)
   6870 {
   6871 	struct elem *elem;
   6872 	u32 i;
   6873 
   6874 	if (!was_section_parsed(interp->module, section_table))
   6875 		return 1;
   6876 
   6877 	for (i = 0; i < interp->module->element_section.num_elements; i++) {
   6878 		elem = &interp->module->element_section.elements[i];
   6879 
   6880 		if (elem->mode != elem_mode_active)
   6881 			continue;
   6882 
   6883 		if (!init_table(interp, elem, i, elem->num_inits)) {
   6884 			return interp_error(interp, "init table failed");
   6885 		}
   6886 	}
   6887 
   6888 	return 1;
   6889 }
   6890 
   6891 static int init_elements(struct wasm_interp *interp)
   6892 {
   6893 	struct elem *elems, *elem;
   6894 	struct elem_inst *inst;
   6895 	struct expr *init;
   6896 	u32 count = 0;
   6897 	u32 i, j;
   6898 
   6899 	debug("init elements\n");
   6900 
   6901 	if (!was_section_parsed(interp->module, section_element))
   6902 		return 1;
   6903 
   6904 	elems = interp->module->element_section.elements;
   6905 
   6906 	for (i = 0; i < interp->module->element_section.num_elements; i++) {
   6907 		elem = &elems[i];
   6908 
   6909 		if (elem->mode != elem_mode_active)
   6910 			continue;
   6911 
   6912 		for (j = 0; j < elem->num_inits; j++, count++) {
   6913 			init = &elem->inits[j];
   6914 
   6915 			assert(count < interp->module_inst.num_elements);
   6916 			inst = &interp->module_inst.elements[count];
   6917 			inst->elem = i;
   6918 			inst->init = j;
   6919 
   6920 			if (!init_element(interp, init, inst)) {
   6921 				return interp_error(interp, "init element %d", j);
   6922 			}
   6923 		}
   6924 
   6925 	}
   6926 
   6927 	return 1;
   6928 }
   6929 
   6930 // https://webassembly.github.io/spec/core/exec/modules.html#instantiation
   6931 static int instantiate_module(struct wasm_interp *interp)
   6932 {
   6933 	int func;
   6934 	//TODO:Assert module is valid with external types classifying its imports
   6935 
   6936 	// TODO: If the number # of imports is not equal to the number of provided external values then fail
   6937 
   6938 	/*
   6939 	if (!push_aux_callframe(interp)) {
   6940 		return interp_error(interp,
   6941 			"failed to pushed aux callframe?? "
   6942 			"ok if this happens seriously wtf why am I even"
   6943 			" writing this error message..)";
   6944 	}
   6945 	*/
   6946 
   6947 	func = interp->module_inst.start_fn != -1
   6948 	     ? interp->module_inst.start_fn
   6949 	     : find_start_function(interp->module);
   6950 
   6951 	/*
   6952 	memset(interp->module_inst.globals, 0,
   6953 			interp->module_inst.num_globals *
   6954 			sizeof(*interp->module_inst.globals));
   6955 
   6956 	memset(interp->module_inst.globals_init, 0,
   6957 			interp->module_inst.num_globals);
   6958 			*/
   6959 
   6960 	if (func == -1) {
   6961 		return interp_error(interp, "no start function found");
   6962 	} else {
   6963 		interp->module_inst.start_fn = func;
   6964 		debug("found start function %s (%d)\n",
   6965 				get_function_name(interp->module, func), func);
   6966 	}
   6967 
   6968 	if (!init_memories(interp)) {
   6969 		return interp_error(interp, "memory init");
   6970 	}
   6971 
   6972 	if (!init_elements(interp)) {
   6973 		return interp_error(interp, "elements init");
   6974 	}
   6975 
   6976 	if (!init_tables(interp)) {
   6977 		return interp_error(interp, "table init");
   6978 	}
   6979 
   6980 	if (!init_globals(interp)) {
   6981 		return interp_error(interp, "globals init");
   6982 	}
   6983 
   6984 	return 1;
   6985 }
   6986 
   6987 static int reset_memory(struct wasm_interp *interp)
   6988 {
   6989 	int pages, num_mems;
   6990 
   6991 	num_mems = was_section_parsed(interp->module, section_memory)?
   6992 		interp->module->memory_section.num_mems : 0;
   6993 
   6994 	reset_cursor(&interp->memory);
   6995 
   6996 	if (num_mems == 1) {
   6997 		pages = interp->module->memory_section.mems[0].min;
   6998 
   6999 		if (pages == 0)
   7000 			return 1;
   7001 
   7002 		if (!cursor_malloc(&interp->memory, pages * WASM_PAGE_SIZE)) {
   7003 			return interp_error(interp,
   7004 					"could not alloc %d memory pages",
   7005 					pages);
   7006 		}
   7007 
   7008 		assert(interp->memory.p > interp->memory.start);
   7009 		// I technically need this...
   7010 		//memset(interp->memory.start, 0, pages * WASM_PAGE_SIZE);
   7011 	}
   7012 
   7013 	return 1;
   7014 }
   7015 
   7016 void setup_wasi(struct wasm_interp *interp, int argc,
   7017 		const char **argv, char **env)
   7018 {
   7019 	char **s = env;
   7020 
   7021 	interp->wasi.argc = argc;
   7022 	interp->wasi.argv = argv;
   7023 
   7024 	interp->wasi.environ = (const char**)env;
   7025 	interp->wasi.environc = 0;
   7026 	if (env)
   7027 		for (; *s; s++, interp->wasi.environc++);
   7028 }
   7029 
   7030 int wasm_interp_init(struct wasm_interp *interp, struct module *module)
   7031 {
   7032 	unsigned char *mem, *heap, *start;
   7033 
   7034 	unsigned int ok, fns, errors_size, stack_size, locals_size,
   7035 	    callframes_size, resolver_size, labels_size, num_labels_size,
   7036 	    labels_capacity, memsize, memory_pages_size,
   7037 	    resolver_offsets_size, num_mems, globals_size, num_globals,
   7038 	    tables_size, elems_size, num_elements;
   7039 
   7040 	memset(interp, 0, sizeof(*interp));
   7041 
   7042 	setup_wasi(interp, 0, NULL, NULL);
   7043 
   7044 	interp->quitting = 0;
   7045 	interp->module = module;
   7046 
   7047 	interp->module_inst.start_fn = -1;
   7048 
   7049 	interp->prev_resolvers = 0;
   7050 
   7051 	//stack = calloc(1, STACK_SPACE);
   7052 	fns = module->num_funcs;
   7053 	labels_capacity  = fns * MAX_LABELS;
   7054 	debug("%d fns, labels capacity %d\n", fns, labels_capacity);
   7055 
   7056 	num_mems = was_section_parsed(module, section_memory)?
   7057 		module->memory_section.num_mems : 0;
   7058 
   7059 	num_globals = was_section_parsed(module, section_global)?
   7060 		module->global_section.num_globals : 0;
   7061 
   7062 	// TODO: make memory limits configurable
   7063 	errors_size      = 0xFFF;
   7064 	stack_size       = sizeof(struct val) * 0xFF;
   7065  	labels_size      = labels_capacity * sizeof(struct label);
   7066  	num_labels_size  = fns * sizeof(u16);
   7067 	resolver_offsets_size = sizeof(int) * 2048;
   7068 	callframes_size  = sizeof(struct callframe) * 2048;
   7069 	resolver_size    = sizeof(struct resolver) * MAX_LABELS * 32;
   7070 	globals_size     = sizeof(struct global_inst) * num_globals;
   7071 
   7072 	num_elements     = count_element_insts(module);
   7073 	elems_size       = num_elements * sizeof(struct elem_inst);
   7074 	locals_size      = 1024 * 1024 * 5; // 5MB stack?
   7075 	tables_size      = calculate_tables_size(module);
   7076 
   7077 	if (num_mems > 1) {
   7078 		printf("more than one memory instance is not supported\n");
   7079 		return 0;
   7080 	}
   7081 
   7082 	memory_pages_size = 64 * 256 * WASM_PAGE_SIZE; /* 1 gb virt */
   7083 
   7084 	memsize =
   7085 		stack_size +
   7086 		errors_size +
   7087 		resolver_offsets_size +
   7088 		resolver_size +
   7089 		callframes_size +
   7090 		globals_size +
   7091 		num_globals +
   7092 		labels_size +
   7093 		num_labels_size +
   7094 		locals_size +
   7095 		tables_size +
   7096 		elems_size
   7097 		;
   7098 
   7099 	mem = calloc(1, memsize);
   7100 	heap = malloc(memory_pages_size);
   7101 
   7102 	make_cursor(mem, mem + memsize, &interp->mem);
   7103 	make_cursor(heap, heap + memory_pages_size, &interp->memory);
   7104 
   7105 	// enable error reporting by default
   7106 	interp->errors.enabled = 1;
   7107 
   7108 	start = interp->mem.p;
   7109 
   7110 	ok = cursor_slice(&interp->mem, &interp->stack, stack_size);
   7111 	assert(interp->mem.p - start == stack_size);
   7112 
   7113 	start = interp->mem.p;
   7114 	ok = ok && cursor_slice(&interp->mem, &interp->errors.cur, errors_size);
   7115 	assert(interp->mem.p - start == errors_size);
   7116 
   7117 	start = interp->mem.p;
   7118 	ok = ok && cursor_slice(&interp->mem, &interp->resolver_offsets, resolver_offsets_size);
   7119 	assert(interp->mem.p - start == resolver_offsets_size);
   7120 
   7121 	start = interp->mem.p;
   7122 	ok = ok && cursor_slice(&interp->mem, &interp->resolver_stack, resolver_size);
   7123 	assert(interp->mem.p - start == resolver_size);
   7124 
   7125 	start = interp->mem.p;
   7126 	ok = ok && cursor_slice(&interp->mem, &interp->callframes, callframes_size);
   7127 	assert(interp->mem.p - start == callframes_size);
   7128 
   7129 	interp->module_inst.num_globals = num_globals;
   7130 
   7131 	start = interp->mem.p;
   7132 	ok = ok && (interp->module_inst.globals = cursor_alloc(&interp->mem, globals_size));
   7133 	assert(interp->mem.p - start == globals_size);
   7134 
   7135 	start = interp->mem.p;
   7136 	ok = ok && (interp->module_inst.globals_init = cursor_alloc(&interp->mem, num_globals));
   7137 	assert(interp->mem.p - start == num_globals);
   7138 
   7139 	start = interp->mem.p;
   7140 	ok = ok && cursor_slice(&interp->mem, &interp->labels, labels_size);
   7141 	assert(interp->mem.p - start == labels_size);
   7142 
   7143 	start = interp->mem.p;
   7144 	ok = ok && alloc_tables(interp);
   7145 	assert(interp->mem.p - start == tables_size);
   7146 
   7147 	start = interp->mem.p;
   7148 	ok = ok && cursor_slice(&interp->mem, &interp->num_labels, num_labels_size);
   7149 	assert(interp->mem.p - start == num_labels_size);
   7150 
   7151 	start = interp->mem.p;
   7152 	ok = ok && cursor_slice(&interp->mem, &interp->locals, locals_size);
   7153 	assert(interp->mem.p - start == locals_size);
   7154 
   7155 	interp->module_inst.num_elements = num_elements;
   7156 
   7157 	start = interp->mem.p;
   7158 	ok = ok && (interp->module_inst.elements =
   7159 			cursor_alloc(&interp->mem, elems_size));
   7160 	assert(interp->mem.p - start == elems_size);
   7161 
   7162 	/* init memory pages */
   7163 	assert((interp->mem.end - interp->mem.start) == memsize);
   7164 
   7165 	if (!ok) {
   7166 		return interp_error(interp, "not enough memory");
   7167 	}
   7168 
   7169 	return 1;
   7170 }
   7171 
   7172 void wasm_parser_free(struct wasm_parser *parser)
   7173 {
   7174 	free(parser->mem.start);
   7175 }
   7176 
   7177 void wasm_interp_free(struct wasm_interp *interp)
   7178 {
   7179 	free(interp->mem.start);
   7180 	free(interp->memory.start);
   7181 }
   7182 
   7183 int interp_wasm_module(struct wasm_interp *interp, int *retval)
   7184 {
   7185 	interp->ops = 0;
   7186 	*retval = 0;
   7187 
   7188 	if (interp->module->code_section.num_funcs == 0) {
   7189 		interp_error(interp, "empty module");
   7190 		return 0;
   7191 	}
   7192 
   7193 	// reset cursors
   7194 	reset_cursor(&interp->stack);
   7195 	reset_cursor(&interp->resolver_stack);
   7196 	reset_cursor(&interp->resolver_offsets);
   7197 	reset_cursor(&interp->errors.cur);
   7198 	reset_cursor(&interp->callframes);
   7199 
   7200 	// don't reset labels for perf!
   7201 
   7202 	if (!reset_memory(interp))
   7203 		return interp_error(interp, "reset memory");
   7204 
   7205 	if (!instantiate_module(interp))
   7206 		return interp_error(interp, "instantiate module");
   7207 
   7208 	//interp->mem.p = interp->mem.start;
   7209 
   7210 	if (!call_function(interp, interp->module_inst.start_fn)) {
   7211 		return interp_error(interp, "call start function");
   7212 	}
   7213 
   7214 	if (interp_code(interp)) {
   7215 		stack_pop_i32(interp, retval);
   7216 		debug("interp success!!\n");
   7217 	} else if (interp->quitting) {
   7218 		stack_pop_i32(interp, retval);
   7219 		debug("process exited\n");
   7220 	} else {
   7221 		*retval = 8;
   7222 		return interp_error(interp, "interp_code");
   7223 	}
   7224 
   7225 	return 1;
   7226 }
   7227 
   7228 int run_wasm(unsigned char *wasm, unsigned long len,
   7229 		int argc, const char **argv, char **env,
   7230 		int *retval)
   7231 {
   7232 	struct wasm_parser p;
   7233 	struct wasm_interp interp;
   7234 
   7235 	wasm_parser_init(&p, wasm, len, len * 16);
   7236 
   7237 	if (!parse_wasm(&p)) {
   7238 		wasm_parser_free(&p);
   7239 		return 0;
   7240 	}
   7241 
   7242 	if (!wasm_interp_init(&interp, &p.module)) {
   7243 		print_error_backtrace(&interp.errors);
   7244 		return 0;
   7245 	}
   7246 
   7247 	setup_wasi(&interp, argc, argv, env);
   7248 
   7249 	if (!interp_wasm_module(&interp, retval)) {
   7250 		print_callstack(&interp);
   7251 		print_error_backtrace(&interp.errors);
   7252 	}
   7253 
   7254 	print_stack(&interp.stack);
   7255 	wasm_interp_free(&interp);
   7256 	wasm_parser_free(&p);
   7257 
   7258 	return 1;
   7259 }