authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-22 16:36:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-06 12:15:04-07:00
log6337808e65fd274fa15acf9df051136661cba515
tree2aab9fc1cfdf8f5579c1c06d18f6a96401d9df95
parente9d9be2902e63a389531f2ce2197766398c281d6

update zig1.c to latest zig-wasi


1 files changed, 1837 insertions(+), 1808 deletions(-)

stage1/zig1.c+1837-1808
......@@ -223,7 +223,7 @@ static struct ByteSlice read_file_alloc(const char *file_path) {
223223
224224
225225struct Preopen {
226 int wasi_fd;
226 int wasi_fd;
227227 int host_fd;
228228 const char *name;
229229 size_t name_len;
......@@ -259,10 +259,6 @@ static uint16_t read_u16_le(const char *ptr) {
259259 (((uint64_t)u8_ptr[1]) << 0x08);
260260}
261261
262static int16_t read_i16_le(const char *ptr) {
263 return read_u16_le(ptr);
264}
265
266262static uint32_t read_u32_le(const char *ptr) {
267263 const uint8_t *u8_ptr = (const uint8_t *)ptr;
268264 return
......@@ -272,10 +268,6 @@ static uint32_t read_u32_le(const char *ptr) {
272268 (((uint64_t)u8_ptr[3]) << 0x18);
273269}
274270
275static uint32_t read_i32_le(const char *ptr) {
276 return read_u32_le(ptr);
277}
278
279271static uint64_t read_u64_le(const char *ptr) {
280272 const uint8_t *u8_ptr = (const uint8_t *)ptr;
281273 return
......@@ -383,19 +375,21 @@ enum Op {
383375 Op_br_void,
384376 Op_br_32,
385377 Op_br_64,
386 Op_br_if_nez_void,
387 Op_br_if_nez_32,
388 Op_br_if_nez_64,
389 Op_br_if_eqz_void,
390 Op_br_if_eqz_32,
391 Op_br_if_eqz_64,
378 Op_br_nez_void,
379 Op_br_nez_32,
380 Op_br_nez_64,
381 Op_br_eqz_void,
382 Op_br_eqz_32,
383 Op_br_eqz_64,
392384 Op_br_table_void,
393385 Op_br_table_32,
394386 Op_br_table_64,
395387 Op_return_void,
396388 Op_return_32,
397389 Op_return_64,
398 Op_call,
390 Op_call_import,
391 Op_call_func,
392 Op_call_indirect,
399393 Op_drop_32,
400394 Op_drop_64,
401395 Op_select_32,
......@@ -410,12 +404,160 @@ enum Op {
410404 Op_global_get_32,
411405 Op_global_set_0_32,
412406 Op_global_set_32,
407 Op_load_0_8,
408 Op_load_8,
409 Op_load_0_16,
410 Op_load_16,
411 Op_load_0_32,
412 Op_load_32,
413 Op_load_0_64,
414 Op_load_64,
415 Op_store_0_8,
416 Op_store_8,
417 Op_store_0_16,
418 Op_store_16,
419 Op_store_0_32,
420 Op_store_32,
421 Op_store_0_64,
422 Op_store_64,
423 Op_mem_size,
424 Op_mem_grow,
425 Op_const_0_32,
426 Op_const_0_64,
427 Op_const_1_32,
428 Op_const_1_64,
413429 Op_const_32,
414430 Op_const_64,
431 Op_const_umax_32,
432 Op_const_umax_64,
433 Op_eqz_32,
434 Op_eq_32,
435 Op_ne_32,
436 Op_slt_32,
437 Op_ult_32,
438 Op_sgt_32,
439 Op_ugt_32,
440 Op_sle_32,
441 Op_ule_32,
442 Op_sge_32,
443 Op_uge_32,
444 Op_eqz_64,
445 Op_eq_64,
446 Op_ne_64,
447 Op_slt_64,
448 Op_ult_64,
449 Op_sgt_64,
450 Op_ugt_64,
451 Op_sle_64,
452 Op_ule_64,
453 Op_sge_64,
454 Op_uge_64,
455 Op_feq_32,
456 Op_fne_32,
457 Op_flt_32,
458 Op_fgt_32,
459 Op_fle_32,
460 Op_fge_32,
461 Op_feq_64,
462 Op_fne_64,
463 Op_flt_64,
464 Op_fgt_64,
465 Op_fle_64,
466 Op_fge_64,
467 Op_clz_32,
468 Op_ctz_32,
469 Op_popcnt_32,
415470 Op_add_32,
471 Op_sub_32,
472 Op_mul_32,
473 Op_sdiv_32,
474 Op_udiv_32,
475 Op_srem_32,
476 Op_urem_32,
416477 Op_and_32,
417 Op_wasm,
418 Op_wasm_prefixed,
478 Op_or_32,
479 Op_xor_32,
480 Op_shl_32,
481 Op_ashr_32,
482 Op_lshr_32,
483 Op_rol_32,
484 Op_ror_32,
485 Op_clz_64,
486 Op_ctz_64,
487 Op_popcnt_64,
488 Op_add_64,
489 Op_sub_64,
490 Op_mul_64,
491 Op_sdiv_64,
492 Op_udiv_64,
493 Op_srem_64,
494 Op_urem_64,
495 Op_and_64,
496 Op_or_64,
497 Op_xor_64,
498 Op_shl_64,
499 Op_ashr_64,
500 Op_lshr_64,
501 Op_rol_64,
502 Op_ror_64,
503 Op_fabs_32,
504 Op_fneg_32,
505 Op_ceil_32,
506 Op_floor_32,
507 Op_trunc_32,
508 Op_nearest_32,
509 Op_sqrt_32,
510 Op_fadd_32,
511 Op_fsub_32,
512 Op_fmul_32,
513 Op_fdiv_32,
514 Op_fmin_32,
515 Op_fmax_32,
516 Op_copysign_32,
517 Op_fabs_64,
518 Op_fneg_64,
519 Op_ceil_64,
520 Op_floor_64,
521 Op_trunc_64,
522 Op_nearest_64,
523 Op_sqrt_64,
524 Op_fadd_64,
525 Op_fsub_64,
526 Op_fmul_64,
527 Op_fdiv_64,
528 Op_fmin_64,
529 Op_fmax_64,
530 Op_copysign_64,
531 Op_ftos_32_32,
532 Op_ftou_32_32,
533 Op_ftos_32_64,
534 Op_ftou_32_64,
535 Op_sext_64_32,
536 Op_ftos_64_32,
537 Op_ftou_64_32,
538 Op_ftos_64_64,
539 Op_ftou_64_64,
540 Op_stof_32_32,
541 Op_utof_32_32,
542 Op_stof_32_64,
543 Op_utof_32_64,
544 Op_ftof_32_64,
545 Op_stof_64_32,
546 Op_utof_64_32,
547 Op_stof_64_64,
548 Op_utof_64_64,
549 Op_ftof_64_32,
550 Op_sext8_32,
551 Op_sext16_32,
552 Op_sext8_64,
553 Op_sext16_64,
554 Op_sext32_64,
555 Op_memcpy,
556 Op_memset,
557
558 Op_wrap_32_64 = Op_drop_32,
559 Op_zext_64_32 = Op_const_0_32,
560 Op_last = Op_memset,
419561};
420562
421563enum WasmOp {
......@@ -638,13 +780,11 @@ struct TypeInfo {
638780};
639781
640782struct Function {
783 uint32_t id;
641784 // Index to start of code in opcodes/operands.
642785 struct ProgramCounter entry_pc;
643786 uint32_t type_idx;
644 uint32_t locals_count;
645 // multi-word bitset with vm->types[type_idx].param_count + locals_count bits
646 // indexed from lsb of the first element, 0 -> 32-bit, 1 -> 64-bit
647 uint32_t *local_types;
787 uint32_t locals_size;
648788};
649789
650790enum ImpMod {
......@@ -688,7 +828,7 @@ struct Import {
688828};
689829
690830struct VirtualMachine {
691 uint64_t *stack;
831 uint32_t *stack;
692832 /// Points to one after the last stack item.
693833 uint32_t stack_top;
694834 struct ProgramCounter pc;
......@@ -869,7 +1009,6 @@ static enum wasi_errno_t finish_wasi_stat(struct VirtualMachine *vm,
8691009 write_u64_le(vm->memory + buf + 0x30, to_wasi_timestamp(st.st_mtim));
8701010 write_u64_le(vm->memory + buf + 0x38, to_wasi_timestamp(st.st_ctim));
8711011#endif
872
8731012 return WASI_ESUCCESS;
8741013}
8751014
......@@ -890,7 +1029,7 @@ static enum wasi_errno_t wasi_args_sizes_get(struct VirtualMachine *vm,
8901029
8911030/// extern fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
8921031static enum wasi_errno_t wasi_args_get(struct VirtualMachine *vm,
893 uint32_t argv, uint32_t argv_buf)
1032 uint32_t argv, uint32_t argv_buf)
8941033{
8951034 uint32_t argv_buf_i = 0;
8961035 uint32_t arg_i = 0;
......@@ -910,7 +1049,7 @@ static enum wasi_errno_t wasi_args_get(struct VirtualMachine *vm,
9101049
9111050/// extern fn random_get(buf: [*]u8, buf_len: usize) errno_t;
9121051static enum wasi_errno_t wasi_random_get(struct VirtualMachine *vm,
913 uint32_t buf, uint32_t buf_len)
1052 uint32_t buf, uint32_t buf_len)
9141053{
9151054#ifdef __linux__
9161055 if (getrandom(vm->memory + buf, buf_len, 0) != buf_len) {
......@@ -1181,7 +1320,7 @@ static enum wasi_errno_t wasi_clock_time_get(struct VirtualMachine *vm,
11811320
11821321///pub extern "wasi_snapshot_preview1" fn debug(string: [*:0]const u8, x: u64) void;
11831322void wasi_debug(struct VirtualMachine *vm, uint32_t text, uint64_t n) {
1184 fprintf(stderr, "wasi_debug: '%s' number=%" PRIu64" %" PRIx64 "\n", vm->memory + text, n, n);
1323 fprintf(stderr, "wasi_debug: '%s' number=%" PRIu64 " %" PRIx64 "\n", vm->memory + text, n, n);
11851324}
11861325
11871326/// pub extern "wasi_snapshot_preview1" fn debug_slice(ptr: [*]const u8, len: usize) void;
......@@ -1189,9 +1328,15 @@ void wasi_debug_slice(struct VirtualMachine *vm, uint32_t ptr, uint32_t len) {
11891328 fprintf(stderr, "wasi_debug_slice: '%.*s'\n", len, vm->memory + ptr);
11901329}
11911330
1331enum StackType {
1332 ST_32,
1333 ST_64,
1334};
1335
11921336struct Label {
11931337 enum WasmOp opcode;
1194 uint32_t stack_depth;
1338 uint32_t stack_index;
1339 uint32_t stack_offset;
11951340 struct TypeInfo type_info;
11961341 // this is a UINT32_MAX terminated linked list that is stored in the operands array
11971342 uint32_t ref_list;
......@@ -1209,7 +1354,7 @@ static uint32_t Label_operandCount(const struct Label *label) {
12091354 }
12101355}
12111356
1212static bool Label_operandType(const struct Label *label, uint32_t index) {
1357static enum StackType Label_operandType(const struct Label *label, uint32_t index) {
12131358 if (label->opcode == WasmOp_loop) {
12141359 return bs_isSet(&label->type_info.param_types, index);
12151360 } else {
......@@ -1217,29 +1362,69 @@ static bool Label_operandType(const struct Label *label, uint32_t index) {
12171362 }
12181363}
12191364
1220static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint32_t *code_i,
1221 struct ProgramCounter *pc)
1365#define max_stack_depth (1 << 12)
1366
1367struct StackInfo {
1368 uint32_t top_index;
1369 uint32_t top_offset;
1370 uint32_t types[max_stack_depth >> 5];
1371 uint32_t offsets[max_stack_depth];
1372};
1373
1374static enum StackType si_top(const struct StackInfo *si) {
1375 return bs_isSet(si->types, si->top_index - 1);
1376}
1377
1378static enum StackType si_local(const struct StackInfo *si, uint32_t local_idx) {
1379 return bs_isSet(si->types, local_idx);
1380}
1381
1382static void si_push(struct StackInfo *si, enum StackType entry_type) {
1383 bs_setValue(si->types, si->top_index, entry_type);
1384 si->offsets[si->top_index] = si->top_offset;
1385 si->top_index += 1;
1386 si->top_offset += 1 + entry_type;
1387}
1388
1389static void si_pop(struct StackInfo *si, enum StackType entry_type) {
1390 assert(si_top(si) == entry_type);
1391 si->top_index -= 1;
1392 si->top_offset -= 1 + entry_type;
1393 assert(si->top_offset == si->offsets[si->top_index]);
1394}
1395
1396static void vm_decodeCode(struct VirtualMachine *vm, struct TypeInfo *func_type_info,
1397 uint32_t *code_i, struct ProgramCounter *pc, struct StackInfo *stack)
12221398{
12231399 const char *mod_ptr = vm->mod_ptr;
12241400 uint8_t *opcodes = vm->opcodes;
12251401 uint32_t *operands = vm->operands;
1226 struct TypeInfo *func_type_info = &vm->types[func->type_idx];
12271402
1228 uint32_t unreachable_depth = 0;
1229 uint32_t stack_depth = func_type_info->param_count + func->locals_count + 2;
1230 static uint32_t stack_types[1 << (12 - 3)];
1403 // push return address
1404 uint32_t frame_size = stack->top_offset;
1405 si_push(stack, ST_32);
1406 si_push(stack, ST_32);
12311407
1408 uint32_t unreachable_depth = 0;
1409 uint32_t label_i = 0;
12321410 static struct Label labels[1 << 9];
12331411#ifndef NDEBUG
12341412 memset(labels, 0xaa, sizeof(struct Label) * (1 << 9)); // to match the zig version
12351413#endif
1236 uint32_t label_i = 0;
12371414 labels[label_i].opcode = WasmOp_block;
1238 labels[label_i].stack_depth = stack_depth;
1239 labels[label_i].type_info = vm->types[func->type_idx];
1415 labels[label_i].stack_index = stack->top_index;
1416 labels[label_i].stack_offset = stack->top_offset;
1417 labels[label_i].type_info = *func_type_info;
12401418 labels[label_i].ref_list = UINT32_MAX;
12411419
1420 enum {
1421 State_default,
1422 State_bool_not,
1423 } state = State_default;
1424
12421425 for (;;) {
1426 assert(stack->top_index >= labels[0].stack_index);
1427 assert(stack->top_offset >= labels[0].stack_offset);
12431428 enum WasmOp opcode = (uint8_t)mod_ptr[*code_i];
12441429 *code_i += 1;
12451430 enum WasmPrefixedOp prefixed_opcode;
......@@ -1248,8 +1433,7 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
12481433 //fprintf(stderr, "decodeCode opcode=0x%x pc=%u:%u\n", opcode, pc->opcode, pc->operand);
12491434 //struct ProgramCounter old_pc = *pc;
12501435
1251 uint32_t initial_stack_depth = stack_depth;
1252 if (unreachable_depth == 0) {
1436 if (unreachable_depth == 0)
12531437 switch (opcode) {
12541438 case WasmOp_unreachable:
12551439 case WasmOp_nop:
......@@ -1258,58 +1442,62 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
12581442 case WasmOp_else:
12591443 case WasmOp_end:
12601444 case WasmOp_br:
1261 case WasmOp_call:
12621445 case WasmOp_return:
1263 break;
1446 case WasmOp_call:
1447 case WasmOp_local_get:
1448 case WasmOp_local_set:
1449 case WasmOp_local_tee:
1450 case WasmOp_global_get:
1451 case WasmOp_global_set:
1452 case WasmOp_drop:
1453 case WasmOp_select:
1454 break; // handled manually below
12641455
12651456 case WasmOp_if:
12661457 case WasmOp_br_if:
12671458 case WasmOp_br_table:
12681459 case WasmOp_call_indirect:
1269 case WasmOp_drop:
1270 case WasmOp_local_set:
1271 case WasmOp_global_set:
1272 stack_depth -= 1;
1460 si_pop(stack, ST_32);
12731461 break;
12741462
1275 case WasmOp_select:
1276 stack_depth -= 2;
1277 break;
1278
1279 case WasmOp_local_get:
1280 case WasmOp_global_get:
12811463 case WasmOp_memory_size:
12821464 case WasmOp_i32_const:
1283 case WasmOp_i64_const:
12841465 case WasmOp_f32_const:
1466 si_push(stack, ST_32);
1467 break;
1468
1469 case WasmOp_i64_const:
12851470 case WasmOp_f64_const:
1286 stack_depth += 1;
1471 si_push(stack, ST_64);
12871472 break;
12881473
1289 case WasmOp_local_tee:
12901474 case WasmOp_i32_load:
1291 case WasmOp_i64_load:
12921475 case WasmOp_f32_load:
1293 case WasmOp_f64_load:
12941476 case WasmOp_i32_load8_s:
12951477 case WasmOp_i32_load8_u:
12961478 case WasmOp_i32_load16_s:
12971479 case WasmOp_i32_load16_u:
1480 si_pop(stack, ST_32);
1481 si_push(stack, ST_32);
1482 break;
1483
1484 case WasmOp_i64_load:
1485 case WasmOp_f64_load:
12981486 case WasmOp_i64_load8_s:
12991487 case WasmOp_i64_load8_u:
13001488 case WasmOp_i64_load16_s:
13011489 case WasmOp_i64_load16_u:
13021490 case WasmOp_i64_load32_s:
13031491 case WasmOp_i64_load32_u:
1492 si_pop(stack, ST_32);
1493 si_push(stack, ST_64);
1494 break;
1495
13041496 case WasmOp_memory_grow:
13051497 case WasmOp_i32_eqz:
13061498 case WasmOp_i32_clz:
13071499 case WasmOp_i32_ctz:
13081500 case WasmOp_i32_popcnt:
1309 case WasmOp_i64_eqz:
1310 case WasmOp_i64_clz:
1311 case WasmOp_i64_ctz:
1312 case WasmOp_i64_popcnt:
13131501 case WasmOp_f32_abs:
13141502 case WasmOp_f32_neg:
13151503 case WasmOp_f32_ceil:
......@@ -1317,6 +1505,32 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
13171505 case WasmOp_f32_trunc:
13181506 case WasmOp_f32_nearest:
13191507 case WasmOp_f32_sqrt:
1508 case WasmOp_i32_trunc_f32_s:
1509 case WasmOp_i32_trunc_f32_u:
1510 case WasmOp_f32_convert_i32_s:
1511 case WasmOp_f32_convert_i32_u:
1512 case WasmOp_i32_reinterpret_f32:
1513 case WasmOp_f32_reinterpret_i32:
1514 case WasmOp_i32_extend8_s:
1515 case WasmOp_i32_extend16_s:
1516 si_pop(stack, ST_32);
1517 si_push(stack, ST_32);
1518 break;
1519
1520 case WasmOp_i64_eqz:
1521 case WasmOp_i32_wrap_i64:
1522 case WasmOp_i32_trunc_f64_s:
1523 case WasmOp_i32_trunc_f64_u:
1524 case WasmOp_f32_convert_i64_s:
1525 case WasmOp_f32_convert_i64_u:
1526 case WasmOp_f32_demote_f64:
1527 si_pop(stack, ST_64);
1528 si_push(stack, ST_32);
1529 break;
1530
1531 case WasmOp_i64_clz:
1532 case WasmOp_i64_ctz:
1533 case WasmOp_i64_popcnt:
13201534 case WasmOp_f64_abs:
13211535 case WasmOp_f64_neg:
13221536 case WasmOp_f64_ceil:
......@@ -1324,48 +1538,45 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
13241538 case WasmOp_f64_trunc:
13251539 case WasmOp_f64_nearest:
13261540 case WasmOp_f64_sqrt:
1327 case WasmOp_i32_wrap_i64:
1328 case WasmOp_i32_trunc_f32_s:
1329 case WasmOp_i32_trunc_f32_u:
1330 case WasmOp_i32_trunc_f64_s:
1331 case WasmOp_i32_trunc_f64_u:
1332 case WasmOp_i64_extend_i32_s:
1333 case WasmOp_i64_extend_i32_u:
1334 case WasmOp_i64_trunc_f32_s:
1335 case WasmOp_i64_trunc_f32_u:
13361541 case WasmOp_i64_trunc_f64_s:
13371542 case WasmOp_i64_trunc_f64_u:
1338 case WasmOp_f32_convert_i32_s:
1339 case WasmOp_f32_convert_i32_u:
1340 case WasmOp_f32_convert_i64_s:
1341 case WasmOp_f32_convert_i64_u:
1342 case WasmOp_f32_demote_f64:
1343 case WasmOp_f64_convert_i32_s:
1344 case WasmOp_f64_convert_i32_u:
13451543 case WasmOp_f64_convert_i64_s:
13461544 case WasmOp_f64_convert_i64_u:
1347 case WasmOp_f64_promote_f32:
1348 case WasmOp_i32_reinterpret_f32:
13491545 case WasmOp_i64_reinterpret_f64:
1350 case WasmOp_f32_reinterpret_i32:
13511546 case WasmOp_f64_reinterpret_i64:
1352 case WasmOp_i32_extend8_s:
1353 case WasmOp_i32_extend16_s:
13541547 case WasmOp_i64_extend8_s:
13551548 case WasmOp_i64_extend16_s:
13561549 case WasmOp_i64_extend32_s:
1550 si_pop(stack, ST_64);
1551 si_push(stack, ST_64);
1552 break;
1553
1554 case WasmOp_i64_extend_i32_s:
1555 case WasmOp_i64_extend_i32_u:
1556 case WasmOp_i64_trunc_f32_s:
1557 case WasmOp_i64_trunc_f32_u:
1558 case WasmOp_f64_convert_i32_s:
1559 case WasmOp_f64_convert_i32_u:
1560 case WasmOp_f64_promote_f32:
1561 si_pop(stack, ST_32);
1562 si_push(stack, ST_64);
13571563 break;
13581564
13591565 case WasmOp_i32_store:
1360 case WasmOp_i64_store:
13611566 case WasmOp_f32_store:
1362 case WasmOp_f64_store:
13631567 case WasmOp_i32_store8:
13641568 case WasmOp_i32_store16:
1569 si_pop(stack, ST_32);
1570 si_pop(stack, ST_32);
1571 break;
1572
1573 case WasmOp_i64_store:
1574 case WasmOp_f64_store:
13651575 case WasmOp_i64_store8:
13661576 case WasmOp_i64_store16:
13671577 case WasmOp_i64_store32:
1368 stack_depth -= 2;
1578 si_pop(stack, ST_64);
1579 si_pop(stack, ST_32);
13691580 break;
13701581
13711582 case WasmOp_i32_eq:
......@@ -1378,6 +1589,17 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
13781589 case WasmOp_i32_le_u:
13791590 case WasmOp_i32_ge_s:
13801591 case WasmOp_i32_ge_u:
1592 case WasmOp_f32_eq:
1593 case WasmOp_f32_ne:
1594 case WasmOp_f32_lt:
1595 case WasmOp_f32_gt:
1596 case WasmOp_f32_le:
1597 case WasmOp_f32_ge:
1598 si_pop(stack, ST_32);
1599 si_pop(stack, ST_32);
1600 si_push(stack, ST_32);
1601 break;
1602
13811603 case WasmOp_i64_eq:
13821604 case WasmOp_i64_ne:
13831605 case WasmOp_i64_lt_s:
......@@ -1388,18 +1610,17 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
13881610 case WasmOp_i64_le_u:
13891611 case WasmOp_i64_ge_s:
13901612 case WasmOp_i64_ge_u:
1391 case WasmOp_f32_eq:
1392 case WasmOp_f32_ne:
1393 case WasmOp_f32_lt:
1394 case WasmOp_f32_gt:
1395 case WasmOp_f32_le:
1396 case WasmOp_f32_ge:
13971613 case WasmOp_f64_eq:
13981614 case WasmOp_f64_ne:
13991615 case WasmOp_f64_lt:
14001616 case WasmOp_f64_gt:
14011617 case WasmOp_f64_le:
14021618 case WasmOp_f64_ge:
1619 si_pop(stack, ST_64);
1620 si_pop(stack, ST_64);
1621 si_push(stack, ST_32);
1622 break;
1623
14031624 case WasmOp_i32_add:
14041625 case WasmOp_i32_sub:
14051626 case WasmOp_i32_mul:
......@@ -1415,6 +1636,18 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14151636 case WasmOp_i32_shr_u:
14161637 case WasmOp_i32_rotl:
14171638 case WasmOp_i32_rotr:
1639 case WasmOp_f32_add:
1640 case WasmOp_f32_sub:
1641 case WasmOp_f32_mul:
1642 case WasmOp_f32_div:
1643 case WasmOp_f32_min:
1644 case WasmOp_f32_max:
1645 case WasmOp_f32_copysign:
1646 si_pop(stack, ST_32);
1647 si_pop(stack, ST_32);
1648 si_push(stack, ST_32);
1649 break;
1650
14181651 case WasmOp_i64_add:
14191652 case WasmOp_i64_sub:
14201653 case WasmOp_i64_mul:
......@@ -1430,13 +1663,6 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14301663 case WasmOp_i64_shr_u:
14311664 case WasmOp_i64_rotl:
14321665 case WasmOp_i64_rotr:
1433 case WasmOp_f32_add:
1434 case WasmOp_f32_sub:
1435 case WasmOp_f32_mul:
1436 case WasmOp_f32_div:
1437 case WasmOp_f32_min:
1438 case WasmOp_f32_max:
1439 case WasmOp_f32_copysign:
14401666 case WasmOp_f64_add:
14411667 case WasmOp_f64_sub:
14421668 case WasmOp_f64_mul:
......@@ -1444,19 +1670,35 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14441670 case WasmOp_f64_min:
14451671 case WasmOp_f64_max:
14461672 case WasmOp_f64_copysign:
1447 stack_depth -= 1;
1673 si_pop(stack, ST_64);
1674 si_pop(stack, ST_64);
1675 si_push(stack, ST_64);
14481676 break;
14491677
14501678 case WasmOp_prefixed:
14511679 switch (prefixed_opcode) {
14521680 case WasmPrefixedOp_i32_trunc_sat_f32_s:
14531681 case WasmPrefixedOp_i32_trunc_sat_f32_u:
1682 si_pop(stack, ST_32);
1683 si_push(stack, ST_32);
1684 break;
1685
14541686 case WasmPrefixedOp_i32_trunc_sat_f64_s:
14551687 case WasmPrefixedOp_i32_trunc_sat_f64_u:
1688 si_pop(stack, ST_64);
1689 si_push(stack, ST_32);
1690 break;
1691
14561692 case WasmPrefixedOp_i64_trunc_sat_f32_s:
14571693 case WasmPrefixedOp_i64_trunc_sat_f32_u:
1694 si_pop(stack, ST_32);
1695 si_push(stack, ST_64);
1696 break;
1697
14581698 case WasmPrefixedOp_i64_trunc_sat_f64_s:
14591699 case WasmPrefixedOp_i64_trunc_sat_f64_u:
1700 si_pop(stack, ST_64);
1701 si_push(stack, ST_64);
14601702 break;
14611703
14621704 case WasmPrefixedOp_memory_init:
......@@ -1464,8 +1706,15 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14641706 case WasmPrefixedOp_memory_fill:
14651707 case WasmPrefixedOp_table_init:
14661708 case WasmPrefixedOp_table_copy:
1709 si_pop(stack, ST_32);
1710 si_pop(stack, ST_32);
1711 si_pop(stack, ST_32);
1712 break;
1713
14671714 case WasmPrefixedOp_table_fill:
1468 stack_depth -= 3;
1715 si_pop(stack, ST_32);
1716 panic("si_pop(stack, unreachable);");
1717 si_pop(stack, ST_32);
14691718 break;
14701719
14711720 case WasmPrefixedOp_data_drop:
......@@ -1473,11 +1722,13 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14731722 break;
14741723
14751724 case WasmPrefixedOp_table_grow:
1476 stack_depth -= 1;
1725 si_pop(stack, ST_32);
1726 panic("si_pop(stack, unreachable);");
1727 si_push(stack, ST_32);
14771728 break;
14781729
14791730 case WasmPrefixedOp_table_size:
1480 stack_depth += 1;
1731 si_push(stack, ST_32);
14811732 break;
14821733
14831734 default: panic("unexpected prefixed opcode");
......@@ -1486,235 +1737,14 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14861737
14871738 default: panic("unexpected opcode");
14881739 }
1489 switch (opcode) {
1490 case WasmOp_unreachable:
1491 case WasmOp_nop:
1492 case WasmOp_block:
1493 case WasmOp_loop:
1494 case WasmOp_else:
1495 case WasmOp_end:
1496 case WasmOp_br:
1497 case WasmOp_call:
1498 case WasmOp_return:
1499 case WasmOp_if:
1500 case WasmOp_br_if:
1501 case WasmOp_br_table:
1502 case WasmOp_call_indirect:
1503 case WasmOp_drop:
1504 case WasmOp_select:
1505 case WasmOp_local_set:
1506 case WasmOp_local_get:
1507 case WasmOp_local_tee:
1508 case WasmOp_global_set:
1509 case WasmOp_global_get:
1510 case WasmOp_i32_store:
1511 case WasmOp_i64_store:
1512 case WasmOp_f32_store:
1513 case WasmOp_f64_store:
1514 case WasmOp_i32_store8:
1515 case WasmOp_i32_store16:
1516 case WasmOp_i64_store8:
1517 case WasmOp_i64_store16:
1518 case WasmOp_i64_store32:
1519 break;
1520
1521 case WasmOp_i32_const:
1522 case WasmOp_f32_const:
1523 case WasmOp_memory_size:
1524 case WasmOp_i32_load:
1525 case WasmOp_f32_load:
1526 case WasmOp_i32_load8_s:
1527 case WasmOp_i32_load8_u:
1528 case WasmOp_i32_load16_s:
1529 case WasmOp_i32_load16_u:
1530 case WasmOp_memory_grow:
1531 case WasmOp_i32_eqz:
1532 case WasmOp_i32_clz:
1533 case WasmOp_i32_ctz:
1534 case WasmOp_i32_popcnt:
1535 case WasmOp_i64_eqz:
1536 case WasmOp_f32_abs:
1537 case WasmOp_f32_neg:
1538 case WasmOp_f32_ceil:
1539 case WasmOp_f32_floor:
1540 case WasmOp_f32_trunc:
1541 case WasmOp_f32_nearest:
1542 case WasmOp_f32_sqrt:
1543 case WasmOp_i32_wrap_i64:
1544 case WasmOp_i32_trunc_f32_s:
1545 case WasmOp_i32_trunc_f32_u:
1546 case WasmOp_i32_trunc_f64_s:
1547 case WasmOp_i32_trunc_f64_u:
1548 case WasmOp_f32_convert_i32_s:
1549 case WasmOp_f32_convert_i32_u:
1550 case WasmOp_f32_convert_i64_s:
1551 case WasmOp_f32_convert_i64_u:
1552 case WasmOp_f32_demote_f64:
1553 case WasmOp_i32_reinterpret_f32:
1554 case WasmOp_f32_reinterpret_i32:
1555 case WasmOp_i32_extend8_s:
1556 case WasmOp_i32_extend16_s:
1557 case WasmOp_i32_eq:
1558 case WasmOp_i32_ne:
1559 case WasmOp_i32_lt_s:
1560 case WasmOp_i32_lt_u:
1561 case WasmOp_i32_gt_s:
1562 case WasmOp_i32_gt_u:
1563 case WasmOp_i32_le_s:
1564 case WasmOp_i32_le_u:
1565 case WasmOp_i32_ge_s:
1566 case WasmOp_i32_ge_u:
1567 case WasmOp_i64_eq:
1568 case WasmOp_i64_ne:
1569 case WasmOp_i64_lt_s:
1570 case WasmOp_i64_lt_u:
1571 case WasmOp_i64_gt_s:
1572 case WasmOp_i64_gt_u:
1573 case WasmOp_i64_le_s:
1574 case WasmOp_i64_le_u:
1575 case WasmOp_i64_ge_s:
1576 case WasmOp_i64_ge_u:
1577 case WasmOp_f32_eq:
1578 case WasmOp_f32_ne:
1579 case WasmOp_f32_lt:
1580 case WasmOp_f32_gt:
1581 case WasmOp_f32_le:
1582 case WasmOp_f32_ge:
1583 case WasmOp_f64_eq:
1584 case WasmOp_f64_ne:
1585 case WasmOp_f64_lt:
1586 case WasmOp_f64_gt:
1587 case WasmOp_f64_le:
1588 case WasmOp_f64_ge:
1589 case WasmOp_i32_add:
1590 case WasmOp_i32_sub:
1591 case WasmOp_i32_mul:
1592 case WasmOp_i32_div_s:
1593 case WasmOp_i32_div_u:
1594 case WasmOp_i32_rem_s:
1595 case WasmOp_i32_rem_u:
1596 case WasmOp_i32_and:
1597 case WasmOp_i32_or:
1598 case WasmOp_i32_xor:
1599 case WasmOp_i32_shl:
1600 case WasmOp_i32_shr_s:
1601 case WasmOp_i32_shr_u:
1602 case WasmOp_i32_rotl:
1603 case WasmOp_i32_rotr:
1604 case WasmOp_f32_add:
1605 case WasmOp_f32_sub:
1606 case WasmOp_f32_mul:
1607 case WasmOp_f32_div:
1608 case WasmOp_f32_min:
1609 case WasmOp_f32_max:
1610 case WasmOp_f32_copysign:
1611 bs_unset(stack_types, stack_depth - 1);
1612 break;
1613
1614 case WasmOp_i64_const:
1615 case WasmOp_f64_const:
1616 case WasmOp_i64_load:
1617 case WasmOp_f64_load:
1618 case WasmOp_i64_load8_s:
1619 case WasmOp_i64_load8_u:
1620 case WasmOp_i64_load16_s:
1621 case WasmOp_i64_load16_u:
1622 case WasmOp_i64_load32_s:
1623 case WasmOp_i64_load32_u:
1624 case WasmOp_i64_clz:
1625 case WasmOp_i64_ctz:
1626 case WasmOp_i64_popcnt:
1627 case WasmOp_f64_abs:
1628 case WasmOp_f64_neg:
1629 case WasmOp_f64_ceil:
1630 case WasmOp_f64_floor:
1631 case WasmOp_f64_trunc:
1632 case WasmOp_f64_nearest:
1633 case WasmOp_f64_sqrt:
1634 case WasmOp_i64_extend_i32_s:
1635 case WasmOp_i64_extend_i32_u:
1636 case WasmOp_i64_trunc_f32_s:
1637 case WasmOp_i64_trunc_f32_u:
1638 case WasmOp_i64_trunc_f64_s:
1639 case WasmOp_i64_trunc_f64_u:
1640 case WasmOp_f64_convert_i32_s:
1641 case WasmOp_f64_convert_i32_u:
1642 case WasmOp_f64_convert_i64_s:
1643 case WasmOp_f64_convert_i64_u:
1644 case WasmOp_f64_promote_f32:
1645 case WasmOp_i64_reinterpret_f64:
1646 case WasmOp_f64_reinterpret_i64:
1647 case WasmOp_i64_extend8_s:
1648 case WasmOp_i64_extend16_s:
1649 case WasmOp_i64_extend32_s:
1650 case WasmOp_i64_add:
1651 case WasmOp_i64_sub:
1652 case WasmOp_i64_mul:
1653 case WasmOp_i64_div_s:
1654 case WasmOp_i64_div_u:
1655 case WasmOp_i64_rem_s:
1656 case WasmOp_i64_rem_u:
1657 case WasmOp_i64_and:
1658 case WasmOp_i64_or:
1659 case WasmOp_i64_xor:
1660 case WasmOp_i64_shl:
1661 case WasmOp_i64_shr_s:
1662 case WasmOp_i64_shr_u:
1663 case WasmOp_i64_rotl:
1664 case WasmOp_i64_rotr:
1665 case WasmOp_f64_add:
1666 case WasmOp_f64_sub:
1667 case WasmOp_f64_mul:
1668 case WasmOp_f64_div:
1669 case WasmOp_f64_min:
1670 case WasmOp_f64_max:
1671 case WasmOp_f64_copysign:
1672 bs_set(stack_types, stack_depth - 1);
1673 break;
1674
1675 case WasmOp_prefixed:
1676 switch (prefixed_opcode) {
1677 case WasmPrefixedOp_memory_init:
1678 case WasmPrefixedOp_memory_copy:
1679 case WasmPrefixedOp_memory_fill:
1680 case WasmPrefixedOp_table_init:
1681 case WasmPrefixedOp_table_copy:
1682 case WasmPrefixedOp_table_fill:
1683 case WasmPrefixedOp_data_drop:
1684 case WasmPrefixedOp_elem_drop:
1685 break;
1686
1687 case WasmPrefixedOp_i32_trunc_sat_f32_s:
1688 case WasmPrefixedOp_i32_trunc_sat_f32_u:
1689 case WasmPrefixedOp_i32_trunc_sat_f64_s:
1690 case WasmPrefixedOp_i32_trunc_sat_f64_u:
1691 case WasmPrefixedOp_table_grow:
1692 case WasmPrefixedOp_table_size:
1693 bs_unset(stack_types, stack_depth - 1);
1694 break;
1695
1696 case WasmPrefixedOp_i64_trunc_sat_f32_s:
1697 case WasmPrefixedOp_i64_trunc_sat_f32_u:
1698 case WasmPrefixedOp_i64_trunc_sat_f64_s:
1699 case WasmPrefixedOp_i64_trunc_sat_f64_u:
1700 bs_set(stack_types, stack_depth - 1);
1701 break;
1702
1703 default: panic("unexpected prefixed opcode");
1704 }
1705 break;
1706
1707 default: panic("unexpected opcode");
1708 }
1709 }
1710
1711 switch (opcode) {
1712 case WasmOp_unreachable:
1713 if (unreachable_depth == 0) {
1714 opcodes[pc->opcode] = Op_unreachable;
1715 pc->opcode += 1;
1716 }
1717 break;
1740 switch (opcode) {
1741 case WasmOp_unreachable:
1742 if (unreachable_depth == 0) {
1743 opcodes[pc->opcode] = Op_unreachable;
1744 pc->opcode += 1;
1745 unreachable_depth += 1;
1746 }
1747 break;
17181748
17191749 case WasmOp_nop:
17201750 case WasmOp_i32_reinterpret_f32:
......@@ -1748,11 +1778,19 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
17481778 break;
17491779 default: panic("unexpected param type");
17501780 }
1751 } else {
1752 label->type_info = vm->types[block_type];
1781 } else label->type_info = vm->types[block_type];
1782
1783 uint32_t param_i = label->type_info.param_count;
1784 while (param_i > 0) {
1785 param_i -= 1;
1786 si_pop(stack, bs_isSet(&label->type_info.param_types, param_i));
17531787 }
1754 label->stack_depth = stack_depth - label->type_info.param_count;
1788 label->stack_index = stack->top_index;
1789 label->stack_offset = stack->top_offset;
17551790 label->ref_list = UINT32_MAX;
1791 for (; param_i < label->type_info.param_count; param_i += 1)
1792 si_push(stack, bs_isSet(&label->type_info.param_types, param_i));
1793
17561794 switch (opcode) {
17571795 case WasmOp_block:
17581796 break;
......@@ -1762,7 +1800,10 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
17621800 break;
17631801
17641802 case WasmOp_if:
1765 opcodes[pc->opcode] = Op_br_if_eqz_void;
1803 if (state == State_bool_not) {
1804 pc->opcode -= 1;
1805 opcodes[pc->opcode] = Op_br_nez_void;
1806 } else opcodes[pc->opcode] = Op_br_eqz_void;
17661807 pc->opcode += 1;
17671808 operands[pc->operand] = 0;
17681809 label->extra.else_ref = pc->operand + 1;
......@@ -1771,7 +1812,7 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
17711812
17721813 default: panic("unexpected label opcode");
17731814 }
1774 }
1815 } else unreachable_depth += 1;
17751816 }
17761817 break;
17771818
......@@ -1780,8 +1821,16 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
17801821 struct Label *label = &labels[label_i];
17811822 assert(label->opcode == WasmOp_if);
17821823 label->opcode = WasmOp_else;
1824
17831825 if (unreachable_depth == 0) {
17841826 uint32_t operand_count = Label_operandCount(label);
1827 for (uint32_t operand_i = operand_count; operand_i > 0; ) {
1828 operand_i -= 1;
1829 si_pop(stack, Label_operandType(label, operand_i));
1830 }
1831 assert(stack->top_index == label->stack_index);
1832 assert(stack->top_offset == label->stack_offset);
1833
17851834 switch (operand_count) {
17861835 case 0:
17871836 opcodes[pc->opcode] = Op_br_void;
......@@ -1790,31 +1839,30 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
17901839 case 1:
17911840 //fprintf(stderr, "label_i=%u operand_type=%d\n",
17921841 // label_i, Label_operandType(label, 0));
1793 if (Label_operandType(label, 0)) {
1794 opcodes[pc->opcode] = Op_br_64;
1795 } else {
1796 opcodes[pc->opcode] = Op_br_32;
1842 switch (Label_operandType(label, 0)) {
1843 case ST_32: opcodes[pc->opcode] = Op_br_32; break;
1844 case ST_64: opcodes[pc->opcode] = Op_br_64; break;
17971845 }
17981846 break;
17991847
18001848 default: panic("unexpected operand count");
18011849 }
18021850 pc->opcode += 1;
1803 operands[pc->operand + 0] = stack_depth - operand_count - label->stack_depth;
1851 operands[pc->operand + 0] = stack->top_offset - label->stack_offset;
18041852 operands[pc->operand + 1] = label->ref_list;
18051853 label->ref_list = pc->operand + 1;
18061854 pc->operand += 3;
1807 assert(stack_depth - label->type_info.result_count == label->stack_depth);
18081855 } else unreachable_depth = 0;
1856
18091857 operands[label->extra.else_ref + 0] = pc->opcode;
18101858 operands[label->extra.else_ref + 1] = pc->operand;
1811 stack_depth = label->stack_depth + label->type_info.param_count;
1859 for (uint32_t param_i = 0; param_i < label->type_info.param_count; param_i += 1)
1860 si_push(stack, bs_isSet(&label->type_info.param_types, param_i));
18121861 }
18131862 break;
18141863
18151864 case WasmOp_end:
18161865 if (unreachable_depth <= 1) {
1817 unreachable_depth = 0;
18181866 struct Label *label = &labels[label_i];
18191867 struct ProgramCounter *target_pc = (label->opcode == WasmOp_loop) ? &label->extra.loop_pc : pc;
18201868 if (label->opcode == WasmOp_if) {
......@@ -1828,33 +1876,44 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
18281876 operands[ref + 1] = target_pc->operand;
18291877 ref = next_ref;
18301878 }
1831 stack_depth = label->stack_depth + label->type_info.result_count;
1879
1880 if (unreachable_depth == 0) {
1881 for (uint32_t result_i = label->type_info.result_count; result_i > 0; ) {
1882 result_i -= 1;
1883 si_pop(stack, bs_isSet(&label->type_info.result_types, result_i));
1884 }
1885 } else unreachable_depth = 0;
18321886
18331887 if (label_i == 0) {
1834 uint32_t operand_count = Label_operandCount(&labels[0]);
1835 switch (operand_count) {
1888 assert(stack->top_index == label->stack_index);
1889 assert(stack->top_offset == label->stack_offset);
1890
1891 switch (labels[0].type_info.result_count) {
18361892 case 0:
18371893 opcodes[pc->opcode] = Op_return_void;
18381894 break;
18391895
18401896 case 1:
1841 switch ((int)Label_operandType(&labels[0], 0)) {
1842 case false: opcodes[pc->opcode] = Op_return_32; break;
1843 case true: opcodes[pc->opcode] = Op_return_64; break;
1897 switch ((enum StackType)bs_isSet(&labels[0].type_info.result_types, 0)) {
1898 case ST_32: opcodes[pc->opcode] = Op_return_32; break;
1899 case ST_64: opcodes[pc->opcode] = Op_return_64; break;
18441900 }
18451901 break;
18461902
18471903 default: panic("unexpected operand count");
18481904 }
18491905 pc->opcode += 1;
1850 operands[pc->operand + 0] = 2 + operand_count;
1851 stack_depth -= operand_count;
1852 assert(stack_depth == labels[0].stack_depth);
1853 operands[pc->operand + 1] = stack_depth;
1906 operands[pc->operand + 0] = stack->top_offset - labels[0].stack_offset;
1907 operands[pc->operand + 1] = frame_size;
18541908 pc->operand += 2;
18551909 return;
18561910 }
18571911 label_i -= 1;
1912
1913 stack->top_index = label->stack_index;
1914 stack->top_offset = label->stack_offset;
1915 for (uint32_t result_i = 0; result_i < label->type_info.result_count; result_i += 1)
1916 si_push(stack, bs_isSet(&label->type_info.result_types, result_i));
18581917 } else unreachable_depth -= 1;
18591918 break;
18601919
......@@ -1865,6 +1924,12 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
18651924 if (unreachable_depth == 0) {
18661925 struct Label *label = &labels[label_i - label_idx];
18671926 uint32_t operand_count = Label_operandCount(label);
1927 uint32_t operand_i = operand_count;
1928 while (operand_i > 0) {
1929 operand_i -= 1;
1930 si_pop(stack, Label_operandType(label, operand_i));
1931 }
1932
18681933 switch (opcode) {
18691934 case WasmOp_br:
18701935 switch (operand_count) {
......@@ -1873,9 +1938,9 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
18731938 break;
18741939
18751940 case 1:
1876 switch ((int)Label_operandType(label, 0)) {
1877 case false: opcodes[pc->opcode] = Op_br_32; break;
1878 case true: opcodes[pc->opcode] = Op_br_64; break;
1941 switch (Label_operandType(label, 0)) {
1942 case ST_32: opcodes[pc->opcode] = Op_br_32; break;
1943 case ST_64: opcodes[pc->opcode] = Op_br_64; break;
18791944 }
18801945 break;
18811946
......@@ -1886,13 +1951,27 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
18861951 case WasmOp_br_if:
18871952 switch (operand_count) {
18881953 case 0:
1889 opcodes[pc->opcode] = Op_br_if_nez_void;
1954 if (state == State_bool_not) {
1955 pc->opcode -= 1;
1956 opcodes[pc->opcode] = Op_br_eqz_void;
1957 } else opcodes[pc->opcode] = Op_br_nez_void;
18901958 break;
18911959
18921960 case 1:
1893 switch ((int)Label_operandType(label, 0)) {
1894 case false: opcodes[pc->opcode] = Op_br_if_nez_32; break;
1895 case true: opcodes[pc->opcode] = Op_br_if_nez_64; break;
1961 switch (Label_operandType(label, 0)) {
1962 case ST_32:
1963 if (state == State_bool_not) {
1964 pc->opcode -= 1;
1965 opcodes[pc->opcode] = Op_br_eqz_32;
1966 } else opcodes[pc->opcode] = Op_br_nez_32;
1967 break;
1968
1969 case ST_64:
1970 if (state == State_bool_not) {
1971 pc->opcode -= 1;
1972 opcodes[pc->opcode] = Op_br_eqz_64;
1973 } else opcodes[pc->opcode] = Op_br_nez_64;
1974 break;
18961975 }
18971976 break;
18981977
......@@ -1900,13 +1979,26 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
19001979 }
19011980 break;
19021981
1903 default: panic("unreachable");
1982 default: panic("unexpected opcode");
19041983 }
19051984 pc->opcode += 1;
1906 operands[pc->operand + 0] = stack_depth - operand_count - label->stack_depth;
1985 operands[pc->operand + 0] = stack->top_offset - label->stack_offset;
19071986 operands[pc->operand + 1] = label->ref_list;
19081987 label->ref_list = pc->operand + 1;
19091988 pc->operand += 3;
1989
1990 switch (opcode) {
1991 case WasmOp_br:
1992 unreachable_depth += 1;
1993 break;
1994
1995 case WasmOp_br_if:
1996 for (; operand_i < operand_count; operand_i += 1)
1997 si_push(stack, Label_operandType(label, operand_i));
1998 break;
1999
2000 default: panic("unexpected opcode");
2001 }
19102002 }
19112003 }
19122004 break;
......@@ -1918,17 +2010,22 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
19182010 uint32_t label_idx = read32_uleb128(mod_ptr, code_i);
19192011 if (unreachable_depth != 0) continue;
19202012 struct Label *label = &labels[label_i - label_idx];
1921 uint32_t operand_count = Label_operandCount(label);
19222013 if (i == 0) {
2014 uint32_t operand_count = Label_operandCount(label);
2015 for (uint32_t operand_i = operand_count; operand_i > 0; ) {
2016 operand_i -= 1;
2017 si_pop(stack, Label_operandType(label, operand_i));
2018 }
2019
19232020 switch (operand_count) {
19242021 case 0:
19252022 opcodes[pc->opcode] = Op_br_table_void;
19262023 break;
19272024
19282025 case 1:
1929 switch ((int)Label_operandType(label, 0)) {
1930 case false: opcodes[pc->opcode] = Op_br_table_32; break;
1931 case true: opcodes[pc->opcode] = Op_br_table_64; break;
2026 switch (Label_operandType(label, 0)) {
2027 case ST_32: opcodes[pc->opcode] = Op_br_table_32; break;
2028 case ST_64: opcodes[pc->opcode] = Op_br_table_64; break;
19322029 }
19332030 break;
19342031
......@@ -1938,11 +2035,41 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
19382035 operands[pc->operand] = labels_len;
19392036 pc->operand += 1;
19402037 }
1941 operands[pc->operand + 0] = stack_depth - operand_count - label->stack_depth;
2038 operands[pc->operand + 0] = stack->top_offset - label->stack_offset;
19422039 operands[pc->operand + 1] = label->ref_list;
19432040 label->ref_list = pc->operand + 1;
19442041 pc->operand += 3;
19452042 }
2043 if (unreachable_depth == 0) unreachable_depth += 1;
2044 }
2045 break;
2046
2047 case WasmOp_return:
2048 if (unreachable_depth == 0) {
2049 for (uint32_t result_i = labels[0].type_info.result_count; result_i > 0; ) {
2050 result_i -= 1;
2051 si_pop(stack, bs_isSet(&labels[0].type_info.result_types, result_i));
2052 }
2053
2054 switch (labels[0].type_info.result_count) {
2055 case 0:
2056 opcodes[pc->opcode] = Op_return_void;
2057 break;
2058
2059 case 1:
2060 switch ((enum StackType)bs_isSet(&labels[0].type_info.result_types, 0)) {
2061 case ST_32: opcodes[pc->opcode] = Op_return_32; break;
2062 case ST_64: opcodes[pc->opcode] = Op_return_64; break;
2063 }
2064 break;
2065
2066 default: panic("unexpected operand count");
2067 }
2068 pc->opcode += 1;
2069 operands[pc->operand + 0] = stack->top_offset - labels[0].stack_offset;
2070 operands[pc->operand + 1] = frame_size;
2071 pc->operand += 2;
2072 unreachable_depth += 1;
19462073 }
19472074 break;
19482075
......@@ -1950,19 +2077,28 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
19502077 {
19512078 uint32_t fn_id = read32_uleb128(mod_ptr, code_i);
19522079 if (unreachable_depth == 0) {
1953 opcodes[pc->opcode] = Op_call;
1954 pc->opcode += 1;
1955 operands[pc->operand] = fn_id;
1956 pc->operand += 1;
1957 uint32_t type_idx = (fn_id < vm->imports_len) ?
1958 vm->imports[fn_id].type_idx :
1959 vm->functions[fn_id - vm->imports_len].type_idx;
2080 uint32_t type_idx;
2081 if (fn_id < vm->imports_len) {
2082 opcodes[pc->opcode + 0] = Op_call_import;
2083 opcodes[pc->opcode + 1] = fn_id;
2084 pc->opcode += 2;
2085 type_idx = vm->imports[fn_id].type_idx;
2086 } else {
2087 uint32_t fn_idx = fn_id - vm->imports_len;
2088 opcodes[pc->opcode] = Op_call_func;
2089 pc->opcode += 1;
2090 operands[pc->operand] = fn_idx;
2091 pc->operand += 1;
2092 type_idx = vm->functions[fn_idx].type_idx;
2093 }
19602094 struct TypeInfo *type_info = &vm->types[type_idx];
1961 stack_depth -= type_info->param_count;
2095
2096 for (uint32_t param_i = type_info->param_count; param_i > 0; ) {
2097 param_i -= 1;
2098 si_pop(stack, bs_isSet(&type_info->param_types, param_i));
2099 }
19622100 for (uint32_t result_i = 0; result_i < type_info->result_count; result_i += 1)
1963 bs_setValue(stack_types, stack_depth + result_i,
1964 bs_isSet(&type_info->result_types, result_i));
1965 stack_depth += type_info->result_count;
2101 si_push(stack, bs_isSet(&type_info->result_types, result_i));
19662102 }
19672103 }
19682104 break;
......@@ -1972,171 +2108,144 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
19722108 uint32_t type_idx = read32_uleb128(mod_ptr, code_i);
19732109 if (read32_uleb128(mod_ptr, code_i) != 0) panic("unexpected table index");
19742110 if (unreachable_depth == 0) {
1975 opcodes[pc->opcode + 0] = Op_wasm;
1976 opcodes[pc->opcode + 1] = opcode;
1977 pc->opcode += 2;
2111 opcodes[pc->opcode] = Op_call_indirect;
2112 pc->opcode += 1;
2113
19782114 struct TypeInfo *type_info = &vm->types[type_idx];
1979 stack_depth -= type_info->param_count;
2115 for (uint32_t param_i = type_info->param_count; param_i > 0; ) {
2116 param_i -= 1;
2117 si_pop(stack, bs_isSet(&type_info->param_types, param_i));
2118 }
19802119 for (uint32_t result_i = 0; result_i < type_info->result_count; result_i += 1)
1981 bs_setValue(stack_types, stack_depth + result_i,
1982 bs_isSet(&type_info->result_types, result_i));
1983 stack_depth += type_info->result_count;
2120 si_push(stack, bs_isSet(&type_info->result_types, result_i));
19842121 }
19852122 }
19862123 break;
19872124
1988 case WasmOp_return:
1989 if (unreachable_depth <= 1) {
1990 uint32_t operand_count = Label_operandCount(&labels[0]);
1991 switch (operand_count) {
1992 case 0:
1993 opcodes[pc->opcode] = Op_return_void;
2125 case WasmOp_select:
2126 case WasmOp_drop:
2127 if (unreachable_depth == 0) {
2128 if (opcode == WasmOp_select) si_pop(stack, ST_32);
2129 enum StackType operand_type = si_top(stack);
2130 si_pop(stack, operand_type);
2131 if (opcode == WasmOp_select) {
2132 si_pop(stack, operand_type);
2133 si_push(stack, operand_type);
2134 }
2135 switch (opcode) {
2136 case WasmOp_select:
2137 switch (operand_type) {
2138 case ST_32: opcodes[pc->opcode] = Op_select_32; break;
2139 case ST_64: opcodes[pc->opcode] = Op_select_64; break;
2140 }
19942141 break;
19952142
1996 case 1:
1997 switch ((int)Label_operandType(&labels[0], 0)) {
1998 case false: opcodes[pc->opcode] = Op_return_32; break;
1999 case true: opcodes[pc->opcode] = Op_return_64; break;
2143 case WasmOp_drop:
2144 switch (operand_type) {
2145 case ST_32: opcodes[pc->opcode] = Op_drop_32; break;
2146 case ST_64: opcodes[pc->opcode] = Op_drop_64; break;
20002147 }
20012148 break;
20022149
2003 default: panic("unexpected operand count");
2150 default: panic("unexpected opcode");
20042151 }
20052152 pc->opcode += 1;
2006 operands[pc->operand + 0] = 2 + stack_depth - labels[0].stack_depth;
2007 stack_depth -= operand_count;
2008 operands[pc->operand + 1] = stack_depth;
2009 pc->operand += 2;
20102153 }
20112154 break;
20122155
2013 case WasmOp_select:
2014 case WasmOp_drop:
2015 if (unreachable_depth == 0) {
2016 switch ((int)bs_isSet(stack_types, stack_depth)) {
2017 case false:
2156 case WasmOp_local_get:
2157 case WasmOp_local_set:
2158 case WasmOp_local_tee:
2159 {
2160 uint32_t local_idx = read32_uleb128(mod_ptr, code_i);
2161 if (unreachable_depth == 0) {
2162 enum StackType local_type = si_local(stack, local_idx);
20182163 switch (opcode) {
2019 case WasmOp_select:
2020 opcodes[pc->opcode] = Op_select_32;
2164 case WasmOp_local_get:
2165 switch (local_type) {
2166 case ST_32: opcodes[pc->opcode] = Op_local_get_32; break;
2167 case ST_64: opcodes[pc->opcode] = Op_local_get_64; break;
2168 }
20212169 break;
20222170
2023 case WasmOp_drop:
2024 opcodes[pc->opcode] = Op_drop_32;
2171 case WasmOp_local_set:
2172 switch (local_type) {
2173 case ST_32: opcodes[pc->opcode] = Op_local_set_32; break;
2174 case ST_64: opcodes[pc->opcode] = Op_local_set_64; break;
2175 }
2176 break;
2177
2178 case WasmOp_local_tee:
2179 switch (local_type) {
2180 case ST_32: opcodes[pc->opcode] = Op_local_tee_32; break;
2181 case ST_64: opcodes[pc->opcode] = Op_local_tee_64; break;
2182 }
20252183 break;
20262184
20272185 default: panic("unexpected opcode");
20282186 }
2029 break;
2030
2031 case true:
2187 pc->opcode += 1;
2188 operands[pc->operand] = stack->top_offset - stack->offsets[local_idx];
2189 pc->operand += 1;
20322190 switch (opcode) {
2033 case WasmOp_select:
2034 opcodes[pc->opcode] = Op_select_64;
2191 case WasmOp_local_get:
2192 si_push(stack, local_type);
2193 break;
2194
2195 case WasmOp_local_set:
2196 si_pop(stack, local_type);
20352197 break;
20362198
2037 case WasmOp_drop:
2038 opcodes[pc->opcode] = Op_drop_64;
2199 case WasmOp_local_tee:
2200 si_pop(stack, local_type);
2201 si_push(stack, local_type);
20392202 break;
20402203
20412204 default: panic("unexpected opcode");
20422205 }
2043 break;
20442206 }
2045 pc->opcode += 1;
20462207 }
20472208 break;
20482209
2049 case WasmOp_local_get:
2050 case WasmOp_local_set:
2051 case WasmOp_local_tee:
2210 case WasmOp_global_get:
2211 case WasmOp_global_set:
20522212 {
2053 uint32_t local_idx = read32_uleb128(mod_ptr, code_i);
2213 uint32_t global_idx = read32_uleb128(mod_ptr, code_i);
20542214 if (unreachable_depth == 0) {
2055 bool local_type = bs_isSet(func->local_types, local_idx);
2056 switch ((int)local_type) {
2057 case false:
2058 switch (opcode) {
2059 case WasmOp_local_get:
2060 opcodes[pc->opcode] = Op_local_get_32;
2061 break;
2062
2063 case WasmOp_local_set:
2064 opcodes[pc->opcode] = Op_local_set_32;
2065 break;
2066
2067 case WasmOp_local_tee:
2068 opcodes[pc->opcode] = Op_local_tee_32;
2069 break;
2070
2071 default: panic("unexpected opcode");
2215 enum StackType global_type = ST_32; // all globals assumed to be 32-bit
2216 switch (opcode) {
2217 case WasmOp_global_get:
2218 switch (global_idx) {
2219 case 0: opcodes[pc->opcode] = Op_global_get_0_32; break;
2220 default: opcodes[pc->opcode] = Op_global_get_32; break;
20722221 }
20732222 break;
20742223
2075 case true:
2076 switch (opcode) {
2077 case WasmOp_local_get:
2078 opcodes[pc->opcode] = Op_local_get_64;
2079 break;
2224 case WasmOp_global_set:
2225 switch (global_idx) {
2226 case 0: opcodes[pc->opcode] = Op_global_set_0_32; break;
2227 default: opcodes[pc->opcode] = Op_global_set_32; break;
2228 }
2229 break;
20802230
2081 case WasmOp_local_set:
2082 opcodes[pc->opcode] = Op_local_set_64;
2083 break;
2084
2085 case WasmOp_local_tee:
2086 opcodes[pc->opcode] = Op_local_tee_64;
2087 break;
2088
2089 default: panic("unexpected opcode");
2090 }
2091 break;
2092 }
2093 pc->opcode += 1;
2094 operands[pc->operand] = initial_stack_depth - local_idx;
2095 pc->operand += 1;
2096 if (opcode == WasmOp_local_get) bs_setValue(stack_types, stack_depth - 1, local_type);
2097 }
2098 }
2099 break;
2100
2101 case WasmOp_global_get:
2102 case WasmOp_global_set:
2103 {
2104 uint32_t global_idx = read32_uleb128(mod_ptr, code_i);
2105 if (unreachable_depth == 0) {
2106 switch (global_idx) {
2107 case 0:
2108 switch (opcode) {
2109 case WasmOp_global_get:
2110 opcodes[pc->opcode] = Op_global_get_0_32;
2111 break;
2112
2113 case WasmOp_global_set:
2114 opcodes[pc->opcode] = Op_global_set_0_32;
2115 break;
2116
2117 default: panic("unexpected opcode");
2118 }
2119 break;
2120
2121 default:
2122 switch (opcode) {
2123 case WasmOp_global_get:
2124 opcodes[pc->opcode] = Op_global_get_32;
2125 break;
2126
2127 case WasmOp_global_set:
2128 opcodes[pc->opcode] = Op_global_set_32;
2129 break;
2130
2131 default: panic("unexpected opcode");
2132 }
2133 break;
2231 default: panic("unexpected opcode");
21342232 }
21352233 pc->opcode += 1;
21362234 if (global_idx != 0) {
21372235 operands[pc->operand] = global_idx;
21382236 pc->operand += 1;
21392237 }
2238 switch (opcode) {
2239 case WasmOp_global_get:
2240 si_push(stack, global_type);
2241 break;
2242
2243 case WasmOp_global_set:
2244 si_pop(stack, global_type);
2245 break;
2246
2247 default: panic("unexpected opcode");
2248 }
21402249 }
21412250 }
21422251 break;
......@@ -2169,11 +2278,111 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
21692278 uint32_t offset = read32_uleb128(mod_ptr, code_i);
21702279 (void)alignment;
21712280 if (unreachable_depth == 0) {
2172 opcodes[pc->opcode + 0] = Op_wasm;
2173 opcodes[pc->opcode + 1] = opcode;
2174 pc->opcode += 2;
2175 operands[pc->operand] = offset;
2176 pc->operand += 1;
2281 switch (opcode) {
2282 default: break;
2283
2284 case WasmOp_i64_store8: case WasmOp_i64_store16: case WasmOp_i64_store32:
2285 opcodes[pc->opcode] = Op_drop_32;
2286 pc->opcode += 1;
2287 break;
2288 }
2289 switch (opcode) {
2290 case WasmOp_i32_load8_s: case WasmOp_i32_load8_u:
2291 case WasmOp_i64_load8_s: case WasmOp_i64_load8_u:
2292 switch (offset) {
2293 case 0: opcodes[pc->opcode] = Op_load_0_8; break;
2294 default: opcodes[pc->opcode] = Op_load_8; break;
2295 }
2296 break;
2297
2298 case WasmOp_i32_load16_s: case WasmOp_i32_load16_u:
2299 case WasmOp_i64_load16_s: case WasmOp_i64_load16_u:
2300 switch (offset) {
2301 case 0: opcodes[pc->opcode] = Op_load_0_16; break;
2302 default: opcodes[pc->opcode] = Op_load_16; break;
2303 }
2304 break;
2305
2306 case WasmOp_i32_load: case WasmOp_f32_load:
2307 case WasmOp_i64_load32_s: case WasmOp_i64_load32_u:
2308 switch (offset) {
2309 case 0: opcodes[pc->opcode] = Op_load_0_32; break;
2310 default: opcodes[pc->opcode] = Op_load_32; break;
2311 }
2312 break;
2313
2314 case WasmOp_i64_load: case WasmOp_f64_load:
2315 switch (offset) {
2316 case 0: opcodes[pc->opcode] = Op_load_0_64; break;
2317 default: opcodes[pc->opcode] = Op_load_64; break;
2318 }
2319 break;
2320
2321 case WasmOp_i32_store8: case WasmOp_i64_store8:
2322 switch (offset) {
2323 case 0: opcodes[pc->opcode] = Op_store_0_8; break;
2324 default: opcodes[pc->opcode] = Op_store_8; break;
2325 }
2326 break;
2327
2328 case WasmOp_i32_store16: case WasmOp_i64_store16:
2329 switch (offset) {
2330 case 0: opcodes[pc->opcode] = Op_store_0_16; break;
2331 default: opcodes[pc->opcode] = Op_store_16; break;
2332 }
2333 break;
2334
2335 case WasmOp_i32_store: case WasmOp_f32_store: case WasmOp_i64_store32:
2336 switch (offset) {
2337 case 0: opcodes[pc->opcode] = Op_store_0_32; break;
2338 default: opcodes[pc->opcode] = Op_store_32; break;
2339 }
2340 break;
2341
2342 case WasmOp_i64_store: case WasmOp_f64_store:
2343 switch (offset) {
2344 case 0: opcodes[pc->opcode] = Op_store_0_64; break;
2345 default: opcodes[pc->opcode] = Op_store_64; break;
2346 }
2347 break;
2348
2349 default: panic("unexpected opcode");
2350 }
2351 pc->opcode += 1;
2352 switch (offset) {
2353 case 0: break;
2354
2355 default:
2356 operands[pc->operand] = offset;
2357 pc->operand += 1;
2358 break;
2359 }
2360 switch (opcode) {
2361 default: break;
2362
2363 case WasmOp_i32_load8_s: case WasmOp_i64_load8_s:
2364 opcodes[pc->opcode] = Op_sext8_32;
2365 pc->opcode += 1;
2366 break;
2367
2368 case WasmOp_i32_load16_s: case WasmOp_i64_load16_s:
2369 opcodes[pc->opcode] = Op_sext16_32;
2370 pc->opcode += 1;
2371 break;
2372 }
2373 switch (opcode) {
2374 default: break;
2375
2376 case WasmOp_i64_load8_s: case WasmOp_i64_load16_s: case WasmOp_i64_load32_s:
2377 opcodes[pc->opcode] = Op_sext_64_32;
2378 pc->opcode += 1;
2379 break;
2380
2381 case WasmOp_i64_load8_u: case WasmOp_i64_load16_u: case WasmOp_i64_load32_u:
2382 opcodes[pc->opcode] = Op_zext_64_32;
2383 pc->opcode += 1;
2384 break;
2385 }
21772386 }
21782387 }
21792388 break;
......@@ -2184,110 +2393,224 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
21842393 if (mod_ptr[*code_i] != 0) panic("unexpected memory index");
21852394 *code_i += 1;
21862395 if (unreachable_depth == 0) {
2187 opcodes[pc->opcode + 0] = Op_wasm;
2188 opcodes[pc->opcode + 1] = opcode;
2189 pc->opcode += 2;
2396 switch (opcode) {
2397 case WasmOp_memory_size: opcodes[pc->opcode] = Op_mem_size; break;
2398 case WasmOp_memory_grow: opcodes[pc->opcode] = Op_mem_grow; break;
2399 default: panic("unexpected opcode");
2400 }
2401 pc->opcode += 1;
21902402 }
21912403 }
21922404 break;
21932405
21942406 case WasmOp_i32_const:
2407 case WasmOp_f32_const:
21952408 {
2196 uint32_t x = read32_ileb128(mod_ptr, code_i);
2409 uint32_t value;
2410 switch (opcode) {
2411 case WasmOp_i32_const: value = read32_ileb128(mod_ptr, code_i); break;
2412
2413 case WasmOp_f32_const:
2414 value = read_u32_le(&mod_ptr[*code_i]);
2415 *code_i += sizeof(value);
2416 break;
2417
2418 default: panic("unexpected opcode");
2419 }
21972420 if (unreachable_depth == 0) {
2198 opcodes[pc->opcode] = Op_const_32;
2421 switch (value) {
2422 case 0: opcodes[pc->opcode] = Op_const_0_32; break;
2423 case 1: opcodes[pc->opcode] = Op_const_1_32; break;
2424
2425 default:
2426 opcodes[pc->opcode] = Op_const_32;
2427 operands[pc->operand] = value;
2428 pc->operand += 1;
2429 break;
2430
2431 case UINT32_MAX: opcodes[pc->opcode] = Op_const_umax_32; break;
2432 }
21992433 pc->opcode += 1;
2200 operands[pc->operand] = x;
2201 pc->operand += 1;
22022434 }
22032435 }
22042436 break;
22052437
22062438 case WasmOp_i64_const:
2439 case WasmOp_f64_const:
22072440 {
2208 uint64_t x = read64_ileb128(mod_ptr, code_i);
2209 if (unreachable_depth == 0) {
2210 opcodes[pc->opcode] = Op_const_64;
2211 pc->opcode += 1;
2212 operands[pc->operand + 0] = x & UINT32_MAX;
2213 operands[pc->operand + 1] = (x >> 32) & UINT32_MAX;
2214 pc->operand += 2;
2215 }
2216 }
2217 break;
2441 uint64_t value;
2442 switch (opcode) {
2443 case WasmOp_i64_const: value = read64_ileb128(mod_ptr, code_i); break;
22182444
2219 case WasmOp_f32_const:
2220 {
2221 uint32_t x;
2222 memcpy(&x, mod_ptr + *code_i, 4);
2223 *code_i += 4;
2224 if (unreachable_depth == 0) {
2225 opcodes[pc->opcode] = Op_const_32;
2226 pc->opcode += 1;
2227 operands[pc->operand] = x;
2228 pc->operand += 1;
2445 case WasmOp_f64_const:
2446 value = read_u64_le(&mod_ptr[*code_i]);
2447 *code_i += sizeof(value);
2448 break;
2449
2450 default: panic("unexpected opcode");
22292451 }
2230 }
2231 break;
22322452
2233 case WasmOp_f64_const:
2234 {
2235 uint64_t x;
2236 memcpy(&x, mod_ptr + *code_i, 8);
2237 *code_i += 8;
22382453 if (unreachable_depth == 0) {
2239 opcodes[pc->opcode] = Op_const_64;
2454 switch (value) {
2455 case 0: opcodes[pc->opcode] = Op_const_0_64; break;
2456 case 1: opcodes[pc->opcode] = Op_const_1_64; break;
2457
2458 default:
2459 opcodes[pc->opcode] = Op_const_64;
2460 operands[pc->operand + 0] = (uint32_t)(value >> 0);
2461 operands[pc->operand + 1] = (uint32_t)(value >> 32);
2462 pc->operand += 2;
2463 break;
2464
2465 case UINT64_MAX: opcodes[pc->opcode] = Op_const_umax_64; break;
2466 }
22402467 pc->opcode += 1;
2241 operands[pc->operand + 0] = x & UINT32_MAX;
2242 operands[pc->operand + 1] = (x >> 32) & UINT32_MAX;
2243 pc->operand += 2;
22442468 }
22452469 }
22462470 break;
22472471
2248 case WasmOp_i32_add:
2249 opcodes[pc->opcode] = Op_add_32;
2250 pc->opcode += 1;
2251 break;
2252
2253 case WasmOp_i32_and:
2254 opcodes[pc->opcode] = Op_and_32;
2255 pc->opcode += 1;
2256 break;
2257
22582472 default:
22592473 if (unreachable_depth == 0) {
2260 opcodes[pc->opcode + 0] = Op_wasm;
2261 opcodes[pc->opcode + 1] = opcode;
2262 pc->opcode += 2;
2474 switch (opcode) {
2475 case WasmOp_i32_eqz: opcodes[pc->opcode] = Op_eqz_32; break;
2476 case WasmOp_i32_eq: opcodes[pc->opcode] = Op_eq_32; break;
2477 case WasmOp_i32_ne: opcodes[pc->opcode] = Op_ne_32; break;
2478 case WasmOp_i32_lt_s: opcodes[pc->opcode] = Op_slt_32; break;
2479 case WasmOp_i32_lt_u: opcodes[pc->opcode] = Op_ult_32; break;
2480 case WasmOp_i32_gt_s: opcodes[pc->opcode] = Op_sgt_32; break;
2481 case WasmOp_i32_gt_u: opcodes[pc->opcode] = Op_ugt_32; break;
2482 case WasmOp_i32_le_s: opcodes[pc->opcode] = Op_sle_32; break;
2483 case WasmOp_i32_le_u: opcodes[pc->opcode] = Op_ule_32; break;
2484 case WasmOp_i32_ge_s: opcodes[pc->opcode] = Op_sge_32; break;
2485 case WasmOp_i32_ge_u: opcodes[pc->opcode] = Op_uge_32; break;
2486 case WasmOp_i64_eqz: opcodes[pc->opcode] = Op_eqz_64; break;
2487 case WasmOp_i64_eq: opcodes[pc->opcode] = Op_eq_64; break;
2488 case WasmOp_i64_ne: opcodes[pc->opcode] = Op_ne_64; break;
2489 case WasmOp_i64_lt_s: opcodes[pc->opcode] = Op_slt_64; break;
2490 case WasmOp_i64_lt_u: opcodes[pc->opcode] = Op_ult_64; break;
2491 case WasmOp_i64_gt_s: opcodes[pc->opcode] = Op_sgt_64; break;
2492 case WasmOp_i64_gt_u: opcodes[pc->opcode] = Op_ugt_64; break;
2493 case WasmOp_i64_le_s: opcodes[pc->opcode] = Op_sle_64; break;
2494 case WasmOp_i64_le_u: opcodes[pc->opcode] = Op_ule_64; break;
2495 case WasmOp_i64_ge_s: opcodes[pc->opcode] = Op_sge_64; break;
2496 case WasmOp_i64_ge_u: opcodes[pc->opcode] = Op_uge_64; break;
2497 case WasmOp_f32_eq: opcodes[pc->opcode] = Op_feq_32; break;
2498 case WasmOp_f32_ne: opcodes[pc->opcode] = Op_fne_32; break;
2499 case WasmOp_f32_lt: opcodes[pc->opcode] = Op_flt_32; break;
2500 case WasmOp_f32_gt: opcodes[pc->opcode] = Op_fgt_32; break;
2501 case WasmOp_f32_le: opcodes[pc->opcode] = Op_fle_32; break;
2502 case WasmOp_f32_ge: opcodes[pc->opcode] = Op_fge_32; break;
2503 case WasmOp_f64_eq: opcodes[pc->opcode] = Op_feq_64; break;
2504 case WasmOp_f64_ne: opcodes[pc->opcode] = Op_fne_64; break;
2505 case WasmOp_f64_lt: opcodes[pc->opcode] = Op_flt_64; break;
2506 case WasmOp_f64_gt: opcodes[pc->opcode] = Op_fgt_64; break;
2507 case WasmOp_f64_le: opcodes[pc->opcode] = Op_fle_64; break;
2508 case WasmOp_f64_ge: opcodes[pc->opcode] = Op_fge_64; break;
2509 case WasmOp_i32_clz: opcodes[pc->opcode] = Op_clz_32; break;
2510 case WasmOp_i32_ctz: opcodes[pc->opcode] = Op_ctz_32; break;
2511 case WasmOp_i32_popcnt: opcodes[pc->opcode] = Op_popcnt_32; break;
2512 case WasmOp_i32_add: opcodes[pc->opcode] = Op_add_32; break;
2513 case WasmOp_i32_sub: opcodes[pc->opcode] = Op_sub_32; break;
2514 case WasmOp_i32_mul: opcodes[pc->opcode] = Op_mul_32; break;
2515 case WasmOp_i32_div_s: opcodes[pc->opcode] = Op_sdiv_32; break;
2516 case WasmOp_i32_div_u: opcodes[pc->opcode] = Op_udiv_32; break;
2517 case WasmOp_i32_rem_s: opcodes[pc->opcode] = Op_srem_32; break;
2518 case WasmOp_i32_rem_u: opcodes[pc->opcode] = Op_urem_32; break;
2519 case WasmOp_i32_and: opcodes[pc->opcode] = Op_and_32; break;
2520 case WasmOp_i32_or: opcodes[pc->opcode] = Op_or_32; break;
2521 case WasmOp_i32_xor: opcodes[pc->opcode] = Op_xor_32; break;
2522 case WasmOp_i32_shl: opcodes[pc->opcode] = Op_shl_32; break;
2523 case WasmOp_i32_shr_s: opcodes[pc->opcode] = Op_ashr_32; break;
2524 case WasmOp_i32_shr_u: opcodes[pc->opcode] = Op_lshr_32; break;
2525 case WasmOp_i32_rotl: opcodes[pc->opcode] = Op_rol_32; break;
2526 case WasmOp_i32_rotr: opcodes[pc->opcode] = Op_ror_32; break;
2527 case WasmOp_i64_clz: opcodes[pc->opcode] = Op_clz_64; break;
2528 case WasmOp_i64_ctz: opcodes[pc->opcode] = Op_ctz_64; break;
2529 case WasmOp_i64_popcnt: opcodes[pc->opcode] = Op_popcnt_64; break;
2530 case WasmOp_i64_add: opcodes[pc->opcode] = Op_add_64; break;
2531 case WasmOp_i64_sub: opcodes[pc->opcode] = Op_sub_64; break;
2532 case WasmOp_i64_mul: opcodes[pc->opcode] = Op_mul_64; break;
2533 case WasmOp_i64_div_s: opcodes[pc->opcode] = Op_sdiv_64; break;
2534 case WasmOp_i64_div_u: opcodes[pc->opcode] = Op_udiv_64; break;
2535 case WasmOp_i64_rem_s: opcodes[pc->opcode] = Op_srem_64; break;
2536 case WasmOp_i64_rem_u: opcodes[pc->opcode] = Op_urem_64; break;
2537 case WasmOp_i64_and: opcodes[pc->opcode] = Op_and_64; break;
2538 case WasmOp_i64_or: opcodes[pc->opcode] = Op_or_64; break;
2539 case WasmOp_i64_xor: opcodes[pc->opcode] = Op_xor_64; break;
2540 case WasmOp_i64_shl: opcodes[pc->opcode] = Op_shl_64; break;
2541 case WasmOp_i64_shr_s: opcodes[pc->opcode] = Op_ashr_64; break;
2542 case WasmOp_i64_shr_u: opcodes[pc->opcode] = Op_lshr_64; break;
2543 case WasmOp_i64_rotl: opcodes[pc->opcode] = Op_rol_64; break;
2544 case WasmOp_i64_rotr: opcodes[pc->opcode] = Op_ror_64; break;
2545 case WasmOp_f32_abs: opcodes[pc->opcode] = Op_fabs_32; break;
2546 case WasmOp_f32_neg: opcodes[pc->opcode] = Op_fneg_32; break;
2547 case WasmOp_f32_ceil: opcodes[pc->opcode] = Op_ceil_32; break;
2548 case WasmOp_f32_floor: opcodes[pc->opcode] = Op_floor_32; break;
2549 case WasmOp_f32_trunc: opcodes[pc->opcode] = Op_trunc_32; break;
2550 case WasmOp_f32_nearest: opcodes[pc->opcode] = Op_nearest_32; break;
2551 case WasmOp_f32_sqrt: opcodes[pc->opcode] = Op_sqrt_32; break;
2552 case WasmOp_f32_add: opcodes[pc->opcode] = Op_fadd_32; break;
2553 case WasmOp_f32_sub: opcodes[pc->opcode] = Op_fsub_32; break;
2554 case WasmOp_f32_mul: opcodes[pc->opcode] = Op_fmul_32; break;
2555 case WasmOp_f32_div: opcodes[pc->opcode] = Op_fdiv_32; break;
2556 case WasmOp_f32_min: opcodes[pc->opcode] = Op_fmin_32; break;
2557 case WasmOp_f32_max: opcodes[pc->opcode] = Op_fmax_32; break;
2558 case WasmOp_f32_copysign: opcodes[pc->opcode] = Op_copysign_32; break;
2559 case WasmOp_f64_abs: opcodes[pc->opcode] = Op_fabs_64; break;
2560 case WasmOp_f64_neg: opcodes[pc->opcode] = Op_fneg_64; break;
2561 case WasmOp_f64_ceil: opcodes[pc->opcode] = Op_ceil_64; break;
2562 case WasmOp_f64_floor: opcodes[pc->opcode] = Op_floor_64; break;
2563 case WasmOp_f64_trunc: opcodes[pc->opcode] = Op_trunc_64; break;
2564 case WasmOp_f64_nearest: opcodes[pc->opcode] = Op_nearest_64; break;
2565 case WasmOp_f64_sqrt: opcodes[pc->opcode] = Op_sqrt_64; break;
2566 case WasmOp_f64_add: opcodes[pc->opcode] = Op_fadd_64; break;
2567 case WasmOp_f64_sub: opcodes[pc->opcode] = Op_fsub_64; break;
2568 case WasmOp_f64_mul: opcodes[pc->opcode] = Op_fmul_64; break;
2569 case WasmOp_f64_div: opcodes[pc->opcode] = Op_fdiv_64; break;
2570 case WasmOp_f64_min: opcodes[pc->opcode] = Op_fmin_64; break;
2571 case WasmOp_f64_max: opcodes[pc->opcode] = Op_fmax_64; break;
2572 case WasmOp_f64_copysign: opcodes[pc->opcode] = Op_copysign_64; break;
2573 case WasmOp_i32_wrap_i64: opcodes[pc->opcode] = Op_wrap_32_64; break;
2574 case WasmOp_i32_trunc_f32_s: opcodes[pc->opcode] = Op_ftos_32_32; break;
2575 case WasmOp_i32_trunc_f32_u: opcodes[pc->opcode] = Op_ftou_32_32; break;
2576 case WasmOp_i32_trunc_f64_s: opcodes[pc->opcode] = Op_ftos_32_64; break;
2577 case WasmOp_i32_trunc_f64_u: opcodes[pc->opcode] = Op_ftou_32_64; break;
2578 case WasmOp_i64_extend_i32_s: opcodes[pc->opcode] = Op_sext_64_32; break;
2579 case WasmOp_i64_extend_i32_u: opcodes[pc->opcode] = Op_zext_64_32; break;
2580 case WasmOp_i64_trunc_f32_s: opcodes[pc->opcode] = Op_ftos_64_32; break;
2581 case WasmOp_i64_trunc_f32_u: opcodes[pc->opcode] = Op_ftou_64_32; break;
2582 case WasmOp_i64_trunc_f64_s: opcodes[pc->opcode] = Op_ftos_64_64; break;
2583 case WasmOp_i64_trunc_f64_u: opcodes[pc->opcode] = Op_ftou_64_64; break;
2584 case WasmOp_f32_convert_i32_s: opcodes[pc->opcode] = Op_stof_32_32; break;
2585 case WasmOp_f32_convert_i32_u: opcodes[pc->opcode] = Op_utof_32_32; break;
2586 case WasmOp_f32_convert_i64_s: opcodes[pc->opcode] = Op_stof_32_64; break;
2587 case WasmOp_f32_convert_i64_u: opcodes[pc->opcode] = Op_utof_32_64; break;
2588 case WasmOp_f32_demote_f64: opcodes[pc->opcode] = Op_ftof_32_64; break;
2589 case WasmOp_f64_convert_i32_s: opcodes[pc->opcode] = Op_stof_64_32; break;
2590 case WasmOp_f64_convert_i32_u: opcodes[pc->opcode] = Op_utof_64_32; break;
2591 case WasmOp_f64_convert_i64_s: opcodes[pc->opcode] = Op_stof_64_64; break;
2592 case WasmOp_f64_convert_i64_u: opcodes[pc->opcode] = Op_utof_64_64; break;
2593 case WasmOp_f64_promote_f32: opcodes[pc->opcode] = Op_ftof_64_32; break;
2594 case WasmOp_i32_extend8_s: opcodes[pc->opcode] = Op_sext8_32; break;
2595 case WasmOp_i32_extend16_s: opcodes[pc->opcode] = Op_sext16_32; break;
2596 case WasmOp_i64_extend8_s: opcodes[pc->opcode] = Op_sext8_64; break;
2597 case WasmOp_i64_extend16_s: opcodes[pc->opcode] = Op_sext16_64; break;
2598 case WasmOp_i64_extend32_s: opcodes[pc->opcode] = Op_sext32_64; break;
2599 default: panic("unexpected opcode");
2600 }
2601 pc->opcode += 1;
22632602 }
22642603 break;
22652604
22662605 case WasmOp_prefixed:
22672606 switch (prefixed_opcode) {
2268 case WasmPrefixedOp_i32_trunc_sat_f32_s:
2269 case WasmPrefixedOp_i32_trunc_sat_f32_u:
2270 case WasmPrefixedOp_i32_trunc_sat_f64_s:
2271 case WasmPrefixedOp_i32_trunc_sat_f64_u:
2272 case WasmPrefixedOp_i64_trunc_sat_f32_s:
2273 case WasmPrefixedOp_i64_trunc_sat_f32_u:
2274 case WasmPrefixedOp_i64_trunc_sat_f64_s:
2275 case WasmPrefixedOp_i64_trunc_sat_f64_u:
2276 if (unreachable_depth == 0) {
2277 opcodes[pc->opcode + 0] = Op_wasm_prefixed;
2278 opcodes[pc->opcode + 1] = prefixed_opcode;
2279 pc->opcode += 2;
2280 }
2281 break;
2282
22832607 case WasmPrefixedOp_memory_copy:
22842608 if (mod_ptr[*code_i + 0] != 0 || mod_ptr[*code_i + 1] != 0)
22852609 panic("unexpected memory index");
22862610 *code_i += 2;
22872611 if (unreachable_depth == 0) {
2288 opcodes[pc->opcode + 0] = Op_wasm_prefixed;
2289 opcodes[pc->opcode + 1] = prefixed_opcode;
2290 pc->opcode += 2;
2612 opcodes[pc->opcode] = Op_memcpy;
2613 pc->opcode += 1;
22912614 }
22922615 break;
22932616
......@@ -2295,27 +2618,18 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
22952618 if (mod_ptr[*code_i] != 0) panic("unexpected memory index");
22962619 *code_i += 1;
22972620 if (unreachable_depth == 0) {
2298 opcodes[pc->opcode + 0] = Op_wasm_prefixed;
2299 opcodes[pc->opcode + 1] = prefixed_opcode;
2300 pc->opcode += 2;
2621 opcodes[pc->opcode] = Op_memset;
2622 pc->opcode += 1;
23012623 }
23022624 break;
23032625
2304 default: panic("unreachable");
2626 default: panic("unexpected opcode");
23052627 }
23062628 break;
23072629 }
2308
23092630 switch (opcode) {
2310 case WasmOp_unreachable:
2311 case WasmOp_return:
2312 case WasmOp_br:
2313 case WasmOp_br_table:
2314 if (unreachable_depth == 0) unreachable_depth = 1;
2315 break;
2316
2317 default:
2318 break;
2631 default: state = State_default; break;
2632 case WasmOp_i32_eqz: state = State_bool_not; break;
23192633 }
23202634
23212635 //for (uint32_t i = old_pc.opcode; i < pc->opcode; i += 1) {
......@@ -2328,70 +2642,71 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
23282642}
23292643
23302644static void vm_push_u32(struct VirtualMachine *vm, uint32_t value) {
2331 vm->stack[vm->stack_top] = value;
2645 vm->stack[vm->stack_top + 0] = value;
23322646 vm->stack_top += 1;
23332647}
23342648
23352649static void vm_push_i32(struct VirtualMachine *vm, int32_t value) {
2336 return vm_push_u32(vm, value);
2650 vm_push_u32(vm, (uint32_t)value);
23372651}
23382652
23392653static void vm_push_u64(struct VirtualMachine *vm, uint64_t value) {
2340 vm->stack[vm->stack_top] = value;
2341 vm->stack_top += 1;
2654 vm->stack[vm->stack_top + 0] = (uint32_t)(value >> 0);
2655 vm->stack[vm->stack_top + 1] = (uint32_t)(value >> 32);
2656 vm->stack_top += 2;
23422657}
23432658
23442659static void vm_push_i64(struct VirtualMachine *vm, int64_t value) {
2345 return vm_push_u64(vm, value);
2660 vm_push_u64(vm, (uint64_t)value);
23462661}
23472662
23482663static void vm_push_f32(struct VirtualMachine *vm, float value) {
23492664 uint32_t integer;
2350 memcpy(&integer, &value, 4);
2351 return vm_push_u32(vm, integer);
2665 memcpy(&integer, &value, sizeof(integer));
2666 vm_push_u32(vm, integer);
23522667}
23532668
23542669static void vm_push_f64(struct VirtualMachine *vm, double value) {
23552670 uint64_t integer;
2356 memcpy(&integer, &value, 8);
2357 return vm_push_u64(vm, integer);
2671 memcpy(&integer, &value, sizeof(integer));
2672 vm_push_u64(vm, integer);
23582673}
23592674
23602675static uint32_t vm_pop_u32(struct VirtualMachine *vm) {
23612676 vm->stack_top -= 1;
2362 return vm->stack[vm->stack_top];
2677 return vm->stack[vm->stack_top + 0];
23632678}
23642679
23652680static int32_t vm_pop_i32(struct VirtualMachine *vm) {
2366 return vm_pop_u32(vm);
2681 return (int32_t)vm_pop_u32(vm);
23672682}
23682683
23692684static uint64_t vm_pop_u64(struct VirtualMachine *vm) {
2370 vm->stack_top -= 1;
2371 return vm->stack[vm->stack_top];
2685 vm->stack_top -= 2;
2686 return vm->stack[vm->stack_top + 0] | (uint64_t)vm->stack[vm->stack_top + 1] << 32;
23722687}
23732688
23742689static int64_t vm_pop_i64(struct VirtualMachine *vm) {
2375 return vm_pop_u64(vm);
2690 return (int64_t)vm_pop_u64(vm);
23762691}
23772692
23782693static float vm_pop_f32(struct VirtualMachine *vm) {
23792694 uint32_t integer = vm_pop_u32(vm);
23802695 float result;
2381 memcpy(&result, &integer, 4);
2696 memcpy(&result, &integer, sizeof(result));
23822697 return result;
23832698}
23842699
23852700static double vm_pop_f64(struct VirtualMachine *vm) {
23862701 uint64_t integer = vm_pop_u64(vm);
23872702 double result;
2388 memcpy(&result, &integer, 8);
2703 memcpy(&result, &integer, sizeof(result));
23892704 return result;
23902705}
23912706
2392static void vm_callImport(struct VirtualMachine *vm, struct Import import) {
2393 switch (import.mod) {
2394 case ImpMod_wasi_snapshot_preview1: switch (import.name) {
2707static void vm_callImport(struct VirtualMachine *vm, const struct Import *import) {
2708 switch (import->mod) {
2709 case ImpMod_wasi_snapshot_preview1: switch (import->name) {
23952710 case ImpName_fd_prestat_get:
23962711 {
23972712 uint32_t buf = vm_pop_u32(vm);
......@@ -2613,21 +2928,14 @@ static void vm_callImport(struct VirtualMachine *vm, struct Import import) {
26132928 }
26142929}
26152930
2616static void vm_call(struct VirtualMachine *vm, uint32_t fn_id) {
2617 if (fn_id < vm->imports_len) {
2618 struct Import imp = vm->imports[fn_id];
2619 return vm_callImport(vm, imp);
2620 }
2621 uint32_t fn_idx = fn_id - vm->imports_len;
2622 struct Function *func = &vm->functions[fn_idx];
2623
2931static void vm_call(struct VirtualMachine *vm, const struct Function *func) {
26242932 //struct TypeInfo *type_info = &vm->types[func->type_idx];
2625 //fprintf(stderr, "enter fn_id: %u, param_count: %u, result_count: %u, locals_count: %u\n",
2626 // fn_id, type_info->param_count, type_info->result_count, func->locals_count);
2933 //fprintf(stderr, "enter fn_id: %u, param_count: %u, result_count: %u, locals_size: %u\n",
2934 // func->id, type_info->param_count, type_info->result_count, func->locals_size);
26272935
26282936 // Push zeroed locals to stack
2629 memset(vm->stack + vm->stack_top, 0, func->locals_count * sizeof(uint64_t));
2630 vm->stack_top += func->locals_count;
2937 memset(&vm->stack[vm->stack_top], 0, func->locals_size * sizeof(uint32_t));
2938 vm->stack_top += func->locals_size;
26312939
26322940 vm_push_u32(vm, vm->pc.opcode);
26332941 vm_push_u32(vm, vm->pc.operand);
......@@ -2667,36 +2975,41 @@ static void vm_br_u64(struct VirtualMachine *vm) {
26672975}
26682976
26692977static void vm_return_void(struct VirtualMachine *vm) {
2670 uint32_t ret_pc_offset = vm->operands[vm->pc.operand + 0];
2671 uint32_t stack_adjust = vm->operands[vm->pc.operand + 1];
2672
2673 vm->pc.opcode = vm->stack[vm->stack_top - ret_pc_offset];
2674 vm->pc.operand = vm->stack[vm->stack_top - ret_pc_offset + 1];
2978 uint32_t stack_adjust = vm->operands[vm->pc.operand + 0];
2979 uint32_t frame_size = vm->operands[vm->pc.operand + 1];
26752980
26762981 vm->stack_top -= stack_adjust;
2982 vm->pc.operand = vm_pop_u32(vm);
2983 vm->pc.opcode = vm_pop_u32(vm);
2984
2985 vm->stack_top -= frame_size;
26772986}
26782987
26792988static void vm_return_u32(struct VirtualMachine *vm) {
2680 uint32_t ret_pc_offset = vm->operands[vm->pc.operand + 0];
2681 uint32_t stack_adjust = vm->operands[vm->pc.operand + 1];
2682
2683 vm->pc.opcode = vm->stack[vm->stack_top - ret_pc_offset];
2684 vm->pc.operand = vm->stack[vm->stack_top - ret_pc_offset + 1];
2989 uint32_t stack_adjust = vm->operands[vm->pc.operand + 0];
2990 uint32_t frame_size = vm->operands[vm->pc.operand + 1];
26852991
26862992 uint32_t result = vm_pop_u32(vm);
2993
26872994 vm->stack_top -= stack_adjust;
2995 vm->pc.operand = vm_pop_u32(vm);
2996 vm->pc.opcode = vm_pop_u32(vm);
2997
2998 vm->stack_top -= frame_size;
26882999 vm_push_u32(vm, result);
26893000}
26903001
26913002static void vm_return_u64(struct VirtualMachine *vm) {
2692 uint32_t ret_pc_offset = vm->operands[vm->pc.operand + 0];
2693 uint32_t stack_adjust = vm->operands[vm->pc.operand + 1];
2694
2695 vm->pc.opcode = vm->stack[vm->stack_top - ret_pc_offset];
2696 vm->pc.operand = vm->stack[vm->stack_top - ret_pc_offset + 1];
3003 uint32_t stack_adjust = vm->operands[vm->pc.operand + 0];
3004 uint32_t frame_size = vm->operands[vm->pc.operand + 1];
26973005
26983006 uint64_t result = vm_pop_u64(vm);
3007
26993008 vm->stack_top -= stack_adjust;
3009 vm->pc.operand = vm_pop_u32(vm);
3010 vm->pc.opcode = vm_pop_u32(vm);
3011
3012 vm->stack_top -= frame_size;
27003013 vm_push_u64(vm, result);
27013014}
27023015
......@@ -2704,77 +3017,68 @@ static void vm_run(struct VirtualMachine *vm) {
27043017 uint8_t *opcodes = vm->opcodes;
27053018 uint32_t *operands = vm->operands;
27063019 struct ProgramCounter *pc = &vm->pc;
3020 uint32_t global_0 = vm->globals[0];
27073021 for (;;) {
27083022 enum Op op = opcodes[pc->opcode];
3023 //fprintf(stderr, "stack[%u:%u]=%x:%x pc=%x:%x op=%u\n",
3024 // vm->stack_top - 2, vm->stack_top - 1,
3025 // vm->stack[vm->stack_top - 2], vm->stack[vm->stack_top - 1],
3026 // pc->opcode, pc->operand, op);
27093027 pc->opcode += 1;
2710 //if (vm->stack_top > 0) {
2711 // fprintf(stderr, "stack[%u]=%lx pc=%u:%u, op=%u\n",
2712 // vm->stack_top - 1, vm->stack[vm->stack_top - 1], pc->opcode, pc->operand, op);
2713 //}
27143028 switch (op) {
27153029 case Op_unreachable:
27163030 panic("unreachable reached");
2717
27183031 case Op_br_void:
27193032 vm_br_void(vm);
27203033 break;
2721
27223034 case Op_br_32:
27233035 vm_br_u32(vm);
27243036 break;
2725
27263037 case Op_br_64:
27273038 vm_br_u64(vm);
27283039 break;
2729
2730 case Op_br_if_nez_void:
3040 case Op_br_nez_void:
27313041 if (vm_pop_u32(vm) != 0) {
27323042 vm_br_void(vm);
27333043 } else {
27343044 pc->operand += 3;
27353045 }
27363046 break;
2737
2738 case Op_br_if_nez_32:
3047 case Op_br_nez_32:
27393048 if (vm_pop_u32(vm) != 0) {
27403049 vm_br_u32(vm);
27413050 } else {
27423051 pc->operand += 3;
27433052 }
27443053 break;
2745
2746 case Op_br_if_nez_64:
3054 case Op_br_nez_64:
27473055 if (vm_pop_u32(vm) != 0) {
27483056 vm_br_u64(vm);
27493057 } else {
27503058 pc->operand += 3;
27513059 }
27523060 break;
2753
2754 case Op_br_if_eqz_void:
3061 case Op_br_eqz_void:
27553062 if (vm_pop_u32(vm) == 0) {
27563063 vm_br_void(vm);
27573064 } else {
27583065 pc->operand += 3;
27593066 }
27603067 break;
2761
2762 case Op_br_if_eqz_32:
3068 case Op_br_eqz_32:
27633069 if (vm_pop_u32(vm) == 0) {
27643070 vm_br_u32(vm);
27653071 } else {
27663072 pc->operand += 3;
27673073 }
27683074 break;
2769
2770 case Op_br_if_eqz_64:
3075 case Op_br_eqz_64:
27713076 if (vm_pop_u32(vm) == 0) {
27723077 vm_br_u64(vm);
27733078 } else {
27743079 pc->operand += 3;
27753080 }
27763081 break;
2777
27783082 case Op_br_table_void:
27793083 {
27803084 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);
......@@ -2782,7 +3086,6 @@ static void vm_run(struct VirtualMachine *vm) {
27823086 vm_br_void(vm);
27833087 }
27843088 break;
2785
27863089 case Op_br_table_32:
27873090 {
27883091 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);
......@@ -2790,7 +3093,6 @@ static void vm_run(struct VirtualMachine *vm) {
27903093 vm_br_u32(vm);
27913094 }
27923095 break;
2793
27943096 case Op_br_table_64:
27953097 {
27963098 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);
......@@ -2798,32 +3100,45 @@ static void vm_run(struct VirtualMachine *vm) {
27983100 vm_br_u64(vm);
27993101 }
28003102 break;
2801
28023103 case Op_return_void:
28033104 vm_return_void(vm);
28043105 break;
2805
28063106 case Op_return_32:
28073107 vm_return_u32(vm);
28083108 break;
2809
28103109 case Op_return_64:
28113110 vm_return_u64(vm);
28123111 break;
2813
2814 case Op_call:
3112 case Op_call_import:
3113 {
3114 uint8_t import_idx = opcodes[pc->opcode];
3115 pc->opcode += 1;
3116 vm_callImport(vm, &vm->imports[import_idx]);
3117 }
3118 break;
3119 case Op_call_func:
28153120 {
2816 uint32_t fn_id = operands[pc->operand];
3121 uint32_t func_idx = operands[pc->operand];
28173122 pc->operand += 1;
2818 vm_call(vm, fn_id);
3123 vm_call(vm, &vm->functions[func_idx]);
3124 }
3125 break;
3126 case Op_call_indirect:
3127 {
3128 uint32_t fn_id = vm->table[vm_pop_u32(vm)];
3129 if (fn_id < vm->imports_len)
3130 vm_callImport(vm, &vm->imports[fn_id]);
3131 else
3132 vm_call(vm, &vm->functions[fn_id - vm->imports_len]);
28193133 }
28203134 break;
28213135
28223136 case Op_drop_32:
2823 case Op_drop_64:
28243137 vm->stack_top -= 1;
28253138 break;
2826
3139 case Op_drop_64:
3140 vm->stack_top -= 2;
3141 break;
28273142 case Op_select_32:
28283143 {
28293144 uint32_t c = vm_pop_u32(vm);
......@@ -2833,7 +3148,6 @@ static void vm_run(struct VirtualMachine *vm) {
28333148 vm_push_u32(vm, result);
28343149 }
28353150 break;
2836
28373151 case Op_select_64:
28383152 {
28393153 uint32_t c = vm_pop_u32(vm);
......@@ -2846,49 +3160,53 @@ static void vm_run(struct VirtualMachine *vm) {
28463160
28473161 case Op_local_get_32:
28483162 {
2849 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
3163 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
28503164 pc->operand += 1;
28513165 vm_push_u32(vm, *local);
28523166 }
28533167 break;
2854
28553168 case Op_local_get_64:
28563169 {
2857 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
3170 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
28583171 pc->operand += 1;
2859 vm_push_u64(vm, *local);
3172 vm_push_u64(vm, local[0] | (uint64_t)local[1] << 32);
28603173 }
28613174 break;
2862
28633175 case Op_local_set_32:
28643176 {
2865 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
3177 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
28663178 pc->operand += 1;
28673179 *local = vm_pop_u32(vm);
28683180 }
28693181 break;
2870
28713182 case Op_local_set_64:
28723183 {
2873 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
3184 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
28743185 pc->operand += 1;
2875 *local = vm_pop_u64(vm);
3186 uint64_t value = vm_pop_u64(vm);
3187 local[0] = (uint32_t)(value >> 0);
3188 local[1] = (uint32_t)(value >> 32);
28763189 }
28773190 break;
2878
28793191 case Op_local_tee_32:
2880 case Op_local_tee_64:
28813192 {
2882 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
3193 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
28833194 pc->operand += 1;
28843195 *local = vm->stack[vm->stack_top - 1];
28853196 }
28863197 break;
3198 case Op_local_tee_64:
3199 {
3200 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
3201 pc->operand += 1;
3202 local[0] = vm->stack[vm->stack_top - 2];
3203 local[1] = vm->stack[vm->stack_top - 1];
3204 }
3205 break;
28873206
28883207 case Op_global_get_0_32:
2889 vm_push_u32(vm, vm->globals[0]);
3208 vm_push_u32(vm, global_0);
28903209 break;
2891
28923210 case Op_global_get_32:
28933211 {
28943212 uint32_t idx = operands[pc->operand];
......@@ -2896,11 +3214,9 @@ static void vm_run(struct VirtualMachine *vm) {
28963214 vm_push_u32(vm, vm->globals[idx]);
28973215 }
28983216 break;
2899
29003217 case Op_global_set_0_32:
2901 vm->globals[0] = vm_pop_u32(vm);
3218 global_0 = vm_pop_u32(vm);
29023219 break;
2903
29043220 case Op_global_set_32:
29053221 {
29063222 uint32_t idx = operands[pc->operand];
......@@ -2909,1140 +3225,850 @@ static void vm_run(struct VirtualMachine *vm) {
29093225 }
29103226 break;
29113227
2912 case Op_const_32:
3228 case Op_load_0_8:
29133229 {
2914 uint32_t x = operands[pc->operand];
3230 uint32_t address = vm_pop_u32(vm);
3231 vm_push_u32(vm, (uint8_t)vm->memory[address]);
3232 }
3233 break;
3234 case Op_load_8:
3235 {
3236 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
29153237 pc->operand += 1;
2916 vm_push_i32(vm, x);
3238 vm_push_u32(vm, (uint8_t)vm->memory[address]);
29173239 }
29183240 break;
2919
2920 case Op_const_64:
3241 case Op_load_0_16:
29213242 {
2922 uint64_t x = ((uint64_t)operands[pc->operand]) |
2923 (((uint64_t)operands[pc->operand + 1]) << 32);
2924 pc->operand += 2;
2925 vm_push_i64(vm, x);
3243 uint32_t address = vm_pop_u32(vm);
3244 vm_push_u32(vm, read_u16_le(&vm->memory[address]));
29263245 }
29273246 break;
2928
2929 case Op_add_32:
3247 case Op_load_16:
29303248 {
2931 uint32_t rhs = vm_pop_u32(vm);
2932 uint32_t lhs = vm_pop_u32(vm);
2933 vm_push_u32(vm, lhs + rhs);
3249 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3250 pc->operand += 1;
3251 vm_push_u32(vm, read_u16_le(&vm->memory[address]));
29343252 }
29353253 break;
2936
2937 case Op_and_32:
3254 case Op_load_0_32:
29383255 {
2939 uint32_t rhs = vm_pop_u32(vm);
2940 uint32_t lhs = vm_pop_u32(vm);
2941 vm_push_u32(vm, lhs & rhs);
3256 uint32_t address = vm_pop_u32(vm);
3257 vm_push_u32(vm, read_u32_le(&vm->memory[address]));
29423258 }
29433259 break;
2944
2945 case Op_wasm:
3260 case Op_load_32:
29463261 {
2947 enum WasmOp wasm_op = opcodes[pc->opcode];
2948 //fprintf(stderr, "op2=%x\n", wasm_op);
2949 pc->opcode += 1;
2950 switch (wasm_op) {
2951 case WasmOp_unreachable:
2952 case WasmOp_nop:
2953 case WasmOp_block:
2954 case WasmOp_loop:
2955 case WasmOp_if:
2956 case WasmOp_else:
2957 case WasmOp_end:
2958 case WasmOp_br:
2959 case WasmOp_br_if:
2960 case WasmOp_br_table:
2961 case WasmOp_return:
2962 case WasmOp_call:
2963 case WasmOp_drop:
2964 case WasmOp_select:
2965 case WasmOp_local_get:
2966 case WasmOp_local_set:
2967 case WasmOp_local_tee:
2968 case WasmOp_global_get:
2969 case WasmOp_global_set:
2970 case WasmOp_i32_const:
2971 case WasmOp_i64_const:
2972 case WasmOp_f32_const:
2973 case WasmOp_f64_const:
2974 case WasmOp_i32_add:
2975 case WasmOp_i32_and:
2976 case WasmOp_i32_reinterpret_f32:
2977 case WasmOp_i64_reinterpret_f64:
2978 case WasmOp_f32_reinterpret_i32:
2979 case WasmOp_f64_reinterpret_i64:
2980 case WasmOp_prefixed:
2981 panic("not produced by decodeCode");
2982 break;
2983
2984 case WasmOp_call_indirect:
2985 {
2986 uint32_t fn_id = vm->table[vm_pop_u32(vm)];
2987 vm_call(vm, fn_id);
2988 }
2989 break;
2990 case WasmOp_i32_load:
2991 {
2992 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
2993 pc->operand += 1;
2994 vm_push_u32(vm, read_u32_le(vm->memory + offset));
2995 }
2996 break;
2997 case WasmOp_i64_load:
2998 {
2999 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3000 pc->operand += 1;
3001 vm_push_u64(vm, read_u64_le(vm->memory + offset));
3002 }
3003 break;
3004 case WasmOp_f32_load:
3005 {
3006 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3007 pc->operand += 1;
3008 uint32_t integer = read_u32_le(vm->memory + offset);
3009 vm_push_u32(vm, integer);
3010 }
3011 break;
3012 case WasmOp_f64_load:
3013 {
3014 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3015 pc->operand += 1;
3016 uint64_t integer = read_u64_le(vm->memory + offset);
3017 vm_push_u64(vm, integer);
3018 }
3019 break;
3020 case WasmOp_i32_load8_s:
3021 {
3022 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3023 pc->operand += 1;
3024 vm_push_i32(vm, (int8_t)vm->memory[offset]);
3025 }
3026 break;
3027 case WasmOp_i32_load8_u:
3028 {
3029 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3030 pc->operand += 1;
3031 vm_push_u32(vm, (uint8_t)vm->memory[offset]);
3032 }
3033 break;
3034 case WasmOp_i32_load16_s:
3035 {
3036 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3037 pc->operand += 1;
3038 int16_t integer = read_i16_le(vm->memory + offset);
3039 vm_push_i32(vm, integer);
3040 }
3041 break;
3042 case WasmOp_i32_load16_u:
3043 {
3044 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3045 pc->operand += 1;
3046 uint16_t integer = read_u16_le(vm->memory + offset);
3047 vm_push_u32(vm, integer);
3048 }
3049 break;
3050 case WasmOp_i64_load8_s:
3051 {
3052 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3053 pc->operand += 1;
3054 vm_push_i64(vm, (int8_t)vm->memory[offset]);
3055 }
3056 break;
3057 case WasmOp_i64_load8_u:
3058 {
3059 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3060 pc->operand += 1;
3061 vm_push_u64(vm, (uint8_t)vm->memory[offset]);
3062 }
3063 break;
3064 case WasmOp_i64_load16_s:
3065 {
3066 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3067 pc->operand += 1;
3068 int16_t integer = read_i16_le(vm->memory + offset);
3069 vm_push_i64(vm, integer);
3070 }
3071 break;
3072 case WasmOp_i64_load16_u:
3073 {
3074 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3075 pc->operand += 1;
3076 uint16_t integer = read_u16_le(vm->memory + offset);
3077 vm_push_u64(vm, integer);
3078 }
3079 break;
3080 case WasmOp_i64_load32_s:
3081 {
3082 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3083 pc->operand += 1;
3084 int32_t integer = read_i32_le(vm->memory + offset);
3085 vm_push_i64(vm, integer);
3086 }
3087 break;
3088 case WasmOp_i64_load32_u:
3089 {
3090 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3091 pc->operand += 1;
3092 uint32_t integer = read_u32_le(vm->memory + offset);
3093 vm_push_u64(vm, integer);
3094 }
3095 break;
3096 case WasmOp_i32_store:
3097 {
3098 uint32_t operand = vm_pop_u32(vm);
3099 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3100 pc->operand += 1;
3101 write_u32_le(vm->memory + offset, operand);
3102 }
3103 break;
3104 case WasmOp_i64_store:
3105 {
3106 uint64_t operand = vm_pop_u64(vm);
3107 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3108 pc->operand += 1;
3109 write_u64_le(vm->memory + offset, operand);
3110 }
3111 break;
3112 case WasmOp_f32_store:
3113 {
3114 uint32_t integer = vm_pop_u32(vm);
3115 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3116 pc->operand += 1;
3117 write_u32_le(vm->memory + offset, integer);
3118 }
3119 break;
3120 case WasmOp_f64_store:
3121 {
3122 uint64_t integer = vm_pop_u64(vm);
3123 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3124 pc->operand += 1;
3125 write_u64_le(vm->memory + offset, integer);
3126 }
3127 break;
3128 case WasmOp_i32_store8:
3129 {
3130 uint8_t small = vm_pop_u32(vm);
3131 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3132 pc->operand += 1;
3133 vm->memory[offset] = small;
3134 }
3135 break;
3136 case WasmOp_i32_store16:
3137 {
3138 uint16_t small = vm_pop_u32(vm);
3139 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3140 pc->operand += 1;
3141 write_u16_le(vm->memory + offset, small);
3142 }
3143 break;
3144 case WasmOp_i64_store8:
3145 {
3146 uint8_t operand = vm_pop_u64(vm);
3147 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3148 pc->operand += 1;
3149 vm->memory[offset] = operand;
3150 }
3151 break;
3152 case WasmOp_i64_store16:
3153 {
3154 uint16_t small = vm_pop_u64(vm);
3155 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3156 pc->operand += 1;
3157 write_u16_le(vm->memory + offset, small);
3158 }
3159 break;
3160 case WasmOp_i64_store32:
3161 {
3162 uint32_t small = vm_pop_u64(vm);
3163 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);
3164 pc->operand += 1;
3165 write_u32_le(vm->memory + offset, small);
3166 }
3167 break;
3168 case WasmOp_memory_size:
3169 {
3170 uint32_t page_count = vm->memory_len / wasm_page_size;
3171 vm_push_u32(vm, page_count);
3172 }
3173 break;
3174 case WasmOp_memory_grow:
3175 {
3176 uint32_t page_count = vm_pop_u32(vm);
3177 uint32_t old_page_count = vm->memory_len / wasm_page_size;
3178 uint32_t new_len = vm->memory_len + page_count * wasm_page_size;
3179 if (new_len > max_memory) {
3180 vm_push_i32(vm, -1);
3181 } else {
3182 vm->memory_len = new_len;
3183 vm_push_u32(vm, old_page_count);
3184 }
3185 }
3186 break;
3187 case WasmOp_i32_eqz:
3188 {
3189 uint32_t lhs = vm_pop_u32(vm);
3190 vm_push_u32(vm, lhs == 0);
3191 }
3192 break;
3193 case WasmOp_i32_eq:
3194 {
3195 uint32_t rhs = vm_pop_u32(vm);
3196 uint32_t lhs = vm_pop_u32(vm);
3197 vm_push_u32(vm, lhs == rhs);
3198 }
3199 break;
3200 case WasmOp_i32_ne:
3201 {
3202 uint32_t rhs = vm_pop_u32(vm);
3203 uint32_t lhs = vm_pop_u32(vm);
3204 vm_push_u32(vm, lhs != rhs);
3205 }
3206 break;
3207 case WasmOp_i32_lt_s:
3208 {
3209 int32_t rhs = vm_pop_i32(vm);
3210 int32_t lhs = vm_pop_i32(vm);
3211 vm_push_u32(vm, lhs < rhs);
3212 }
3213 break;
3214 case WasmOp_i32_lt_u:
3215 {
3216 uint32_t rhs = vm_pop_u32(vm);
3217 uint32_t lhs = vm_pop_u32(vm);
3218 vm_push_u32(vm, lhs < rhs);
3219 }
3220 break;
3221 case WasmOp_i32_gt_s:
3222 {
3223 int32_t rhs = vm_pop_i32(vm);
3224 int32_t lhs = vm_pop_i32(vm);
3225 vm_push_u32(vm, lhs > rhs);
3226 }
3227 break;
3228 case WasmOp_i32_gt_u:
3229 {
3230 uint32_t rhs = vm_pop_u32(vm);
3231 uint32_t lhs = vm_pop_u32(vm);
3232 vm_push_u32(vm, lhs > rhs);
3233 }
3234 break;
3235 case WasmOp_i32_le_s:
3236 {
3237 int32_t rhs = vm_pop_i32(vm);
3238 int32_t lhs = vm_pop_i32(vm);
3239 vm_push_u32(vm, lhs <= rhs);
3240 }
3241 break;
3242 case WasmOp_i32_le_u:
3243 {
3244 uint32_t rhs = vm_pop_u32(vm);
3245 uint32_t lhs = vm_pop_u32(vm);
3246 vm_push_u32(vm, lhs <= rhs);
3247 }
3248 break;
3249 case WasmOp_i32_ge_s:
3250 {
3251 int32_t rhs = vm_pop_i32(vm);
3252 int32_t lhs = vm_pop_i32(vm);
3253 vm_push_u32(vm, lhs >= rhs);
3254 }
3255 break;
3256 case WasmOp_i32_ge_u:
3257 {
3258 uint32_t rhs = vm_pop_u32(vm);
3259 uint32_t lhs = vm_pop_u32(vm);
3260 vm_push_u32(vm, lhs >= rhs);
3261 }
3262 break;
3263 case WasmOp_i64_eqz:
3264 {
3265 uint64_t lhs = vm_pop_u64(vm);
3266 vm_push_u32(vm, lhs == 0);
3267 }
3268 break;
3269 case WasmOp_i64_eq:
3270 {
3271 uint64_t rhs = vm_pop_u64(vm);
3272 uint64_t lhs = vm_pop_u64(vm);
3273 vm_push_u32(vm, lhs == rhs);
3274 }
3275 break;
3276 case WasmOp_i64_ne:
3277 {
3278 uint64_t rhs = vm_pop_u64(vm);
3279 uint64_t lhs = vm_pop_u64(vm);
3280 vm_push_u32(vm, lhs != rhs);
3281 }
3282 break;
3283 case WasmOp_i64_lt_s:
3284 {
3285 int64_t rhs = vm_pop_i64(vm);
3286 int64_t lhs = vm_pop_i64(vm);
3287 vm_push_u32(vm, lhs < rhs);
3288 }
3289 break;
3290 case WasmOp_i64_lt_u:
3291 {
3292 uint64_t rhs = vm_pop_u64(vm);
3293 uint64_t lhs = vm_pop_u64(vm);
3294 vm_push_u32(vm, lhs < rhs);
3295 }
3296 break;
3297 case WasmOp_i64_gt_s:
3298 {
3299 int64_t rhs = vm_pop_i64(vm);
3300 int64_t lhs = vm_pop_i64(vm);
3301 vm_push_u32(vm, lhs > rhs);
3302 }
3303 break;
3304 case WasmOp_i64_gt_u:
3305 {
3306 uint64_t rhs = vm_pop_u64(vm);
3307 uint64_t lhs = vm_pop_u64(vm);
3308 vm_push_u32(vm, lhs > rhs);
3309 }
3310 break;
3311 case WasmOp_i64_le_s:
3312 {
3313 int64_t rhs = vm_pop_i64(vm);
3314 int64_t lhs = vm_pop_i64(vm);
3315 vm_push_u32(vm, lhs <= rhs);
3316 }
3317 break;
3318 case WasmOp_i64_le_u:
3319 {
3320 uint64_t rhs = vm_pop_u64(vm);
3321 uint64_t lhs = vm_pop_u64(vm);
3322 vm_push_u32(vm, lhs <= rhs);
3323 }
3324 break;
3325 case WasmOp_i64_ge_s:
3326 {
3327 int64_t rhs = vm_pop_i64(vm);
3328 int64_t lhs = vm_pop_i64(vm);
3329 vm_push_u32(vm, lhs >= rhs);
3330 }
3331 break;
3332 case WasmOp_i64_ge_u:
3333 {
3334 uint64_t rhs = vm_pop_u64(vm);
3335 uint64_t lhs = vm_pop_u64(vm);
3336 vm_push_u32(vm, lhs >= rhs);
3337 }
3338 break;
3339 case WasmOp_f32_eq:
3340 {
3341 float rhs = vm_pop_f32(vm);
3342 float lhs = vm_pop_f32(vm);
3343 vm_push_u32(vm, lhs == rhs);
3344 }
3345 break;
3346 case WasmOp_f32_ne:
3347 {
3348 float rhs = vm_pop_f32(vm);
3349 float lhs = vm_pop_f32(vm);
3350 vm_push_u32(vm, lhs != rhs);
3351 }
3352 break;
3353 case WasmOp_f32_lt:
3354 {
3355 float rhs = vm_pop_f32(vm);
3356 float lhs = vm_pop_f32(vm);
3357 vm_push_u32(vm, lhs < rhs);
3358 }
3359 break;
3360 case WasmOp_f32_gt:
3361 {
3362 float rhs = vm_pop_f32(vm);
3363 float lhs = vm_pop_f32(vm);
3364 vm_push_u32(vm, lhs > rhs);
3365 }
3366 break;
3367 case WasmOp_f32_le:
3368 {
3369 float rhs = vm_pop_f32(vm);
3370 float lhs = vm_pop_f32(vm);
3371 vm_push_u32(vm, lhs <= rhs);
3372 }
3373 break;
3374 case WasmOp_f32_ge:
3375 {
3376 float rhs = vm_pop_f32(vm);
3377 float lhs = vm_pop_f32(vm);
3378 vm_push_u32(vm, lhs >= rhs);
3379 }
3380 break;
3381 case WasmOp_f64_eq:
3382 {
3383 double rhs = vm_pop_f64(vm);
3384 double lhs = vm_pop_f64(vm);
3385 vm_push_u32(vm, lhs == rhs);
3386 }
3387 break;
3388 case WasmOp_f64_ne:
3389 {
3390 double rhs = vm_pop_f64(vm);
3391 double lhs = vm_pop_f64(vm);
3392 vm_push_u32(vm, lhs != rhs);
3393 }
3394 break;
3395 case WasmOp_f64_lt:
3396 {
3397 double rhs = vm_pop_f64(vm);
3398 double lhs = vm_pop_f64(vm);
3399 vm_push_u32(vm, lhs <= rhs);
3400 }
3401 break;
3402 case WasmOp_f64_gt:
3403 {
3404 double rhs = vm_pop_f64(vm);
3405 double lhs = vm_pop_f64(vm);
3406 vm_push_u32(vm, lhs > rhs);
3407 }
3408 break;
3409 case WasmOp_f64_le:
3410 {
3411 double rhs = vm_pop_f64(vm);
3412 double lhs = vm_pop_f64(vm);
3413 vm_push_u32(vm, lhs <= rhs);
3414 }
3415 break;
3416 case WasmOp_f64_ge:
3417 {
3418 double rhs = vm_pop_f64(vm);
3419 double lhs = vm_pop_f64(vm);
3420 vm_push_u32(vm, lhs >= rhs);
3421 }
3422 break;
3262 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3263 pc->operand += 1;
3264 vm_push_u32(vm, read_u32_le(&vm->memory[address]));
3265 }
3266 break;
3267 case Op_load_0_64:
3268 {
3269 uint32_t address = vm_pop_u32(vm);
3270 vm_push_u64(vm, read_u64_le(&vm->memory[address]));
3271 }
3272 break;
3273 case Op_load_64:
3274 {
3275 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3276 pc->operand += 1;
3277 vm_push_u64(vm, read_u64_le(&vm->memory[address]));
3278 }
3279 break;
3280 case Op_store_0_8:
3281 {
3282 uint8_t value = (uint8_t)vm_pop_u32(vm);
3283 uint32_t address = vm_pop_u32(vm);
3284 vm->memory[address] = value;
3285 }
3286 break;
3287 case Op_store_8:
3288 {
3289 uint8_t value = (uint8_t)vm_pop_u32(vm);
3290 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3291 pc->operand += 1;
3292 vm->memory[address] = value;
3293 }
3294 break;
3295 case Op_store_0_16:
3296 {
3297 uint16_t value = (uint16_t)vm_pop_u32(vm);
3298 uint32_t address = vm_pop_u32(vm);
3299 write_u16_le(&vm->memory[address], value);
3300 }
3301 break;
3302 case Op_store_16:
3303 {
3304 uint16_t value = (uint16_t)vm_pop_u32(vm);
3305 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3306 pc->operand += 1;
3307 write_u16_le(&vm->memory[address], value);
3308 }
3309 break;
3310 case Op_store_0_32:
3311 {
3312 uint32_t value = vm_pop_u32(vm);
3313 uint32_t address = vm_pop_u32(vm);
3314 write_u32_le(&vm->memory[address], value);
3315 }
3316 break;
3317 case Op_store_32:
3318 {
3319 uint32_t value = vm_pop_u32(vm);
3320 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3321 pc->operand += 1;
3322 write_u32_le(&vm->memory[address], value);
3323 }
3324 break;
3325 case Op_store_0_64:
3326 {
3327 uint64_t value = vm_pop_u64(vm);
3328 uint32_t address = vm_pop_u32(vm);
3329 write_u64_le(&vm->memory[address], value);
3330 }
3331 break;
3332 case Op_store_64:
3333 {
3334 uint64_t value = vm_pop_u64(vm);
3335 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3336 pc->operand += 1;
3337 write_u64_le(&vm->memory[address], value);
3338 }
3339 break;
3340 case Op_mem_size:
3341 vm_push_u32(vm, vm->memory_len / wasm_page_size);
3342 break;
3343 case Op_mem_grow:
3344 {
3345 uint32_t page_count = vm_pop_u32(vm);
3346 uint32_t old_page_count = vm->memory_len / wasm_page_size;
3347 uint32_t new_len = vm->memory_len + page_count * wasm_page_size;
3348 if (new_len > max_memory) {
3349 vm_push_i32(vm, -1);
3350 } else {
3351 vm->memory_len = new_len;
3352 vm_push_u32(vm, old_page_count);
3353 }
3354 }
3355 break;
34233356
3424 case WasmOp_i32_clz:
3425 {
3426 uint32_t operand = vm_pop_u32(vm);
3427 uint32_t result = (operand == 0) ? 32 : __builtin_clz(operand);
3428 vm_push_u32(vm, result);
3429 }
3430 break;
3431 case WasmOp_i32_ctz:
3432 {
3433 uint32_t operand = vm_pop_u32(vm);
3434 uint32_t result = (operand == 0) ? 32 : __builtin_ctz(operand);
3435 vm_push_u32(vm, result);
3436 }
3437 break;
3438 case WasmOp_i32_popcnt:
3439 {
3440 uint32_t operand = vm_pop_u32(vm);
3441 uint32_t result = __builtin_popcount(operand);
3442 vm_push_u32(vm, result);
3443 }
3444 break;
3445 case WasmOp_i32_sub:
3446 {
3447 uint32_t rhs = vm_pop_u32(vm);
3448 uint32_t lhs = vm_pop_u32(vm);
3449 vm_push_u32(vm, lhs - rhs);
3450 }
3451 break;
3452 case WasmOp_i32_mul:
3453 {
3454 uint32_t rhs = vm_pop_u32(vm);
3455 uint32_t lhs = vm_pop_u32(vm);
3456 vm_push_u32(vm, lhs * rhs);
3457 }
3458 break;
3459 case WasmOp_i32_div_s:
3460 {
3461 int32_t rhs = vm_pop_i32(vm);
3462 int32_t lhs = vm_pop_i32(vm);
3463 vm_push_i32(vm, lhs / rhs);
3464 }
3465 break;
3466 case WasmOp_i32_div_u:
3467 {
3468 uint32_t rhs = vm_pop_u32(vm);
3469 uint32_t lhs = vm_pop_u32(vm);
3470 vm_push_u32(vm, lhs / rhs);
3471 }
3472 break;
3473 case WasmOp_i32_rem_s:
3474 {
3475 int32_t rhs = vm_pop_i32(vm);
3476 int32_t lhs = vm_pop_i32(vm);
3477 vm_push_i32(vm, lhs % rhs);
3478 }
3479 break;
3480 case WasmOp_i32_rem_u:
3481 {
3482 uint32_t rhs = vm_pop_u32(vm);
3483 uint32_t lhs = vm_pop_u32(vm);
3484 vm_push_u32(vm, lhs % rhs);
3485 }
3486 break;
3487 case WasmOp_i32_or:
3488 {
3489 uint32_t rhs = vm_pop_u32(vm);
3490 uint32_t lhs = vm_pop_u32(vm);
3491 vm_push_u32(vm, lhs | rhs);
3492 }
3493 break;
3494 case WasmOp_i32_xor:
3495 {
3496 uint32_t rhs = vm_pop_u32(vm);
3497 uint32_t lhs = vm_pop_u32(vm);
3498 vm_push_u32(vm, lhs ^ rhs);
3499 }
3500 break;
3501 case WasmOp_i32_shl:
3502 {
3503 uint32_t rhs = vm_pop_u32(vm);
3504 uint32_t lhs = vm_pop_u32(vm);
3505 vm_push_u32(vm, lhs << (rhs & 0x1f));
3506 }
3507 break;
3508 case WasmOp_i32_shr_s:
3509 {
3510 uint32_t rhs = vm_pop_u32(vm);
3511 int32_t lhs = vm_pop_i32(vm);
3512 vm_push_i32(vm, lhs >> (rhs & 0x1f));
3513 }
3514 break;
3515 case WasmOp_i32_shr_u:
3516 {
3517 uint32_t rhs = vm_pop_u32(vm);
3518 uint32_t lhs = vm_pop_u32(vm);
3519 vm_push_u32(vm, lhs >> (rhs & 0x1f));
3520 }
3521 break;
3522 case WasmOp_i32_rotl:
3523 {
3524 uint32_t rhs = vm_pop_u32(vm);
3525 uint32_t lhs = vm_pop_u32(vm);
3526 vm_push_u32(vm, rotl32(lhs, rhs));
3527 }
3528 break;
3529 case WasmOp_i32_rotr:
3530 {
3531 uint32_t rhs = vm_pop_u32(vm);
3532 uint32_t lhs = vm_pop_u32(vm);
3533 vm_push_u32(vm, rotr32(lhs, rhs ));
3534 }
3535 break;
3357 case Op_const_0_32:
3358 vm_push_i32(vm, 0);
3359 break;
3360 case Op_const_0_64:
3361 vm_push_i64(vm, 0);
3362 break;
3363 case Op_const_1_32:
3364 vm_push_i32(vm, 1);
3365 break;
3366 case Op_const_1_64:
3367 vm_push_i64(vm, 1);
3368 break;
3369 case Op_const_32:
3370 {
3371 uint32_t value = operands[pc->operand];
3372 pc->operand += 1;
3373 vm_push_i32(vm, value);
3374 }
3375 break;
3376 case Op_const_64:
3377 {
3378 uint64_t value = ((uint64_t)operands[pc->operand]) |
3379 (((uint64_t)operands[pc->operand + 1]) << 32);
3380 pc->operand += 2;
3381 vm_push_i64(vm, value);
3382 }
3383 break;
3384 case Op_const_umax_32:
3385 vm_push_i32(vm, -1);
3386 break;
3387 case Op_const_umax_64:
3388 vm_push_i64(vm, -1);
3389 break;
35363390
3537 case WasmOp_i64_clz:
3538 {
3539 uint64_t operand = vm_pop_u64(vm);
3540 uint64_t result = (operand == 0) ? 64 : __builtin_clzll(operand);
3541 vm_push_u64(vm, result);
3542 }
3543 break;
3544 case WasmOp_i64_ctz:
3545 {
3546 uint64_t operand = vm_pop_u64(vm);
3547 uint64_t result = (operand == 0) ? 64 : __builtin_ctzll(operand);
3548 vm_push_u64(vm, result);
3549 }
3550 break;
3551 case WasmOp_i64_popcnt:
3552 {
3553 uint64_t operand = vm_pop_u64(vm);
3554 uint64_t result = __builtin_popcountll(operand);
3555 vm_push_u64(vm, result);
3556 }
3557 break;
3558 case WasmOp_i64_add:
3559 {
3560 uint64_t rhs = vm_pop_u64(vm);
3561 uint64_t lhs = vm_pop_u64(vm);
3562 vm_push_u64(vm, lhs + rhs);
3563 }
3564 break;
3565 case WasmOp_i64_sub:
3566 {
3567 uint64_t rhs = vm_pop_u64(vm);
3568 uint64_t lhs = vm_pop_u64(vm);
3569 vm_push_u64(vm, lhs - rhs);
3570 }
3571 break;
3572 case WasmOp_i64_mul:
3573 {
3574 uint64_t rhs = vm_pop_u64(vm);
3575 uint64_t lhs = vm_pop_u64(vm);
3576 vm_push_u64(vm, lhs * rhs);
3577 }
3578 break;
3579 case WasmOp_i64_div_s:
3580 {
3581 int64_t rhs = vm_pop_i64(vm);
3582 int64_t lhs = vm_pop_i64(vm);
3583 vm_push_i64(vm, lhs / rhs);
3584 }
3585 break;
3586 case WasmOp_i64_div_u:
3587 {
3588 uint64_t rhs = vm_pop_u64(vm);
3589 uint64_t lhs = vm_pop_u64(vm);
3590 vm_push_u64(vm, lhs / rhs);
3591 }
3592 break;
3593 case WasmOp_i64_rem_s:
3594 {
3595 int64_t rhs = vm_pop_i64(vm);
3596 int64_t lhs = vm_pop_i64(vm);
3597 vm_push_i64(vm, lhs % rhs);
3598 }
3599 break;
3600 case WasmOp_i64_rem_u:
3601 {
3602 uint64_t rhs = vm_pop_u64(vm);
3603 uint64_t lhs = vm_pop_u64(vm);
3604 vm_push_u64(vm, lhs % rhs);
3605 }
3606 break;
3607 case WasmOp_i64_and:
3608 {
3609 uint64_t rhs = vm_pop_u64(vm);
3610 uint64_t lhs = vm_pop_u64(vm);
3611 vm_push_u64(vm, lhs & rhs);
3612 }
3613 break;
3614 case WasmOp_i64_or:
3615 {
3616 uint64_t rhs = vm_pop_u64(vm);
3617 uint64_t lhs = vm_pop_u64(vm);
3618 vm_push_u64(vm, lhs | rhs);
3619 }
3620 break;
3621 case WasmOp_i64_xor:
3622 {
3623 uint64_t rhs = vm_pop_u64(vm);
3624 uint64_t lhs = vm_pop_u64(vm);
3625 vm_push_u64(vm, lhs ^ rhs);
3626 }
3627 break;
3628 case WasmOp_i64_shl:
3629 {
3630 uint64_t rhs = vm_pop_u64(vm);
3631 uint64_t lhs = vm_pop_u64(vm);
3632 vm_push_u64(vm, lhs << (rhs & 0x3f));
3633 }
3634 break;
3635 case WasmOp_i64_shr_s:
3636 {
3637 uint64_t rhs = vm_pop_u64(vm);
3638 int64_t lhs = vm_pop_i64(vm);
3639 vm_push_i64(vm, lhs >> (rhs & 0x3f));
3640 }
3641 break;
3642 case WasmOp_i64_shr_u:
3643 {
3644 uint64_t rhs = vm_pop_u64(vm);
3645 uint64_t lhs = vm_pop_u64(vm);
3646 vm_push_u64(vm, lhs >> (rhs & 0x3f));
3647 }
3648 break;
3649 case WasmOp_i64_rotl:
3650 {
3651 uint64_t rhs = vm_pop_u64(vm);
3652 uint64_t lhs = vm_pop_u64(vm);
3653 vm_push_u64(vm, rotl64(lhs, rhs));
3654 }
3655 break;
3656 case WasmOp_i64_rotr:
3657 {
3658 uint64_t rhs = vm_pop_u64(vm);
3659 uint64_t lhs = vm_pop_u64(vm);
3660 vm_push_u64(vm, rotr64(lhs, rhs));
3661 }
3662 break;
3391 case Op_eqz_32:
3392 {
3393 uint32_t lhs = vm_pop_u32(vm);
3394 vm_push_u32(vm, lhs == 0);
3395 }
3396 break;
3397 case Op_eq_32:
3398 {
3399 uint32_t rhs = vm_pop_u32(vm);
3400 uint32_t lhs = vm_pop_u32(vm);
3401 vm_push_u32(vm, lhs == rhs);
3402 }
3403 break;
3404 case Op_ne_32:
3405 {
3406 uint32_t rhs = vm_pop_u32(vm);
3407 uint32_t lhs = vm_pop_u32(vm);
3408 vm_push_u32(vm, lhs != rhs);
3409 }
3410 break;
3411 case Op_slt_32:
3412 {
3413 int32_t rhs = vm_pop_i32(vm);
3414 int32_t lhs = vm_pop_i32(vm);
3415 vm_push_u32(vm, lhs < rhs);
3416 }
3417 break;
3418 case Op_ult_32:
3419 {
3420 uint32_t rhs = vm_pop_u32(vm);
3421 uint32_t lhs = vm_pop_u32(vm);
3422 vm_push_u32(vm, lhs < rhs);
3423 }
3424 break;
3425 case Op_sgt_32:
3426 {
3427 int32_t rhs = vm_pop_i32(vm);
3428 int32_t lhs = vm_pop_i32(vm);
3429 vm_push_u32(vm, lhs > rhs);
3430 }
3431 break;
3432 case Op_ugt_32:
3433 {
3434 uint32_t rhs = vm_pop_u32(vm);
3435 uint32_t lhs = vm_pop_u32(vm);
3436 vm_push_u32(vm, lhs > rhs);
3437 }
3438 break;
3439 case Op_sle_32:
3440 {
3441 int32_t rhs = vm_pop_i32(vm);
3442 int32_t lhs = vm_pop_i32(vm);
3443 vm_push_u32(vm, lhs <= rhs);
3444 }
3445 break;
3446 case Op_ule_32:
3447 {
3448 uint32_t rhs = vm_pop_u32(vm);
3449 uint32_t lhs = vm_pop_u32(vm);
3450 vm_push_u32(vm, lhs <= rhs);
3451 }
3452 break;
3453 case Op_sge_32:
3454 {
3455 int32_t rhs = vm_pop_i32(vm);
3456 int32_t lhs = vm_pop_i32(vm);
3457 vm_push_u32(vm, lhs >= rhs);
3458 }
3459 break;
3460 case Op_uge_32:
3461 {
3462 uint32_t rhs = vm_pop_u32(vm);
3463 uint32_t lhs = vm_pop_u32(vm);
3464 vm_push_u32(vm, lhs >= rhs);
3465 }
3466 break;
36633467
3664 case WasmOp_f32_abs:
3665 {
3666 vm_push_f32(vm, fabsf(vm_pop_f32(vm)));
3667 }
3668 break;
3669 case WasmOp_f32_neg:
3670 {
3671 vm_push_f32(vm, -vm_pop_f32(vm));
3672 }
3673 break;
3674 case WasmOp_f32_ceil:
3675 {
3676 vm_push_f32(vm, ceilf(vm_pop_f32(vm)));
3677 }
3678 break;
3679 case WasmOp_f32_floor:
3680 {
3681 vm_push_f32(vm, floorf(vm_pop_f32(vm)));
3682 }
3683 break;
3684 case WasmOp_f32_trunc:
3685 {
3686 vm_push_f32(vm, truncf(vm_pop_f32(vm)));
3687 }
3688 break;
3689 case WasmOp_f32_nearest:
3690 {
3691 vm_push_f32(vm, roundf(vm_pop_f32(vm)));
3692 }
3693 break;
3694 case WasmOp_f32_sqrt:
3695 {
3696 vm_push_f32(vm, sqrtf(vm_pop_f32(vm)));
3697 }
3698 break;
3699 case WasmOp_f32_add:
3700 {
3701 float rhs = vm_pop_f32(vm);
3702 float lhs = vm_pop_f32(vm);
3703 vm_push_f32(vm, lhs + rhs);
3704 }
3705 break;
3706 case WasmOp_f32_sub:
3707 {
3708 float rhs = vm_pop_f32(vm);
3709 float lhs = vm_pop_f32(vm);
3710 vm_push_f32(vm, lhs - rhs);
3711 }
3712 break;
3713 case WasmOp_f32_mul:
3714 {
3715 float rhs = vm_pop_f32(vm);
3716 float lhs = vm_pop_f32(vm);
3717 vm_push_f32(vm, lhs * rhs);
3718 }
3719 break;
3720 case WasmOp_f32_div:
3721 {
3722 float rhs = vm_pop_f32(vm);
3723 float lhs = vm_pop_f32(vm);
3724 vm_push_f32(vm, lhs / rhs);
3725 }
3726 break;
3727 case WasmOp_f32_min:
3728 {
3729 float rhs = vm_pop_f32(vm);
3730 float lhs = vm_pop_f32(vm);
3731 vm_push_f32(vm, (lhs < rhs) ? lhs : rhs);
3732 }
3733 break;
3734 case WasmOp_f32_max:
3735 {
3736 float rhs = vm_pop_f32(vm);
3737 float lhs = vm_pop_f32(vm);
3738 vm_push_f32(vm, (lhs > rhs) ? lhs : rhs);
3739 }
3740 break;
3741 case WasmOp_f32_copysign:
3742 {
3743 float rhs = vm_pop_f32(vm);
3744 float lhs = vm_pop_f32(vm);
3745 vm_push_f32(vm, copysignf(lhs, rhs));
3746 }
3747 break;
3748 case WasmOp_f64_abs:
3749 {
3750 vm_push_f64(vm, fabs(vm_pop_f64(vm)));
3751 }
3752 break;
3753 case WasmOp_f64_neg:
3754 {
3755 vm_push_f64(vm, -vm_pop_f64(vm));
3756 }
3757 break;
3758 case WasmOp_f64_ceil:
3759 {
3760 vm_push_f64(vm, ceil(vm_pop_f64(vm)));
3761 }
3762 break;
3763 case WasmOp_f64_floor:
3764 {
3765 vm_push_f64(vm, floor(vm_pop_f64(vm)));
3766 }
3767 break;
3768 case WasmOp_f64_trunc:
3769 {
3770 vm_push_f64(vm, trunc(vm_pop_f64(vm)));
3771 }
3772 break;
3773 case WasmOp_f64_nearest:
3774 {
3775 vm_push_f64(vm, round(vm_pop_f64(vm)));
3776 }
3777 break;
3778 case WasmOp_f64_sqrt:
3779 {
3780 vm_push_f64(vm, sqrt(vm_pop_f64(vm)));
3781 }
3782 break;
3783 case WasmOp_f64_add:
3784 {
3785 double rhs = vm_pop_f64(vm);
3786 double lhs = vm_pop_f64(vm);
3787 vm_push_f64(vm, lhs + rhs);
3788 }
3789 break;
3790 case WasmOp_f64_sub:
3791 {
3792 double rhs = vm_pop_f64(vm);
3793 double lhs = vm_pop_f64(vm);
3794 vm_push_f64(vm, lhs - rhs);
3795 }
3796 break;
3797 case WasmOp_f64_mul:
3798 {
3799 double rhs = vm_pop_f64(vm);
3800 double lhs = vm_pop_f64(vm);
3801 vm_push_f64(vm, lhs * rhs);
3802 }
3803 break;
3804 case WasmOp_f64_div:
3805 {
3806 double rhs = vm_pop_f64(vm);
3807 double lhs = vm_pop_f64(vm);
3808 vm_push_f64(vm, lhs / rhs);
3809 }
3810 break;
3811 case WasmOp_f64_min:
3812 {
3813 double rhs = vm_pop_f64(vm);
3814 double lhs = vm_pop_f64(vm);
3815 vm_push_f64(vm, (lhs < rhs) ? lhs : rhs);
3816 }
3817 break;
3818 case WasmOp_f64_max:
3819 {
3820 double rhs = vm_pop_f64(vm);
3821 double lhs = vm_pop_f64(vm);
3822 vm_push_f64(vm, (lhs > rhs) ? lhs : rhs);
3823 }
3824 break;
3825 case WasmOp_f64_copysign:
3826 {
3827 double rhs = vm_pop_f64(vm);
3828 double lhs = vm_pop_f64(vm);
3829 vm_push_f64(vm, copysign(lhs, rhs));
3830 }
3831 break;
3468 case Op_eqz_64:
3469 {
3470 uint64_t lhs = vm_pop_u64(vm);
3471 vm_push_u32(vm, lhs == 0);
3472 }
3473 break;
3474 case Op_eq_64:
3475 {
3476 uint64_t rhs = vm_pop_u64(vm);
3477 uint64_t lhs = vm_pop_u64(vm);
3478 vm_push_u32(vm, lhs == rhs);
3479 }
3480 break;
3481 case Op_ne_64:
3482 {
3483 uint64_t rhs = vm_pop_u64(vm);
3484 uint64_t lhs = vm_pop_u64(vm);
3485 vm_push_u32(vm, lhs != rhs);
3486 }
3487 break;
3488 case Op_slt_64:
3489 {
3490 int64_t rhs = vm_pop_i64(vm);
3491 int64_t lhs = vm_pop_i64(vm);
3492 vm_push_u32(vm, lhs < rhs);
3493 }
3494 break;
3495 case Op_ult_64:
3496 {
3497 uint64_t rhs = vm_pop_u64(vm);
3498 uint64_t lhs = vm_pop_u64(vm);
3499 vm_push_u32(vm, lhs < rhs);
3500 }
3501 break;
3502 case Op_sgt_64:
3503 {
3504 int64_t rhs = vm_pop_i64(vm);
3505 int64_t lhs = vm_pop_i64(vm);
3506 vm_push_u32(vm, lhs > rhs);
3507 }
3508 break;
3509 case Op_ugt_64:
3510 {
3511 uint64_t rhs = vm_pop_u64(vm);
3512 uint64_t lhs = vm_pop_u64(vm);
3513 vm_push_u32(vm, lhs > rhs);
3514 }
3515 break;
3516 case Op_sle_64:
3517 {
3518 int64_t rhs = vm_pop_i64(vm);
3519 int64_t lhs = vm_pop_i64(vm);
3520 vm_push_u32(vm, lhs <= rhs);
3521 }
3522 break;
3523 case Op_ule_64:
3524 {
3525 uint64_t rhs = vm_pop_u64(vm);
3526 uint64_t lhs = vm_pop_u64(vm);
3527 vm_push_u32(vm, lhs <= rhs);
3528 }
3529 break;
3530 case Op_sge_64:
3531 {
3532 int64_t rhs = vm_pop_i64(vm);
3533 int64_t lhs = vm_pop_i64(vm);
3534 vm_push_u32(vm, lhs >= rhs);
3535 }
3536 break;
3537 case Op_uge_64:
3538 {
3539 uint64_t rhs = vm_pop_u64(vm);
3540 uint64_t lhs = vm_pop_u64(vm);
3541 vm_push_u32(vm, lhs >= rhs);
3542 }
3543 break;
38323544
3833 case WasmOp_i32_wrap_i64:
3834 {
3835 uint64_t operand = vm_pop_u64(vm);
3836 vm_push_u32(vm, operand);
3837 }
3838 break;
3839 case WasmOp_i32_trunc_f32_s:
3840 {
3841 float operand = vm_pop_f32(vm);
3842 vm_push_i32(vm, truncf(operand));
3843 }
3844 break;
3845 case WasmOp_i32_trunc_f32_u:
3846 {
3847 float operand = vm_pop_f32(vm);
3848 vm_push_u32(vm, truncf(operand));
3849 }
3850 break;
3851 case WasmOp_i32_trunc_f64_s:
3852 {
3853 double operand = vm_pop_f64(vm);
3854 vm_push_i32(vm, trunc(operand));
3855 }
3856 break;
3857 case WasmOp_i32_trunc_f64_u:
3858 {
3859 double operand = vm_pop_f64(vm);
3860 vm_push_u32(vm, trunc(operand));
3861 }
3862 break;
3863 case WasmOp_i64_extend_i32_s:
3864 {
3865 int32_t operand = vm_pop_i32(vm);
3866 vm_push_i64(vm, operand);
3867 }
3868 break;
3869 case WasmOp_i64_extend_i32_u:
3870 {
3871 uint64_t operand = vm_pop_u64(vm);
3872 vm_push_u64(vm, operand);
3873 }
3874 break;
3875 case WasmOp_i64_trunc_f32_s:
3876 {
3877 float operand = vm_pop_f32(vm);
3878 vm_push_i64(vm, truncf(operand));
3879 }
3880 break;
3881 case WasmOp_i64_trunc_f32_u:
3882 {
3883 float operand = vm_pop_f32(vm);
3884 vm_push_u64(vm, truncf(operand));
3885 }
3886 break;
3887 case WasmOp_i64_trunc_f64_s:
3888 {
3889 double operand = vm_pop_f64(vm);
3890 vm_push_i64(vm, trunc(operand));
3891 }
3892 break;
3893 case WasmOp_i64_trunc_f64_u:
3894 {
3895 double operand = vm_pop_f64(vm);
3896 vm_push_u64(vm, trunc(operand));
3897 }
3898 break;
3899 case WasmOp_f32_convert_i32_s:
3900 {
3901 vm_push_f32(vm, vm_pop_i32(vm));
3902 }
3903 break;
3904 case WasmOp_f32_convert_i32_u:
3905 {
3906 vm_push_f32(vm, vm_pop_u32(vm));
3907 }
3908 break;
3909 case WasmOp_f32_convert_i64_s:
3910 {
3911 vm_push_f32(vm, vm_pop_i64(vm));
3912 }
3913 break;
3914 case WasmOp_f32_convert_i64_u:
3915 {
3916 vm_push_f32(vm, vm_pop_u64(vm));
3917 }
3918 break;
3919 case WasmOp_f32_demote_f64:
3920 {
3921 vm_push_f32(vm, vm_pop_f64(vm));
3922 }
3923 break;
3924 case WasmOp_f64_convert_i32_s:
3925 {
3926 vm_push_f64(vm, vm_pop_i32(vm));
3927 }
3928 break;
3929 case WasmOp_f64_convert_i32_u:
3930 {
3931 vm_push_f64(vm, vm_pop_u32(vm));
3932 }
3933 break;
3934 case WasmOp_f64_convert_i64_s:
3935 {
3936 vm_push_f64(vm, vm_pop_i64(vm));
3937 }
3938 break;
3939 case WasmOp_f64_convert_i64_u:
3940 {
3941 vm_push_f64(vm, vm_pop_u64(vm));
3942 }
3943 break;
3944 case WasmOp_f64_promote_f32:
3945 {
3946 vm_push_f64(vm, vm_pop_f32(vm));
3947 }
3948 break;
3545 case Op_feq_32:
3546 {
3547 float rhs = vm_pop_f32(vm);
3548 float lhs = vm_pop_f32(vm);
3549 vm_push_u32(vm, lhs == rhs);
3550 }
3551 break;
3552 case Op_fne_32:
3553 {
3554 float rhs = vm_pop_f32(vm);
3555 float lhs = vm_pop_f32(vm);
3556 vm_push_u32(vm, lhs != rhs);
3557 }
3558 break;
3559 case Op_flt_32:
3560 {
3561 float rhs = vm_pop_f32(vm);
3562 float lhs = vm_pop_f32(vm);
3563 vm_push_u32(vm, lhs < rhs);
3564 }
3565 break;
3566 case Op_fgt_32:
3567 {
3568 float rhs = vm_pop_f32(vm);
3569 float lhs = vm_pop_f32(vm);
3570 vm_push_u32(vm, lhs > rhs);
3571 }
3572 break;
3573 case Op_fle_32:
3574 {
3575 float rhs = vm_pop_f32(vm);
3576 float lhs = vm_pop_f32(vm);
3577 vm_push_u32(vm, lhs <= rhs);
3578 }
3579 break;
3580 case Op_fge_32:
3581 {
3582 float rhs = vm_pop_f32(vm);
3583 float lhs = vm_pop_f32(vm);
3584 vm_push_u32(vm, lhs >= rhs);
3585 }
3586 break;
39493587
3950 case WasmOp_i32_extend8_s:
3951 {
3952 int8_t operand = vm_pop_i32(vm);
3953 vm_push_i32(vm, operand);
3954 }
3955 break;
3956 case WasmOp_i32_extend16_s:
3957 {
3958 int16_t operand = vm_pop_i32(vm);
3959 vm_push_i32(vm, operand);
3960 }
3961 break;
3962 case WasmOp_i64_extend8_s:
3963 {
3964 int8_t operand = vm_pop_i64(vm);
3965 vm_push_i64(vm, operand);
3966 }
3967 break;
3968 case WasmOp_i64_extend16_s:
3969 {
3970 int16_t operand = vm_pop_i64(vm);
3971 vm_push_i64(vm, operand);
3972 }
3973 break;
3974 case WasmOp_i64_extend32_s:
3975 {
3976 int32_t operand = vm_pop_i64(vm);
3977 vm_push_i64(vm, operand);
3978 }
3979 break;
3588 case Op_feq_64:
3589 {
3590 double rhs = vm_pop_f64(vm);
3591 double lhs = vm_pop_f64(vm);
3592 vm_push_u32(vm, lhs == rhs);
3593 }
3594 break;
3595 case Op_fne_64:
3596 {
3597 double rhs = vm_pop_f64(vm);
3598 double lhs = vm_pop_f64(vm);
3599 vm_push_u32(vm, lhs != rhs);
3600 }
3601 break;
3602 case Op_flt_64:
3603 {
3604 double rhs = vm_pop_f64(vm);
3605 double lhs = vm_pop_f64(vm);
3606 vm_push_u32(vm, lhs <= rhs);
3607 }
3608 break;
3609 case Op_fgt_64:
3610 {
3611 double rhs = vm_pop_f64(vm);
3612 double lhs = vm_pop_f64(vm);
3613 vm_push_u32(vm, lhs > rhs);
3614 }
3615 break;
3616 case Op_fle_64:
3617 {
3618 double rhs = vm_pop_f64(vm);
3619 double lhs = vm_pop_f64(vm);
3620 vm_push_u32(vm, lhs <= rhs);
3621 }
3622 break;
3623 case Op_fge_64:
3624 {
3625 double rhs = vm_pop_f64(vm);
3626 double lhs = vm_pop_f64(vm);
3627 vm_push_u32(vm, lhs >= rhs);
3628 }
3629 break;
39803630
3981 default:
3982 panic("unreachable");
3983 }
3631 case Op_clz_32:
3632 {
3633 uint32_t operand = vm_pop_u32(vm);
3634 uint32_t result = (operand == 0) ? 32 : __builtin_clz(operand);
3635 vm_push_u32(vm, result);
3636 }
3637 break;
3638 case Op_ctz_32:
3639 {
3640 uint32_t operand = vm_pop_u32(vm);
3641 uint32_t result = (operand == 0) ? 32 : __builtin_ctz(operand);
3642 vm_push_u32(vm, result);
3643 }
3644 break;
3645 case Op_popcnt_32:
3646 {
3647 uint32_t operand = vm_pop_u32(vm);
3648 uint32_t result = __builtin_popcount(operand);
3649 vm_push_u32(vm, result);
3650 }
3651 break;
3652 case Op_add_32:
3653 {
3654 uint32_t rhs = vm_pop_u32(vm);
3655 uint32_t lhs = vm_pop_u32(vm);
3656 vm_push_u32(vm, lhs + rhs);
3657 }
3658 break;
3659 case Op_sub_32:
3660 {
3661 uint32_t rhs = vm_pop_u32(vm);
3662 uint32_t lhs = vm_pop_u32(vm);
3663 vm_push_u32(vm, lhs - rhs);
3664 }
3665 break;
3666 case Op_mul_32:
3667 {
3668 uint32_t rhs = vm_pop_u32(vm);
3669 uint32_t lhs = vm_pop_u32(vm);
3670 vm_push_u32(vm, lhs * rhs);
3671 }
3672 break;
3673 case Op_sdiv_32:
3674 {
3675 int32_t rhs = vm_pop_i32(vm);
3676 int32_t lhs = vm_pop_i32(vm);
3677 vm_push_i32(vm, lhs / rhs);
3678 }
3679 break;
3680 case Op_udiv_32:
3681 {
3682 uint32_t rhs = vm_pop_u32(vm);
3683 uint32_t lhs = vm_pop_u32(vm);
3684 vm_push_u32(vm, lhs / rhs);
3685 }
3686 break;
3687 case Op_srem_32:
3688 {
3689 int32_t rhs = vm_pop_i32(vm);
3690 int32_t lhs = vm_pop_i32(vm);
3691 vm_push_i32(vm, lhs % rhs);
3692 }
3693 break;
3694 case Op_urem_32:
3695 {
3696 uint32_t rhs = vm_pop_u32(vm);
3697 uint32_t lhs = vm_pop_u32(vm);
3698 vm_push_u32(vm, lhs % rhs);
3699 }
3700 break;
3701 case Op_and_32:
3702 {
3703 uint32_t rhs = vm_pop_u32(vm);
3704 uint32_t lhs = vm_pop_u32(vm);
3705 vm_push_u32(vm, lhs & rhs);
3706 }
3707 break;
3708 case Op_or_32:
3709 {
3710 uint32_t rhs = vm_pop_u32(vm);
3711 uint32_t lhs = vm_pop_u32(vm);
3712 vm_push_u32(vm, lhs | rhs);
3713 }
3714 break;
3715 case Op_xor_32:
3716 {
3717 uint32_t rhs = vm_pop_u32(vm);
3718 uint32_t lhs = vm_pop_u32(vm);
3719 vm_push_u32(vm, lhs ^ rhs);
3720 }
3721 break;
3722 case Op_shl_32:
3723 {
3724 uint32_t rhs = vm_pop_u32(vm);
3725 uint32_t lhs = vm_pop_u32(vm);
3726 vm_push_u32(vm, lhs << (rhs & 0x1f));
3727 }
3728 break;
3729 case Op_ashr_32:
3730 {
3731 uint32_t rhs = vm_pop_u32(vm);
3732 int32_t lhs = vm_pop_i32(vm);
3733 vm_push_i32(vm, lhs >> (rhs & 0x1f));
3734 }
3735 break;
3736 case Op_lshr_32:
3737 {
3738 uint32_t rhs = vm_pop_u32(vm);
3739 uint32_t lhs = vm_pop_u32(vm);
3740 vm_push_u32(vm, lhs >> (rhs & 0x1f));
3741 }
3742 break;
3743 case Op_rol_32:
3744 {
3745 uint32_t rhs = vm_pop_u32(vm);
3746 uint32_t lhs = vm_pop_u32(vm);
3747 vm_push_u32(vm, rotl32(lhs, rhs));
3748 }
3749 break;
3750 case Op_ror_32:
3751 {
3752 uint32_t rhs = vm_pop_u32(vm);
3753 uint32_t lhs = vm_pop_u32(vm);
3754 vm_push_u32(vm, rotr32(lhs, rhs));
39843755 }
39853756 break;
39863757
3987 case Op_wasm_prefixed:
3758 case Op_clz_64:
39883759 {
3989 enum WasmPrefixedOp wasm_prefixed_op = opcodes[pc->opcode];
3990 pc->opcode += 1;
3991 switch (wasm_prefixed_op) {
3992 case WasmPrefixedOp_i32_trunc_sat_f32_s:
3993 panic("unreachable");
3994 case WasmPrefixedOp_i32_trunc_sat_f32_u:
3995 panic("unreachable");
3996 case WasmPrefixedOp_i32_trunc_sat_f64_s:
3997 panic("unreachable");
3998 case WasmPrefixedOp_i32_trunc_sat_f64_u:
3999 panic("unreachable");
4000 case WasmPrefixedOp_i64_trunc_sat_f32_s:
4001 panic("unreachable");
4002 case WasmPrefixedOp_i64_trunc_sat_f32_u:
4003 panic("unreachable");
4004 case WasmPrefixedOp_i64_trunc_sat_f64_s:
4005 panic("unreachable");
4006 case WasmPrefixedOp_i64_trunc_sat_f64_u:
4007 panic("unreachable");
4008 case WasmPrefixedOp_memory_init:
4009 panic("unreachable");
4010 case WasmPrefixedOp_data_drop:
4011 panic("unreachable");
4012
4013 case WasmPrefixedOp_memory_copy:
4014 {
4015 uint32_t n = vm_pop_u32(vm);
4016 uint32_t src = vm_pop_u32(vm);
4017 uint32_t dest = vm_pop_u32(vm);
4018 assert(dest + n <= vm->memory_len);
4019 assert(src + n <= vm->memory_len);
4020 assert(src + n <= dest || dest + n <= src); // overlapping
4021 memcpy(vm->memory + dest, vm->memory + src, n);
4022 }
4023 break;
3760 uint64_t operand = vm_pop_u64(vm);
3761 uint64_t result = (operand == 0) ? 64 : __builtin_clzll(operand);
3762 vm_push_u64(vm, result);
3763 }
3764 break;
3765 case Op_ctz_64:
3766 {
3767 uint64_t operand = vm_pop_u64(vm);
3768 uint64_t result = (operand == 0) ? 64 : __builtin_ctzll(operand);
3769 vm_push_u64(vm, result);
3770 }
3771 break;
3772 case Op_popcnt_64:
3773 {
3774 uint64_t operand = vm_pop_u64(vm);
3775 uint64_t result = __builtin_popcountll(operand);
3776 vm_push_u64(vm, result);
3777 }
3778 break;
3779 case Op_add_64:
3780 {
3781 uint64_t rhs = vm_pop_u64(vm);
3782 uint64_t lhs = vm_pop_u64(vm);
3783 vm_push_u64(vm, lhs + rhs);
3784 }
3785 break;
3786 case Op_sub_64:
3787 {
3788 uint64_t rhs = vm_pop_u64(vm);
3789 uint64_t lhs = vm_pop_u64(vm);
3790 vm_push_u64(vm, lhs - rhs);
3791 }
3792 break;
3793 case Op_mul_64:
3794 {
3795 uint64_t rhs = vm_pop_u64(vm);
3796 uint64_t lhs = vm_pop_u64(vm);
3797 vm_push_u64(vm, lhs * rhs);
3798 }
3799 break;
3800 case Op_sdiv_64:
3801 {
3802 int64_t rhs = vm_pop_i64(vm);
3803 int64_t lhs = vm_pop_i64(vm);
3804 vm_push_i64(vm, lhs / rhs);
3805 }
3806 break;
3807 case Op_udiv_64:
3808 {
3809 uint64_t rhs = vm_pop_u64(vm);
3810 uint64_t lhs = vm_pop_u64(vm);
3811 vm_push_u64(vm, lhs / rhs);
3812 }
3813 break;
3814 case Op_srem_64:
3815 {
3816 int64_t rhs = vm_pop_i64(vm);
3817 int64_t lhs = vm_pop_i64(vm);
3818 vm_push_i64(vm, lhs % rhs);
3819 }
3820 break;
3821 case Op_urem_64:
3822 {
3823 uint64_t rhs = vm_pop_u64(vm);
3824 uint64_t lhs = vm_pop_u64(vm);
3825 vm_push_u64(vm, lhs % rhs);
3826 }
3827 break;
3828 case Op_and_64:
3829 {
3830 uint64_t rhs = vm_pop_u64(vm);
3831 uint64_t lhs = vm_pop_u64(vm);
3832 vm_push_u64(vm, lhs & rhs);
3833 }
3834 break;
3835 case Op_or_64:
3836 {
3837 uint64_t rhs = vm_pop_u64(vm);
3838 uint64_t lhs = vm_pop_u64(vm);
3839 vm_push_u64(vm, lhs | rhs);
3840 }
3841 break;
3842 case Op_xor_64:
3843 {
3844 uint64_t rhs = vm_pop_u64(vm);
3845 uint64_t lhs = vm_pop_u64(vm);
3846 vm_push_u64(vm, lhs ^ rhs);
3847 }
3848 break;
3849 case Op_shl_64:
3850 {
3851 uint64_t rhs = vm_pop_u64(vm);
3852 uint64_t lhs = vm_pop_u64(vm);
3853 vm_push_u64(vm, lhs << (rhs & 0x3f));
3854 }
3855 break;
3856 case Op_ashr_64:
3857 {
3858 uint64_t rhs = vm_pop_u64(vm);
3859 int64_t lhs = vm_pop_i64(vm);
3860 vm_push_i64(vm, lhs >> (rhs & 0x3f));
3861 }
3862 break;
3863 case Op_lshr_64:
3864 {
3865 uint64_t rhs = vm_pop_u64(vm);
3866 uint64_t lhs = vm_pop_u64(vm);
3867 vm_push_u64(vm, lhs >> (rhs & 0x3f));
3868 }
3869 break;
3870 case Op_rol_64:
3871 {
3872 uint64_t rhs = vm_pop_u64(vm);
3873 uint64_t lhs = vm_pop_u64(vm);
3874 vm_push_u64(vm, rotl64(lhs, rhs));
3875 }
3876 break;
3877 case Op_ror_64:
3878 {
3879 uint64_t rhs = vm_pop_u64(vm);
3880 uint64_t lhs = vm_pop_u64(vm);
3881 vm_push_u64(vm, rotr64(lhs, rhs));
3882 }
3883 break;
40243884
4025 case WasmPrefixedOp_memory_fill:
4026 {
4027 uint32_t n = vm_pop_u32(vm);
4028 uint8_t value = vm_pop_u32(vm);
4029 uint32_t dest = vm_pop_u32(vm);
4030 assert(dest + n <= vm->memory_len);
4031 memset(vm->memory + dest, value, n);
4032 }
4033 break;
3885 case Op_fabs_32:
3886 vm_push_f32(vm, fabsf(vm_pop_f32(vm)));
3887 break;
3888 case Op_fneg_32:
3889 vm_push_f32(vm, -vm_pop_f32(vm));
3890 break;
3891 case Op_ceil_32:
3892 vm_push_f32(vm, ceilf(vm_pop_f32(vm)));
3893 break;
3894 case Op_floor_32:
3895 vm_push_f32(vm, floorf(vm_pop_f32(vm)));
3896 break;
3897 case Op_trunc_32:
3898 vm_push_f32(vm, truncf(vm_pop_f32(vm)));
3899 break;
3900 case Op_nearest_32:
3901 vm_push_f32(vm, roundf(vm_pop_f32(vm)));
3902 break;
3903 case Op_sqrt_32:
3904 vm_push_f32(vm, sqrtf(vm_pop_f32(vm)));
3905 break;
3906 case Op_fadd_32:
3907 {
3908 float rhs = vm_pop_f32(vm);
3909 float lhs = vm_pop_f32(vm);
3910 vm_push_f32(vm, lhs + rhs);
3911 }
3912 break;
3913 case Op_fsub_32:
3914 {
3915 float rhs = vm_pop_f32(vm);
3916 float lhs = vm_pop_f32(vm);
3917 vm_push_f32(vm, lhs - rhs);
3918 }
3919 break;
3920 case Op_fmul_32:
3921 {
3922 float rhs = vm_pop_f32(vm);
3923 float lhs = vm_pop_f32(vm);
3924 vm_push_f32(vm, lhs * rhs);
3925 }
3926 break;
3927 case Op_fdiv_32:
3928 {
3929 float rhs = vm_pop_f32(vm);
3930 float lhs = vm_pop_f32(vm);
3931 vm_push_f32(vm, lhs / rhs);
3932 }
3933 break;
3934 case Op_fmin_32:
3935 {
3936 float rhs = vm_pop_f32(vm);
3937 float lhs = vm_pop_f32(vm);
3938 vm_push_f32(vm, fminf(lhs, rhs));
3939 }
3940 break;
3941 case Op_fmax_32:
3942 {
3943 float rhs = vm_pop_f32(vm);
3944 float lhs = vm_pop_f32(vm);
3945 vm_push_f32(vm, fmaxf(lhs, rhs));
3946 }
3947 break;
3948 case Op_copysign_32:
3949 {
3950 float rhs = vm_pop_f32(vm);
3951 float lhs = vm_pop_f32(vm);
3952 vm_push_f32(vm, copysignf(lhs, rhs));
3953 }
3954 break;
40343955
4035 case WasmPrefixedOp_table_init: panic("unreachable");
4036 case WasmPrefixedOp_elem_drop: panic("unreachable");
4037 case WasmPrefixedOp_table_copy: panic("unreachable");
4038 case WasmPrefixedOp_table_grow: panic("unreachable");
4039 case WasmPrefixedOp_table_size: panic("unreachable");
4040 case WasmPrefixedOp_table_fill: panic("unreachable");
4041 default: panic("unreachable");
4042 }
3956 case Op_fabs_64:
3957 vm_push_f64(vm, fabs(vm_pop_f64(vm)));
3958 break;
3959 case Op_fneg_64:
3960 vm_push_f64(vm, -vm_pop_f64(vm));
3961 break;
3962 case Op_ceil_64:
3963 vm_push_f64(vm, ceil(vm_pop_f64(vm)));
3964 break;
3965 case Op_floor_64:
3966 vm_push_f64(vm, floor(vm_pop_f64(vm)));
3967 break;
3968 case Op_trunc_64:
3969 vm_push_f64(vm, trunc(vm_pop_f64(vm)));
3970 break;
3971 case Op_nearest_64:
3972 vm_push_f64(vm, round(vm_pop_f64(vm)));
3973 break;
3974 case Op_sqrt_64:
3975 vm_push_f64(vm, sqrt(vm_pop_f64(vm)));
3976 break;
3977 case Op_fadd_64:
3978 {
3979 double rhs = vm_pop_f64(vm);
3980 double lhs = vm_pop_f64(vm);
3981 vm_push_f64(vm, lhs + rhs);
3982 }
3983 break;
3984 case Op_fsub_64:
3985 {
3986 double rhs = vm_pop_f64(vm);
3987 double lhs = vm_pop_f64(vm);
3988 vm_push_f64(vm, lhs - rhs);
3989 }
3990 break;
3991 case Op_fmul_64:
3992 {
3993 double rhs = vm_pop_f64(vm);
3994 double lhs = vm_pop_f64(vm);
3995 vm_push_f64(vm, lhs * rhs);
3996 }
3997 break;
3998 case Op_fdiv_64:
3999 {
4000 double rhs = vm_pop_f64(vm);
4001 double lhs = vm_pop_f64(vm);
4002 vm_push_f64(vm, lhs / rhs);
4003 }
4004 break;
4005 case Op_fmin_64:
4006 {
4007 double rhs = vm_pop_f64(vm);
4008 double lhs = vm_pop_f64(vm);
4009 vm_push_f64(vm, fmin(lhs, rhs));
4010 }
4011 break;
4012 case Op_fmax_64:
4013 {
4014 double rhs = vm_pop_f64(vm);
4015 double lhs = vm_pop_f64(vm);
4016 vm_push_f64(vm, fmax(lhs, rhs));
4017 }
4018 break;
4019 case Op_copysign_64:
4020 {
4021 double rhs = vm_pop_f64(vm);
4022 double lhs = vm_pop_f64(vm);
4023 vm_push_f64(vm, copysign(lhs, rhs));
40434024 }
40444025 break;
40454026
4027 case Op_ftos_32_32: vm_push_f32(vm, (float)vm_pop_i32(vm)); break;
4028 case Op_ftou_32_32: vm_push_f32(vm, (float)vm_pop_u32(vm)); break;
4029 case Op_ftos_32_64: vm_push_f32(vm, (float)vm_pop_i64(vm)); break;
4030 case Op_ftou_32_64: vm_push_f32(vm, (float)vm_pop_u64(vm)); break;
4031 case Op_sext_64_32: vm_push_i64(vm, vm_pop_i32(vm)); break;
4032 case Op_ftos_64_32: vm_push_i64(vm, (int64_t)vm_pop_f32(vm)); break;
4033 case Op_ftou_64_32: vm_push_u64(vm, (uint64_t)vm_pop_f32(vm)); break;
4034 case Op_ftos_64_64: vm_push_i64(vm, (int64_t)vm_pop_f64(vm)); break;
4035 case Op_ftou_64_64: vm_push_u64(vm, (uint64_t)vm_pop_f64(vm)); break;
4036 case Op_stof_32_32: vm_push_f32(vm, (float)vm_pop_i32(vm)); break;
4037 case Op_utof_32_32: vm_push_f32(vm, (float)vm_pop_u32(vm)); break;
4038 case Op_stof_32_64: vm_push_f32(vm, (float)vm_pop_i64(vm)); break;
4039 case Op_utof_32_64: vm_push_f32(vm, (float)vm_pop_u64(vm)); break;
4040 case Op_ftof_32_64: vm_push_f32(vm, (float)vm_pop_f64(vm)); break;
4041 case Op_stof_64_32: vm_push_f64(vm, (double)vm_pop_i32(vm)); break;
4042 case Op_utof_64_32: vm_push_f64(vm, (double)vm_pop_u32(vm)); break;
4043 case Op_stof_64_64: vm_push_f64(vm, (double)vm_pop_i64(vm)); break;
4044 case Op_utof_64_64: vm_push_f64(vm, (double)vm_pop_u64(vm)); break;
4045 case Op_ftof_64_32: vm_push_f64(vm, (double)vm_pop_f32(vm)); break;
4046 case Op_sext8_32: vm_push_i32(vm, (int8_t)vm_pop_i32(vm)); break;
4047 case Op_sext16_32: vm_push_i32(vm, (int16_t)vm_pop_i32(vm)); break;
4048 case Op_sext8_64: vm_push_i64(vm, (int8_t)vm_pop_i64(vm)); break;
4049 case Op_sext16_64: vm_push_i64(vm, (int16_t)vm_pop_i64(vm)); break;
4050 case Op_sext32_64: vm_push_i64(vm, (int32_t)vm_pop_i64(vm)); break;
4051
4052 case Op_memcpy:
4053 {
4054 uint32_t n = vm_pop_u32(vm);
4055 uint32_t src = vm_pop_u32(vm);
4056 uint32_t dest = vm_pop_u32(vm);
4057 assert(dest + n <= vm->memory_len);
4058 assert(src + n <= vm->memory_len);
4059 assert(src + n <= dest || dest + n <= src); // overlapping
4060 memcpy(vm->memory + dest, vm->memory + src, n);
4061 }
4062 break;
4063 case Op_memset:
4064 {
4065 uint32_t n = vm_pop_u32(vm);
4066 uint8_t value = (uint8_t)vm_pop_u32(vm);
4067 uint32_t dest = vm_pop_u32(vm);
4068 assert(dest + n <= vm->memory_len);
4069 memset(vm->memory + dest, value, n);
4070 }
4071 break;
40464072 }
40474073 }
40484074}
......@@ -4064,11 +4090,12 @@ int main(int argc, char **argv) {
40644090
40654091 size_t cwd_path_len = common_prefix(zig_lib_dir_path, cmake_binary_dir_path);
40664092 const char *rel_cmake_bin_path = cmake_binary_dir_path + cwd_path_len;
4093
40674094 size_t rel_cmake_bin_path_len = strlen(rel_cmake_bin_path);
40684095
40694096 const char *new_argv[30];
40704097 char new_argv_buf[PATH_MAX + 1024];
4071 uint32_t new_argv_i = 0;
4098 uint32_t new_argv_i = 0;
40724099 uint32_t new_argv_buf_i = 0;
40734100
40744101 int cache_dir = -1;
......@@ -4102,7 +4129,7 @@ int main(int argc, char **argv) {
41024129 new_argv_i += 1;
41034130 argv_i += 1;
41044131
4105 for(; argv[argv_i]; argv_i += 1) {
4132 for (; argv[argv_i]; argv_i += 1) {
41064133 new_argv[new_argv_i] = argv[argv_i];
41074134 new_argv_i += 1;
41084135 }
......@@ -4380,6 +4407,7 @@ int main(int argc, char **argv) {
43804407 functions = arena_alloc(sizeof(struct Function) * functions_len);
43814408 for (size_t func_i = 0; func_i < functions_len; func_i += 1) {
43824409 struct Function *func = &functions[func_i];
4410 func->id = imports_len + func_i;
43834411 func->type_idx = read32_uleb128(mod_ptr, &i);
43844412 }
43854413 }
......@@ -4474,7 +4502,7 @@ int main(int argc, char **argv) {
44744502#ifndef NDEBUG
44754503 memset(&vm, 0xaa, sizeof(struct VirtualMachine)); // to match the zig version
44764504#endif
4477 vm.stack = arena_alloc(sizeof(uint64_t) * 10000000),
4505 vm.stack = arena_alloc(sizeof(uint32_t) * 10000000),
44784506 vm.mod_ptr = mod_ptr;
44794507 vm.opcodes = arena_alloc(2000000);
44804508 vm.operands = arena_alloc(sizeof(uint32_t) * 2000000);
......@@ -4496,42 +4524,43 @@ int main(int argc, char **argv) {
44964524 struct ProgramCounter pc;
44974525 pc.opcode = 0;
44984526 pc.operand = 0;
4527 struct StackInfo stack;
44994528 for (uint32_t func_i = 0; func_i < functions_len; func_i += 1) {
45004529 struct Function *func = &functions[func_i];
45014530 uint32_t size = read32_uleb128(mod_ptr, &code_i);
45024531 uint32_t code_begin = code_i;
45034532
4533 stack.top_index = 0;
4534 stack.top_offset = 0;
45044535 struct TypeInfo *type_info = &vm.types[func->type_idx];
4505 func->locals_count = 0;
4506 func->local_types = malloc(sizeof(uint32_t) * ((type_info->param_count + func->locals_count + 31) / 32));
4507 func->local_types[0] = type_info->param_types;
4536 for (uint32_t param_i = 0; param_i < type_info->param_count; param_i += 1)
4537 si_push(&stack, bs_isSet(&type_info->param_types, param_i));
4538 uint32_t params_size = stack.top_offset;
45084539
45094540 for (uint32_t local_sets_count = read32_uleb128(mod_ptr, &code_i);
45104541 local_sets_count > 0; local_sets_count -= 1)
45114542 {
4512 uint32_t set_count = read32_uleb128(mod_ptr, &code_i);
4513 int64_t local_type = read64_ileb128(mod_ptr, &code_i);
4514
4515 uint32_t i = type_info->param_count + func->locals_count;
4516 func->locals_count += set_count;
4517 if ((type_info->param_count + func->locals_count + 31) / 32 > (i + 31) / 32)
4518 func->local_types = realloc(func->local_types, sizeof(uint32_t) * ((type_info->param_count + func->locals_count + 31) / 32));
4519 for (; i < type_info->param_count + func->locals_count; i += 1)
4520 switch (local_type) {
4521 case -1: case -3: bs_unset(func->local_types, i); break;
4522 case -2: case -4: bs_set(func->local_types, i); break;
4523 default: panic("unexpected local type");
4524 }
4543 uint32_t local_set_count = read32_uleb128(mod_ptr, &code_i);
4544 enum StackType local_type;
4545 switch (read64_ileb128(mod_ptr, &code_i)) {
4546 case -1: case -3: local_type = ST_32; break;
4547 case -2: case -4: local_type = ST_64; break;
4548 default: panic("unexpected local type");
4549 }
4550 for (; local_set_count > 0; local_set_count -= 1)
4551 si_push(&stack, local_type);
45254552 }
4553 func->locals_size = stack.top_offset - params_size;
45264554
4527 //fprintf(stderr, "set up func %u with pc %u:%u\n", func->type_idx, pc.opcode, pc.operand);
45284555 func->entry_pc = pc;
4529 vm_decodeCode(&vm, func, &code_i, &pc);
4556 //fprintf(stderr, "decoding func id %u with pc %u:%u\n", func->id, pc.opcode, pc.operand);
4557 vm_decodeCode(&vm, type_info, &code_i, &pc, &stack);
45304558 if (code_i != code_begin + size) panic("bad code size");
45314559 }
4560 //fprintf(stderr, "%u opcodes\n%u operands\n", pc.opcode, pc.operand);
45324561 }
45334562
4534 vm_call(&vm, start_fn_idx);
4563 vm_call(&vm, &vm.functions[start_fn_idx - imports_len]);
45354564 vm_run(&vm);
45364565
45374566 return 0;