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