protoverse

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

wasm.c (177952B)


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