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