damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

wasm.c (177897B)


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