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) {...@@ -223,7 +223,7 @@ static struct ByteSlice read_file_alloc(const char *file_path) {
223223
224224
225struct Preopen {225struct Preopen {
226 int wasi_fd; 226 int wasi_fd;
227 int host_fd;227 int host_fd;
228 const char *name;228 const char *name;
229 size_t name_len;229 size_t name_len;
...@@ -259,10 +259,6 @@ static uint16_t read_u16_le(const char *ptr) {...@@ -259,10 +259,6 @@ static uint16_t read_u16_le(const char *ptr) {
259 (((uint64_t)u8_ptr[1]) << 0x08);259 (((uint64_t)u8_ptr[1]) << 0x08);
260}260}
261261
262static int16_t read_i16_le(const char *ptr) {
263 return read_u16_le(ptr);
264}
265
266static uint32_t read_u32_le(const char *ptr) {262static uint32_t read_u32_le(const char *ptr) {
267 const uint8_t *u8_ptr = (const uint8_t *)ptr;263 const uint8_t *u8_ptr = (const uint8_t *)ptr;
268 return264 return
...@@ -272,10 +268,6 @@ static uint32_t read_u32_le(const char *ptr) {...@@ -272,10 +268,6 @@ static uint32_t read_u32_le(const char *ptr) {
272 (((uint64_t)u8_ptr[3]) << 0x18);268 (((uint64_t)u8_ptr[3]) << 0x18);
273}269}
274270
275static uint32_t read_i32_le(const char *ptr) {
276 return read_u32_le(ptr);
277}
278
279static uint64_t read_u64_le(const char *ptr) {271static uint64_t read_u64_le(const char *ptr) {
280 const uint8_t *u8_ptr = (const uint8_t *)ptr;272 const uint8_t *u8_ptr = (const uint8_t *)ptr;
281 return273 return
...@@ -383,19 +375,21 @@ enum Op {...@@ -383,19 +375,21 @@ enum Op {
383 Op_br_void,375 Op_br_void,
384 Op_br_32,376 Op_br_32,
385 Op_br_64,377 Op_br_64,
386 Op_br_if_nez_void,378 Op_br_nez_void,
387 Op_br_if_nez_32,379 Op_br_nez_32,
388 Op_br_if_nez_64,380 Op_br_nez_64,
389 Op_br_if_eqz_void,381 Op_br_eqz_void,
390 Op_br_if_eqz_32,382 Op_br_eqz_32,
391 Op_br_if_eqz_64,383 Op_br_eqz_64,
392 Op_br_table_void,384 Op_br_table_void,
393 Op_br_table_32,385 Op_br_table_32,
394 Op_br_table_64,386 Op_br_table_64,
395 Op_return_void,387 Op_return_void,
396 Op_return_32,388 Op_return_32,
397 Op_return_64,389 Op_return_64,
398 Op_call,390 Op_call_import,
391 Op_call_func,
392 Op_call_indirect,
399 Op_drop_32,393 Op_drop_32,
400 Op_drop_64,394 Op_drop_64,
401 Op_select_32,395 Op_select_32,
...@@ -410,12 +404,160 @@ enum Op {...@@ -410,12 +404,160 @@ enum Op {
410 Op_global_get_32,404 Op_global_get_32,
411 Op_global_set_0_32,405 Op_global_set_0_32,
412 Op_global_set_32,406 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,
413 Op_const_32,429 Op_const_32,
414 Op_const_64,430 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,
415 Op_add_32,470 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,
416 Op_and_32,477 Op_and_32,
417 Op_wasm,478 Op_or_32,
418 Op_wasm_prefixed,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,
419};561};
420562
421enum WasmOp {563enum WasmOp {
...@@ -638,13 +780,11 @@ struct TypeInfo {...@@ -638,13 +780,11 @@ struct TypeInfo {
638};780};
639781
640struct Function {782struct Function {
783 uint32_t id;
641 // Index to start of code in opcodes/operands.784 // Index to start of code in opcodes/operands.
642 struct ProgramCounter entry_pc;785 struct ProgramCounter entry_pc;
643 uint32_t type_idx;786 uint32_t type_idx;
644 uint32_t locals_count;787 uint32_t locals_size;
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;
648};788};
649789
650enum ImpMod {790enum ImpMod {
...@@ -688,7 +828,7 @@ struct Import {...@@ -688,7 +828,7 @@ struct Import {
688};828};
689829
690struct VirtualMachine {830struct VirtualMachine {
691 uint64_t *stack;831 uint32_t *stack;
692 /// Points to one after the last stack item.832 /// Points to one after the last stack item.
693 uint32_t stack_top;833 uint32_t stack_top;
694 struct ProgramCounter pc;834 struct ProgramCounter pc;
...@@ -869,7 +1009,6 @@ static enum wasi_errno_t finish_wasi_stat(struct VirtualMachine *vm,...@@ -869,7 +1009,6 @@ static enum wasi_errno_t finish_wasi_stat(struct VirtualMachine *vm,
869 write_u64_le(vm->memory + buf + 0x30, to_wasi_timestamp(st.st_mtim));1009 write_u64_le(vm->memory + buf + 0x30, to_wasi_timestamp(st.st_mtim));
870 write_u64_le(vm->memory + buf + 0x38, to_wasi_timestamp(st.st_ctim));1010 write_u64_le(vm->memory + buf + 0x38, to_wasi_timestamp(st.st_ctim));
871#endif1011#endif
872
873 return WASI_ESUCCESS;1012 return WASI_ESUCCESS;
874}1013}
8751014
...@@ -890,7 +1029,7 @@ static enum wasi_errno_t wasi_args_sizes_get(struct VirtualMachine *vm,...@@ -890,7 +1029,7 @@ static enum wasi_errno_t wasi_args_sizes_get(struct VirtualMachine *vm,
8901029
891/// extern fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;1030/// extern fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
892static enum wasi_errno_t wasi_args_get(struct VirtualMachine *vm,1031static 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)
894{1033{
895 uint32_t argv_buf_i = 0;1034 uint32_t argv_buf_i = 0;
896 uint32_t arg_i = 0;1035 uint32_t arg_i = 0;
...@@ -910,7 +1049,7 @@ static enum wasi_errno_t wasi_args_get(struct VirtualMachine *vm,...@@ -910,7 +1049,7 @@ static enum wasi_errno_t wasi_args_get(struct VirtualMachine *vm,
9101049
911/// extern fn random_get(buf: [*]u8, buf_len: usize) errno_t;1050/// extern fn random_get(buf: [*]u8, buf_len: usize) errno_t;
912static enum wasi_errno_t wasi_random_get(struct VirtualMachine *vm,1051static 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)
914{1053{
915#ifdef __linux__1054#ifdef __linux__
916 if (getrandom(vm->memory + buf, buf_len, 0) != buf_len) {1055 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,...@@ -1181,7 +1320,7 @@ static enum wasi_errno_t wasi_clock_time_get(struct VirtualMachine *vm,
11811320
1182///pub extern "wasi_snapshot_preview1" fn debug(string: [*:0]const u8, x: u64) void;1321///pub extern "wasi_snapshot_preview1" fn debug(string: [*:0]const u8, x: u64) void;
1183void wasi_debug(struct VirtualMachine *vm, uint32_t text, uint64_t n) {1322void 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);
1185}1324}
11861325
1187/// pub extern "wasi_snapshot_preview1" fn debug_slice(ptr: [*]const u8, len: usize) void;1326/// 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) {...@@ -1189,9 +1328,15 @@ void wasi_debug_slice(struct VirtualMachine *vm, uint32_t ptr, uint32_t len) {
1189 fprintf(stderr, "wasi_debug_slice: '%.*s'\n", len, vm->memory + ptr);1328 fprintf(stderr, "wasi_debug_slice: '%.*s'\n", len, vm->memory + ptr);
1190}1329}
11911330
1331enum StackType {
1332 ST_32,
1333 ST_64,
1334};
1335
1192struct Label {1336struct Label {
1193 enum WasmOp opcode;1337 enum WasmOp opcode;
1194 uint32_t stack_depth;1338 uint32_t stack_index;
1339 uint32_t stack_offset;
1195 struct TypeInfo type_info;1340 struct TypeInfo type_info;
1196 // this is a UINT32_MAX terminated linked list that is stored in the operands array1341 // this is a UINT32_MAX terminated linked list that is stored in the operands array
1197 uint32_t ref_list;1342 uint32_t ref_list;
...@@ -1209,7 +1354,7 @@ static uint32_t Label_operandCount(const struct Label *label) {...@@ -1209,7 +1354,7 @@ static uint32_t Label_operandCount(const struct Label *label) {
1209 }1354 }
1210}1355}
12111356
1212static bool Label_operandType(const struct Label *label, uint32_t index) {1357static enum StackType Label_operandType(const struct Label *label, uint32_t index) {
1213 if (label->opcode == WasmOp_loop) {1358 if (label->opcode == WasmOp_loop) {
1214 return bs_isSet(&label->type_info.param_types, index);1359 return bs_isSet(&label->type_info.param_types, index);
1215 } else {1360 } else {
...@@ -1217,29 +1362,69 @@ static bool Label_operandType(const struct Label *label, uint32_t index) {...@@ -1217,29 +1362,69 @@ static bool Label_operandType(const struct Label *label, uint32_t index) {
1217 }1362 }
1218}1363}
12191364
1220static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint32_t *code_i,1365#define max_stack_depth (1 << 12)
1221 struct ProgramCounter *pc)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)
1222{1398{
1223 const char *mod_ptr = vm->mod_ptr;1399 const char *mod_ptr = vm->mod_ptr;
1224 uint8_t *opcodes = vm->opcodes;1400 uint8_t *opcodes = vm->opcodes;
1225 uint32_t *operands = vm->operands;1401 uint32_t *operands = vm->operands;
1226 struct TypeInfo *func_type_info = &vm->types[func->type_idx];
12271402
1228 uint32_t unreachable_depth = 0;1403 // push return address
1229 uint32_t stack_depth = func_type_info->param_count + func->locals_count + 2;1404 uint32_t frame_size = stack->top_offset;
1230 static uint32_t stack_types[1 << (12 - 3)];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;
1232 static struct Label labels[1 << 9];1410 static struct Label labels[1 << 9];
1233#ifndef NDEBUG1411#ifndef NDEBUG
1234 memset(labels, 0xaa, sizeof(struct Label) * (1 << 9)); // to match the zig version1412 memset(labels, 0xaa, sizeof(struct Label) * (1 << 9)); // to match the zig version
1235#endif1413#endif
1236 uint32_t label_i = 0;
1237 labels[label_i].opcode = WasmOp_block;1414 labels[label_i].opcode = WasmOp_block;
1238 labels[label_i].stack_depth = stack_depth;1415 labels[label_i].stack_index = stack->top_index;
1239 labels[label_i].type_info = vm->types[func->type_idx];1416 labels[label_i].stack_offset = stack->top_offset;
1417 labels[label_i].type_info = *func_type_info;
1240 labels[label_i].ref_list = UINT32_MAX;1418 labels[label_i].ref_list = UINT32_MAX;
12411419
1420 enum {
1421 State_default,
1422 State_bool_not,
1423 } state = State_default;
1424
1242 for (;;) {1425 for (;;) {
1426 assert(stack->top_index >= labels[0].stack_index);
1427 assert(stack->top_offset >= labels[0].stack_offset);
1243 enum WasmOp opcode = (uint8_t)mod_ptr[*code_i];1428 enum WasmOp opcode = (uint8_t)mod_ptr[*code_i];
1244 *code_i += 1;1429 *code_i += 1;
1245 enum WasmPrefixedOp prefixed_opcode;1430 enum WasmPrefixedOp prefixed_opcode;
...@@ -1248,8 +1433,7 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1248,8 +1433,7 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1248 //fprintf(stderr, "decodeCode opcode=0x%x pc=%u:%u\n", opcode, pc->opcode, pc->operand);1433 //fprintf(stderr, "decodeCode opcode=0x%x pc=%u:%u\n", opcode, pc->opcode, pc->operand);
1249 //struct ProgramCounter old_pc = *pc;1434 //struct ProgramCounter old_pc = *pc;
12501435
1251 uint32_t initial_stack_depth = stack_depth;1436 if (unreachable_depth == 0)
1252 if (unreachable_depth == 0) {
1253 switch (opcode) {1437 switch (opcode) {
1254 case WasmOp_unreachable:1438 case WasmOp_unreachable:
1255 case WasmOp_nop:1439 case WasmOp_nop:
...@@ -1258,58 +1442,62 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1258,58 +1442,62 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1258 case WasmOp_else:1442 case WasmOp_else:
1259 case WasmOp_end:1443 case WasmOp_end:
1260 case WasmOp_br:1444 case WasmOp_br:
1261 case WasmOp_call:
1262 case WasmOp_return:1445 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
1265 case WasmOp_if:1456 case WasmOp_if:
1266 case WasmOp_br_if:1457 case WasmOp_br_if:
1267 case WasmOp_br_table:1458 case WasmOp_br_table:
1268 case WasmOp_call_indirect:1459 case WasmOp_call_indirect:
1269 case WasmOp_drop:1460 si_pop(stack, ST_32);
1270 case WasmOp_local_set:
1271 case WasmOp_global_set:
1272 stack_depth -= 1;
1273 break;1461 break;
12741462
1275 case WasmOp_select:
1276 stack_depth -= 2;
1277 break;
1278
1279 case WasmOp_local_get:
1280 case WasmOp_global_get:
1281 case WasmOp_memory_size:1463 case WasmOp_memory_size:
1282 case WasmOp_i32_const:1464 case WasmOp_i32_const:
1283 case WasmOp_i64_const:
1284 case WasmOp_f32_const:1465 case WasmOp_f32_const:
1466 si_push(stack, ST_32);
1467 break;
1468
1469 case WasmOp_i64_const:
1285 case WasmOp_f64_const:1470 case WasmOp_f64_const:
1286 stack_depth += 1;1471 si_push(stack, ST_64);
1287 break;1472 break;
12881473
1289 case WasmOp_local_tee:
1290 case WasmOp_i32_load:1474 case WasmOp_i32_load:
1291 case WasmOp_i64_load:
1292 case WasmOp_f32_load:1475 case WasmOp_f32_load:
1293 case WasmOp_f64_load:
1294 case WasmOp_i32_load8_s:1476 case WasmOp_i32_load8_s:
1295 case WasmOp_i32_load8_u:1477 case WasmOp_i32_load8_u:
1296 case WasmOp_i32_load16_s:1478 case WasmOp_i32_load16_s:
1297 case WasmOp_i32_load16_u:1479 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:
1298 case WasmOp_i64_load8_s:1486 case WasmOp_i64_load8_s:
1299 case WasmOp_i64_load8_u:1487 case WasmOp_i64_load8_u:
1300 case WasmOp_i64_load16_s:1488 case WasmOp_i64_load16_s:
1301 case WasmOp_i64_load16_u:1489 case WasmOp_i64_load16_u:
1302 case WasmOp_i64_load32_s:1490 case WasmOp_i64_load32_s:
1303 case WasmOp_i64_load32_u:1491 case WasmOp_i64_load32_u:
1492 si_pop(stack, ST_32);
1493 si_push(stack, ST_64);
1494 break;
1495
1304 case WasmOp_memory_grow:1496 case WasmOp_memory_grow:
1305 case WasmOp_i32_eqz:1497 case WasmOp_i32_eqz:
1306 case WasmOp_i32_clz:1498 case WasmOp_i32_clz:
1307 case WasmOp_i32_ctz:1499 case WasmOp_i32_ctz:
1308 case WasmOp_i32_popcnt:1500 case WasmOp_i32_popcnt:
1309 case WasmOp_i64_eqz:
1310 case WasmOp_i64_clz:
1311 case WasmOp_i64_ctz:
1312 case WasmOp_i64_popcnt:
1313 case WasmOp_f32_abs:1501 case WasmOp_f32_abs:
1314 case WasmOp_f32_neg:1502 case WasmOp_f32_neg:
1315 case WasmOp_f32_ceil:1503 case WasmOp_f32_ceil:
...@@ -1317,6 +1505,32 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1317,6 +1505,32 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1317 case WasmOp_f32_trunc:1505 case WasmOp_f32_trunc:
1318 case WasmOp_f32_nearest:1506 case WasmOp_f32_nearest:
1319 case WasmOp_f32_sqrt:1507 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:
1320 case WasmOp_f64_abs:1534 case WasmOp_f64_abs:
1321 case WasmOp_f64_neg:1535 case WasmOp_f64_neg:
1322 case WasmOp_f64_ceil:1536 case WasmOp_f64_ceil:
...@@ -1324,48 +1538,45 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1324,48 +1538,45 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1324 case WasmOp_f64_trunc:1538 case WasmOp_f64_trunc:
1325 case WasmOp_f64_nearest:1539 case WasmOp_f64_nearest:
1326 case WasmOp_f64_sqrt:1540 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:
1336 case WasmOp_i64_trunc_f64_s:1541 case WasmOp_i64_trunc_f64_s:
1337 case WasmOp_i64_trunc_f64_u:1542 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:
1345 case WasmOp_f64_convert_i64_s:1543 case WasmOp_f64_convert_i64_s:
1346 case WasmOp_f64_convert_i64_u:1544 case WasmOp_f64_convert_i64_u:
1347 case WasmOp_f64_promote_f32:
1348 case WasmOp_i32_reinterpret_f32:
1349 case WasmOp_i64_reinterpret_f64:1545 case WasmOp_i64_reinterpret_f64:
1350 case WasmOp_f32_reinterpret_i32:
1351 case WasmOp_f64_reinterpret_i64:1546 case WasmOp_f64_reinterpret_i64:
1352 case WasmOp_i32_extend8_s:
1353 case WasmOp_i32_extend16_s:
1354 case WasmOp_i64_extend8_s:1547 case WasmOp_i64_extend8_s:
1355 case WasmOp_i64_extend16_s:1548 case WasmOp_i64_extend16_s:
1356 case WasmOp_i64_extend32_s:1549 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);
1357 break;1563 break;
13581564
1359 case WasmOp_i32_store:1565 case WasmOp_i32_store:
1360 case WasmOp_i64_store:
1361 case WasmOp_f32_store:1566 case WasmOp_f32_store:
1362 case WasmOp_f64_store:
1363 case WasmOp_i32_store8:1567 case WasmOp_i32_store8:
1364 case WasmOp_i32_store16:1568 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:
1365 case WasmOp_i64_store8:1575 case WasmOp_i64_store8:
1366 case WasmOp_i64_store16:1576 case WasmOp_i64_store16:
1367 case WasmOp_i64_store32:1577 case WasmOp_i64_store32:
1368 stack_depth -= 2;1578 si_pop(stack, ST_64);
1579 si_pop(stack, ST_32);
1369 break;1580 break;
13701581
1371 case WasmOp_i32_eq:1582 case WasmOp_i32_eq:
...@@ -1378,6 +1589,17 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1378,6 +1589,17 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1378 case WasmOp_i32_le_u:1589 case WasmOp_i32_le_u:
1379 case WasmOp_i32_ge_s:1590 case WasmOp_i32_ge_s:
1380 case WasmOp_i32_ge_u:1591 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
1381 case WasmOp_i64_eq:1603 case WasmOp_i64_eq:
1382 case WasmOp_i64_ne:1604 case WasmOp_i64_ne:
1383 case WasmOp_i64_lt_s:1605 case WasmOp_i64_lt_s:
...@@ -1388,18 +1610,17 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1388,18 +1610,17 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1388 case WasmOp_i64_le_u:1610 case WasmOp_i64_le_u:
1389 case WasmOp_i64_ge_s:1611 case WasmOp_i64_ge_s:
1390 case WasmOp_i64_ge_u:1612 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:
1397 case WasmOp_f64_eq:1613 case WasmOp_f64_eq:
1398 case WasmOp_f64_ne:1614 case WasmOp_f64_ne:
1399 case WasmOp_f64_lt:1615 case WasmOp_f64_lt:
1400 case WasmOp_f64_gt:1616 case WasmOp_f64_gt:
1401 case WasmOp_f64_le:1617 case WasmOp_f64_le:
1402 case WasmOp_f64_ge:1618 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
1403 case WasmOp_i32_add:1624 case WasmOp_i32_add:
1404 case WasmOp_i32_sub:1625 case WasmOp_i32_sub:
1405 case WasmOp_i32_mul:1626 case WasmOp_i32_mul:
...@@ -1415,6 +1636,18 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1415,6 +1636,18 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1415 case WasmOp_i32_shr_u:1636 case WasmOp_i32_shr_u:
1416 case WasmOp_i32_rotl:1637 case WasmOp_i32_rotl:
1417 case WasmOp_i32_rotr:1638 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
1418 case WasmOp_i64_add:1651 case WasmOp_i64_add:
1419 case WasmOp_i64_sub:1652 case WasmOp_i64_sub:
1420 case WasmOp_i64_mul:1653 case WasmOp_i64_mul:
...@@ -1430,13 +1663,6 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1430,13 +1663,6 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1430 case WasmOp_i64_shr_u:1663 case WasmOp_i64_shr_u:
1431 case WasmOp_i64_rotl:1664 case WasmOp_i64_rotl:
1432 case WasmOp_i64_rotr:1665 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:
1440 case WasmOp_f64_add:1666 case WasmOp_f64_add:
1441 case WasmOp_f64_sub:1667 case WasmOp_f64_sub:
1442 case WasmOp_f64_mul:1668 case WasmOp_f64_mul:
...@@ -1444,19 +1670,35 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1444,19 +1670,35 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1444 case WasmOp_f64_min:1670 case WasmOp_f64_min:
1445 case WasmOp_f64_max:1671 case WasmOp_f64_max:
1446 case WasmOp_f64_copysign:1672 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);
1448 break;1676 break;
14491677
1450 case WasmOp_prefixed:1678 case WasmOp_prefixed:
1451 switch (prefixed_opcode) {1679 switch (prefixed_opcode) {
1452 case WasmPrefixedOp_i32_trunc_sat_f32_s:1680 case WasmPrefixedOp_i32_trunc_sat_f32_s:
1453 case WasmPrefixedOp_i32_trunc_sat_f32_u:1681 case WasmPrefixedOp_i32_trunc_sat_f32_u:
1682 si_pop(stack, ST_32);
1683 si_push(stack, ST_32);
1684 break;
1685
1454 case WasmPrefixedOp_i32_trunc_sat_f64_s:1686 case WasmPrefixedOp_i32_trunc_sat_f64_s:
1455 case WasmPrefixedOp_i32_trunc_sat_f64_u:1687 case WasmPrefixedOp_i32_trunc_sat_f64_u:
1688 si_pop(stack, ST_64);
1689 si_push(stack, ST_32);
1690 break;
1691
1456 case WasmPrefixedOp_i64_trunc_sat_f32_s:1692 case WasmPrefixedOp_i64_trunc_sat_f32_s:
1457 case WasmPrefixedOp_i64_trunc_sat_f32_u:1693 case WasmPrefixedOp_i64_trunc_sat_f32_u:
1694 si_pop(stack, ST_32);
1695 si_push(stack, ST_64);
1696 break;
1697
1458 case WasmPrefixedOp_i64_trunc_sat_f64_s:1698 case WasmPrefixedOp_i64_trunc_sat_f64_s:
1459 case WasmPrefixedOp_i64_trunc_sat_f64_u:1699 case WasmPrefixedOp_i64_trunc_sat_f64_u:
1700 si_pop(stack, ST_64);
1701 si_push(stack, ST_64);
1460 break;1702 break;
14611703
1462 case WasmPrefixedOp_memory_init:1704 case WasmPrefixedOp_memory_init:
...@@ -1464,8 +1706,15 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1464,8 +1706,15 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1464 case WasmPrefixedOp_memory_fill:1706 case WasmPrefixedOp_memory_fill:
1465 case WasmPrefixedOp_table_init:1707 case WasmPrefixedOp_table_init:
1466 case WasmPrefixedOp_table_copy:1708 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
1467 case WasmPrefixedOp_table_fill:1714 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);
1469 break;1718 break;
14701719
1471 case WasmPrefixedOp_data_drop:1720 case WasmPrefixedOp_data_drop:
...@@ -1473,11 +1722,13 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1473,11 +1722,13 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1473 break;1722 break;
14741723
1475 case WasmPrefixedOp_table_grow:1724 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);
1477 break;1728 break;
14781729
1479 case WasmPrefixedOp_table_size:1730 case WasmPrefixedOp_table_size:
1480 stack_depth += 1;1731 si_push(stack, ST_32);
1481 break;1732 break;
14821733
1483 default: panic("unexpected prefixed opcode");1734 default: panic("unexpected prefixed opcode");
...@@ -1486,235 +1737,14 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1486,235 +1737,14 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
14861737
1487 default: panic("unexpected opcode");1738 default: panic("unexpected opcode");
1488 }1739 }
1489 switch (opcode) {1740 switch (opcode) {
1490 case WasmOp_unreachable:1741 case WasmOp_unreachable:
1491 case WasmOp_nop:1742 if (unreachable_depth == 0) {
1492 case WasmOp_block:1743 opcodes[pc->opcode] = Op_unreachable;
1493 case WasmOp_loop:1744 pc->opcode += 1;
1494 case WasmOp_else:1745 unreachable_depth += 1;
1495 case WasmOp_end:1746 }
1496 case WasmOp_br:1747 break;
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;
17181748
1719 case WasmOp_nop:1749 case WasmOp_nop:
1720 case WasmOp_i32_reinterpret_f32:1750 case WasmOp_i32_reinterpret_f32:
...@@ -1748,11 +1778,19 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1748,11 +1778,19 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1748 break;1778 break;
1749 default: panic("unexpected param type");1779 default: panic("unexpected param type");
1750 }1780 }
1751 } else {1781 } else label->type_info = vm->types[block_type];
1752 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));
1753 }1787 }
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;
1755 label->ref_list = UINT32_MAX;1790 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
1756 switch (opcode) {1794 switch (opcode) {
1757 case WasmOp_block:1795 case WasmOp_block:
1758 break;1796 break;
...@@ -1762,7 +1800,10 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1762,7 +1800,10 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1762 break;1800 break;
17631801
1764 case WasmOp_if:1802 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;
1766 pc->opcode += 1;1807 pc->opcode += 1;
1767 operands[pc->operand] = 0;1808 operands[pc->operand] = 0;
1768 label->extra.else_ref = pc->operand + 1;1809 label->extra.else_ref = pc->operand + 1;
...@@ -1771,7 +1812,7 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1771,7 +1812,7 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
17711812
1772 default: panic("unexpected label opcode");1813 default: panic("unexpected label opcode");
1773 }1814 }
1774 }1815 } else unreachable_depth += 1;
1775 }1816 }
1776 break;1817 break;
17771818
...@@ -1780,8 +1821,16 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1780,8 +1821,16 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1780 struct Label *label = &labels[label_i];1821 struct Label *label = &labels[label_i];
1781 assert(label->opcode == WasmOp_if);1822 assert(label->opcode == WasmOp_if);
1782 label->opcode = WasmOp_else;1823 label->opcode = WasmOp_else;
1824
1783 if (unreachable_depth == 0) {1825 if (unreachable_depth == 0) {
1784 uint32_t operand_count = Label_operandCount(label);1826 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
1785 switch (operand_count) {1834 switch (operand_count) {
1786 case 0:1835 case 0:
1787 opcodes[pc->opcode] = Op_br_void;1836 opcodes[pc->opcode] = Op_br_void;
...@@ -1790,31 +1839,30 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1790,31 +1839,30 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1790 case 1:1839 case 1:
1791 //fprintf(stderr, "label_i=%u operand_type=%d\n",1840 //fprintf(stderr, "label_i=%u operand_type=%d\n",
1792 // label_i, Label_operandType(label, 0));1841 // label_i, Label_operandType(label, 0));
1793 if (Label_operandType(label, 0)) {1842 switch (Label_operandType(label, 0)) {
1794 opcodes[pc->opcode] = Op_br_64;1843 case ST_32: opcodes[pc->opcode] = Op_br_32; break;
1795 } else {1844 case ST_64: opcodes[pc->opcode] = Op_br_64; break;
1796 opcodes[pc->opcode] = Op_br_32;
1797 }1845 }
1798 break;1846 break;
17991847
1800 default: panic("unexpected operand count");1848 default: panic("unexpected operand count");
1801 }1849 }
1802 pc->opcode += 1;1850 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;
1804 operands[pc->operand + 1] = label->ref_list;1852 operands[pc->operand + 1] = label->ref_list;
1805 label->ref_list = pc->operand + 1;1853 label->ref_list = pc->operand + 1;
1806 pc->operand += 3;1854 pc->operand += 3;
1807 assert(stack_depth - label->type_info.result_count == label->stack_depth);
1808 } else unreachable_depth = 0;1855 } else unreachable_depth = 0;
1856
1809 operands[label->extra.else_ref + 0] = pc->opcode;1857 operands[label->extra.else_ref + 0] = pc->opcode;
1810 operands[label->extra.else_ref + 1] = pc->operand;1858 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));
1812 }1861 }
1813 break;1862 break;
18141863
1815 case WasmOp_end:1864 case WasmOp_end:
1816 if (unreachable_depth <= 1) {1865 if (unreachable_depth <= 1) {
1817 unreachable_depth = 0;
1818 struct Label *label = &labels[label_i];1866 struct Label *label = &labels[label_i];
1819 struct ProgramCounter *target_pc = (label->opcode == WasmOp_loop) ? &label->extra.loop_pc : pc;1867 struct ProgramCounter *target_pc = (label->opcode == WasmOp_loop) ? &label->extra.loop_pc : pc;
1820 if (label->opcode == WasmOp_if) {1868 if (label->opcode == WasmOp_if) {
...@@ -1828,33 +1876,44 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1828,33 +1876,44 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1828 operands[ref + 1] = target_pc->operand;1876 operands[ref + 1] = target_pc->operand;
1829 ref = next_ref;1877 ref = next_ref;
1830 }1878 }
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
1833 if (label_i == 0) {1887 if (label_i == 0) {
1834 uint32_t operand_count = Label_operandCount(&labels[0]);1888 assert(stack->top_index == label->stack_index);
1835 switch (operand_count) {1889 assert(stack->top_offset == label->stack_offset);
1890
1891 switch (labels[0].type_info.result_count) {
1836 case 0:1892 case 0:
1837 opcodes[pc->opcode] = Op_return_void;1893 opcodes[pc->opcode] = Op_return_void;
1838 break;1894 break;
18391895
1840 case 1:1896 case 1:
1841 switch ((int)Label_operandType(&labels[0], 0)) {1897 switch ((enum StackType)bs_isSet(&labels[0].type_info.result_types, 0)) {
1842 case false: opcodes[pc->opcode] = Op_return_32; break;1898 case ST_32: opcodes[pc->opcode] = Op_return_32; break;
1843 case true: opcodes[pc->opcode] = Op_return_64; break;1899 case ST_64: opcodes[pc->opcode] = Op_return_64; break;
1844 }1900 }
1845 break;1901 break;
18461902
1847 default: panic("unexpected operand count");1903 default: panic("unexpected operand count");
1848 }1904 }
1849 pc->opcode += 1;1905 pc->opcode += 1;
1850 operands[pc->operand + 0] = 2 + operand_count;1906 operands[pc->operand + 0] = stack->top_offset - labels[0].stack_offset;
1851 stack_depth -= operand_count;1907 operands[pc->operand + 1] = frame_size;
1852 assert(stack_depth == labels[0].stack_depth);
1853 operands[pc->operand + 1] = stack_depth;
1854 pc->operand += 2;1908 pc->operand += 2;
1855 return;1909 return;
1856 }1910 }
1857 label_i -= 1;1911 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));
1858 } else unreachable_depth -= 1;1917 } else unreachable_depth -= 1;
1859 break;1918 break;
18601919
...@@ -1865,6 +1924,12 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1865,6 +1924,12 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1865 if (unreachable_depth == 0) {1924 if (unreachable_depth == 0) {
1866 struct Label *label = &labels[label_i - label_idx];1925 struct Label *label = &labels[label_i - label_idx];
1867 uint32_t operand_count = Label_operandCount(label);1926 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
1868 switch (opcode) {1933 switch (opcode) {
1869 case WasmOp_br:1934 case WasmOp_br:
1870 switch (operand_count) {1935 switch (operand_count) {
...@@ -1873,9 +1938,9 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1873,9 +1938,9 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1873 break;1938 break;
18741939
1875 case 1:1940 case 1:
1876 switch ((int)Label_operandType(label, 0)) {1941 switch (Label_operandType(label, 0)) {
1877 case false: opcodes[pc->opcode] = Op_br_32; break;1942 case ST_32: opcodes[pc->opcode] = Op_br_32; break;
1878 case true: opcodes[pc->opcode] = Op_br_64; break;1943 case ST_64: opcodes[pc->opcode] = Op_br_64; break;
1879 }1944 }
1880 break;1945 break;
18811946
...@@ -1886,13 +1951,27 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1886,13 +1951,27 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1886 case WasmOp_br_if:1951 case WasmOp_br_if:
1887 switch (operand_count) {1952 switch (operand_count) {
1888 case 0:1953 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;
1890 break;1958 break;
18911959
1892 case 1:1960 case 1:
1893 switch ((int)Label_operandType(label, 0)) {1961 switch (Label_operandType(label, 0)) {
1894 case false: opcodes[pc->opcode] = Op_br_if_nez_32; break;1962 case ST_32:
1895 case true: opcodes[pc->opcode] = Op_br_if_nez_64; break;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;
1896 }1975 }
1897 break;1976 break;
18981977
...@@ -1900,13 +1979,26 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1900,13 +1979,26 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1900 }1979 }
1901 break;1980 break;
19021981
1903 default: panic("unreachable");1982 default: panic("unexpected opcode");
1904 }1983 }
1905 pc->opcode += 1;1984 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;
1907 operands[pc->operand + 1] = label->ref_list;1986 operands[pc->operand + 1] = label->ref_list;
1908 label->ref_list = pc->operand + 1;1987 label->ref_list = pc->operand + 1;
1909 pc->operand += 3;1988 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 }
1910 }2002 }
1911 }2003 }
1912 break;2004 break;
...@@ -1918,17 +2010,22 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1918,17 +2010,22 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1918 uint32_t label_idx = read32_uleb128(mod_ptr, code_i);2010 uint32_t label_idx = read32_uleb128(mod_ptr, code_i);
1919 if (unreachable_depth != 0) continue;2011 if (unreachable_depth != 0) continue;
1920 struct Label *label = &labels[label_i - label_idx];2012 struct Label *label = &labels[label_i - label_idx];
1921 uint32_t operand_count = Label_operandCount(label);
1922 if (i == 0) {2013 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
1923 switch (operand_count) {2020 switch (operand_count) {
1924 case 0:2021 case 0:
1925 opcodes[pc->opcode] = Op_br_table_void;2022 opcodes[pc->opcode] = Op_br_table_void;
1926 break;2023 break;
19272024
1928 case 1:2025 case 1:
1929 switch ((int)Label_operandType(label, 0)) {2026 switch (Label_operandType(label, 0)) {
1930 case false: opcodes[pc->opcode] = Op_br_table_32; break;2027 case ST_32: opcodes[pc->opcode] = Op_br_table_32; break;
1931 case true: opcodes[pc->opcode] = Op_br_table_64; break;2028 case ST_64: opcodes[pc->opcode] = Op_br_table_64; break;
1932 }2029 }
1933 break;2030 break;
19342031
...@@ -1938,11 +2035,41 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1938,11 +2035,41 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1938 operands[pc->operand] = labels_len;2035 operands[pc->operand] = labels_len;
1939 pc->operand += 1;2036 pc->operand += 1;
1940 }2037 }
1941 operands[pc->operand + 0] = stack_depth - operand_count - label->stack_depth;2038 operands[pc->operand + 0] = stack->top_offset - label->stack_offset;
1942 operands[pc->operand + 1] = label->ref_list;2039 operands[pc->operand + 1] = label->ref_list;
1943 label->ref_list = pc->operand + 1;2040 label->ref_list = pc->operand + 1;
1944 pc->operand += 3;2041 pc->operand += 3;
1945 }2042 }
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;
1946 }2073 }
1947 break;2074 break;
19482075
...@@ -1950,19 +2077,28 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1950,19 +2077,28 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1950 {2077 {
1951 uint32_t fn_id = read32_uleb128(mod_ptr, code_i);2078 uint32_t fn_id = read32_uleb128(mod_ptr, code_i);
1952 if (unreachable_depth == 0) {2079 if (unreachable_depth == 0) {
1953 opcodes[pc->opcode] = Op_call;2080 uint32_t type_idx;
1954 pc->opcode += 1;2081 if (fn_id < vm->imports_len) {
1955 operands[pc->operand] = fn_id;2082 opcodes[pc->opcode + 0] = Op_call_import;
1956 pc->operand += 1;2083 opcodes[pc->opcode + 1] = fn_id;
1957 uint32_t type_idx = (fn_id < vm->imports_len) ?2084 pc->opcode += 2;
1958 vm->imports[fn_id].type_idx :2085 type_idx = vm->imports[fn_id].type_idx;
1959 vm->functions[fn_id - vm->imports_len].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 }
1960 struct TypeInfo *type_info = &vm->types[type_idx];2094 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 }
1962 for (uint32_t result_i = 0; result_i < type_info->result_count; result_i += 1)2100 for (uint32_t result_i = 0; result_i < type_info->result_count; result_i += 1)
1963 bs_setValue(stack_types, stack_depth + result_i,2101 si_push(stack, bs_isSet(&type_info->result_types, result_i));
1964 bs_isSet(&type_info->result_types, result_i));
1965 stack_depth += type_info->result_count;
1966 }2102 }
1967 }2103 }
1968 break;2104 break;
...@@ -1972,171 +2108,144 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -1972,171 +2108,144 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
1972 uint32_t type_idx = read32_uleb128(mod_ptr, code_i);2108 uint32_t type_idx = read32_uleb128(mod_ptr, code_i);
1973 if (read32_uleb128(mod_ptr, code_i) != 0) panic("unexpected table index");2109 if (read32_uleb128(mod_ptr, code_i) != 0) panic("unexpected table index");
1974 if (unreachable_depth == 0) {2110 if (unreachable_depth == 0) {
1975 opcodes[pc->opcode + 0] = Op_wasm;2111 opcodes[pc->opcode] = Op_call_indirect;
1976 opcodes[pc->opcode + 1] = opcode;2112 pc->opcode += 1;
1977 pc->opcode += 2;2113
1978 struct TypeInfo *type_info = &vm->types[type_idx];2114 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 }
1980 for (uint32_t result_i = 0; result_i < type_info->result_count; result_i += 1)2119 for (uint32_t result_i = 0; result_i < type_info->result_count; result_i += 1)
1981 bs_setValue(stack_types, stack_depth + result_i,2120 si_push(stack, bs_isSet(&type_info->result_types, result_i));
1982 bs_isSet(&type_info->result_types, result_i));
1983 stack_depth += type_info->result_count;
1984 }2121 }
1985 }2122 }
1986 break;2123 break;
19872124
1988 case WasmOp_return:2125 case WasmOp_select:
1989 if (unreachable_depth <= 1) {2126 case WasmOp_drop:
1990 uint32_t operand_count = Label_operandCount(&labels[0]);2127 if (unreachable_depth == 0) {
1991 switch (operand_count) {2128 if (opcode == WasmOp_select) si_pop(stack, ST_32);
1992 case 0:2129 enum StackType operand_type = si_top(stack);
1993 opcodes[pc->opcode] = Op_return_void;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 }
1994 break;2141 break;
19952142
1996 case 1:2143 case WasmOp_drop:
1997 switch ((int)Label_operandType(&labels[0], 0)) {2144 switch (operand_type) {
1998 case false: opcodes[pc->opcode] = Op_return_32; break;2145 case ST_32: opcodes[pc->opcode] = Op_drop_32; break;
1999 case true: opcodes[pc->opcode] = Op_return_64; break;2146 case ST_64: opcodes[pc->opcode] = Op_drop_64; break;
2000 }2147 }
2001 break;2148 break;
20022149
2003 default: panic("unexpected operand count");2150 default: panic("unexpected opcode");
2004 }2151 }
2005 pc->opcode += 1;2152 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;
2010 }2153 }
2011 break;2154 break;
20122155
2013 case WasmOp_select:2156 case WasmOp_local_get:
2014 case WasmOp_drop:2157 case WasmOp_local_set:
2015 if (unreachable_depth == 0) {2158 case WasmOp_local_tee:
2016 switch ((int)bs_isSet(stack_types, stack_depth)) {2159 {
2017 case false: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);
2018 switch (opcode) {2163 switch (opcode) {
2019 case WasmOp_select:2164 case WasmOp_local_get:
2020 opcodes[pc->opcode] = Op_select_32;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 }
2021 break;2169 break;
20222170
2023 case WasmOp_drop:2171 case WasmOp_local_set:
2024 opcodes[pc->opcode] = Op_drop_32;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 }
2025 break;2183 break;
20262184
2027 default: panic("unexpected opcode");2185 default: panic("unexpected opcode");
2028 }2186 }
2029 break;2187 pc->opcode += 1;
20302188 operands[pc->operand] = stack->top_offset - stack->offsets[local_idx];
2031 case true:2189 pc->operand += 1;
2032 switch (opcode) {2190 switch (opcode) {
2033 case WasmOp_select:2191 case WasmOp_local_get:
2034 opcodes[pc->opcode] = Op_select_64;2192 si_push(stack, local_type);
2193 break;
2194
2195 case WasmOp_local_set:
2196 si_pop(stack, local_type);
2035 break;2197 break;
20362198
2037 case WasmOp_drop:2199 case WasmOp_local_tee:
2038 opcodes[pc->opcode] = Op_drop_64;2200 si_pop(stack, local_type);
2201 si_push(stack, local_type);
2039 break;2202 break;
20402203
2041 default: panic("unexpected opcode");2204 default: panic("unexpected opcode");
2042 }2205 }
2043 break;
2044 }2206 }
2045 pc->opcode += 1;
2046 }2207 }
2047 break;2208 break;
20482209
2049 case WasmOp_local_get:2210 case WasmOp_global_get:
2050 case WasmOp_local_set:2211 case WasmOp_global_set:
2051 case WasmOp_local_tee:
2052 {2212 {
2053 uint32_t local_idx = read32_uleb128(mod_ptr, code_i);2213 uint32_t global_idx = read32_uleb128(mod_ptr, code_i);
2054 if (unreachable_depth == 0) {2214 if (unreachable_depth == 0) {
2055 bool local_type = bs_isSet(func->local_types, local_idx);2215 enum StackType global_type = ST_32; // all globals assumed to be 32-bit
2056 switch ((int)local_type) {2216 switch (opcode) {
2057 case false:2217 case WasmOp_global_get:
2058 switch (opcode) {2218 switch (global_idx) {
2059 case WasmOp_local_get:2219 case 0: opcodes[pc->opcode] = Op_global_get_0_32; break;
2060 opcodes[pc->opcode] = Op_local_get_32;2220 default: opcodes[pc->opcode] = Op_global_get_32; break;
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");
2072 }2221 }
2073 break;2222 break;
20742223
2075 case true:2224 case WasmOp_global_set:
2076 switch (opcode) {2225 switch (global_idx) {
2077 case WasmOp_local_get:2226 case 0: opcodes[pc->opcode] = Op_global_set_0_32; break;
2078 opcodes[pc->opcode] = Op_local_get_64;2227 default: opcodes[pc->opcode] = Op_global_set_32; break;
2079 break;2228 }
2229 break;
20802230
2081 case WasmOp_local_set:2231 default: panic("unexpected opcode");
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;
2134 }2232 }
2135 pc->opcode += 1;2233 pc->opcode += 1;
2136 if (global_idx != 0) {2234 if (global_idx != 0) {
2137 operands[pc->operand] = global_idx;2235 operands[pc->operand] = global_idx;
2138 pc->operand += 1;2236 pc->operand += 1;
2139 }2237 }
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 }
2140 }2249 }
2141 }2250 }
2142 break;2251 break;
...@@ -2169,11 +2278,111 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -2169,11 +2278,111 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
2169 uint32_t offset = read32_uleb128(mod_ptr, code_i);2278 uint32_t offset = read32_uleb128(mod_ptr, code_i);
2170 (void)alignment;2279 (void)alignment;
2171 if (unreachable_depth == 0) {2280 if (unreachable_depth == 0) {
2172 opcodes[pc->opcode + 0] = Op_wasm;2281 switch (opcode) {
2173 opcodes[pc->opcode + 1] = opcode;2282 default: break;
2174 pc->opcode += 2;2283
2175 operands[pc->operand] = offset;2284 case WasmOp_i64_store8: case WasmOp_i64_store16: case WasmOp_i64_store32:
2176 pc->operand += 1;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 }
2177 }2386 }
2178 }2387 }
2179 break;2388 break;
...@@ -2184,110 +2393,224 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -2184,110 +2393,224 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
2184 if (mod_ptr[*code_i] != 0) panic("unexpected memory index");2393 if (mod_ptr[*code_i] != 0) panic("unexpected memory index");
2185 *code_i += 1;2394 *code_i += 1;
2186 if (unreachable_depth == 0) {2395 if (unreachable_depth == 0) {
2187 opcodes[pc->opcode + 0] = Op_wasm;2396 switch (opcode) {
2188 opcodes[pc->opcode + 1] = opcode;2397 case WasmOp_memory_size: opcodes[pc->opcode] = Op_mem_size; break;
2189 pc->opcode += 2;2398 case WasmOp_memory_grow: opcodes[pc->opcode] = Op_mem_grow; break;
2399 default: panic("unexpected opcode");
2400 }
2401 pc->opcode += 1;
2190 }2402 }
2191 }2403 }
2192 break;2404 break;
21932405
2194 case WasmOp_i32_const:2406 case WasmOp_i32_const:
2407 case WasmOp_f32_const:
2195 {2408 {
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 }
2197 if (unreachable_depth == 0) {2420 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 }
2199 pc->opcode += 1;2433 pc->opcode += 1;
2200 operands[pc->operand] = x;
2201 pc->operand += 1;
2202 }2434 }
2203 }2435 }
2204 break;2436 break;
22052437
2206 case WasmOp_i64_const:2438 case WasmOp_i64_const:
2439 case WasmOp_f64_const:
2207 {2440 {
2208 uint64_t x = read64_ileb128(mod_ptr, code_i);2441 uint64_t value;
2209 if (unreachable_depth == 0) {2442 switch (opcode) {
2210 opcodes[pc->opcode] = Op_const_64;2443 case WasmOp_i64_const: value = read64_ileb128(mod_ptr, code_i); break;
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;
22182444
2219 case WasmOp_f32_const:2445 case WasmOp_f64_const:
2220 {2446 value = read_u64_le(&mod_ptr[*code_i]);
2221 uint32_t x;2447 *code_i += sizeof(value);
2222 memcpy(&x, mod_ptr + *code_i, 4);2448 break;
2223 *code_i += 4;2449
2224 if (unreachable_depth == 0) {2450 default: panic("unexpected opcode");
2225 opcodes[pc->opcode] = Op_const_32;
2226 pc->opcode += 1;
2227 operands[pc->operand] = x;
2228 pc->operand += 1;
2229 }2451 }
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;
2238 if (unreachable_depth == 0) {2453 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 }
2240 pc->opcode += 1;2467 pc->opcode += 1;
2241 operands[pc->operand + 0] = x & UINT32_MAX;
2242 operands[pc->operand + 1] = (x >> 32) & UINT32_MAX;
2243 pc->operand += 2;
2244 }2468 }
2245 }2469 }
2246 break;2470 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
2258 default:2472 default:
2259 if (unreachable_depth == 0) {2473 if (unreachable_depth == 0) {
2260 opcodes[pc->opcode + 0] = Op_wasm;2474 switch (opcode) {
2261 opcodes[pc->opcode + 1] = opcode;2475 case WasmOp_i32_eqz: opcodes[pc->opcode] = Op_eqz_32; break;
2262 pc->opcode += 2;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;
2263 }2602 }
2264 break;2603 break;
22652604
2266 case WasmOp_prefixed:2605 case WasmOp_prefixed:
2267 switch (prefixed_opcode) {2606 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
2283 case WasmPrefixedOp_memory_copy:2607 case WasmPrefixedOp_memory_copy:
2284 if (mod_ptr[*code_i + 0] != 0 || mod_ptr[*code_i + 1] != 0)2608 if (mod_ptr[*code_i + 0] != 0 || mod_ptr[*code_i + 1] != 0)
2285 panic("unexpected memory index");2609 panic("unexpected memory index");
2286 *code_i += 2;2610 *code_i += 2;
2287 if (unreachable_depth == 0) {2611 if (unreachable_depth == 0) {
2288 opcodes[pc->opcode + 0] = Op_wasm_prefixed;2612 opcodes[pc->opcode] = Op_memcpy;
2289 opcodes[pc->opcode + 1] = prefixed_opcode;2613 pc->opcode += 1;
2290 pc->opcode += 2;
2291 }2614 }
2292 break;2615 break;
22932616
...@@ -2295,27 +2618,18 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint...@@ -2295,27 +2618,18 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
2295 if (mod_ptr[*code_i] != 0) panic("unexpected memory index");2618 if (mod_ptr[*code_i] != 0) panic("unexpected memory index");
2296 *code_i += 1;2619 *code_i += 1;
2297 if (unreachable_depth == 0) {2620 if (unreachable_depth == 0) {
2298 opcodes[pc->opcode + 0] = Op_wasm_prefixed;2621 opcodes[pc->opcode] = Op_memset;
2299 opcodes[pc->opcode + 1] = prefixed_opcode;2622 pc->opcode += 1;
2300 pc->opcode += 2;
2301 }2623 }
2302 break;2624 break;
23032625
2304 default: panic("unreachable");2626 default: panic("unexpected opcode");
2305 }2627 }
2306 break;2628 break;
2307 }2629 }
2308
2309 switch (opcode) {2630 switch (opcode) {
2310 case WasmOp_unreachable:2631 default: state = State_default; break;
2311 case WasmOp_return:2632 case WasmOp_i32_eqz: state = State_bool_not; break;
2312 case WasmOp_br:
2313 case WasmOp_br_table:
2314 if (unreachable_depth == 0) unreachable_depth = 1;
2315 break;
2316
2317 default:
2318 break;
2319 }2633 }
23202634
2321 //for (uint32_t i = old_pc.opcode; i < pc->opcode; i += 1) {2635 //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...@@ -2328,70 +2642,71 @@ static void vm_decodeCode(struct VirtualMachine *vm, struct Function *func, uint
2328}2642}
23292643
2330static void vm_push_u32(struct VirtualMachine *vm, uint32_t value) {2644static 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;
2332 vm->stack_top += 1;2646 vm->stack_top += 1;
2333}2647}
23342648
2335static void vm_push_i32(struct VirtualMachine *vm, int32_t value) {2649static 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);
2337}2651}
23382652
2339static void vm_push_u64(struct VirtualMachine *vm, uint64_t value) {2653static void vm_push_u64(struct VirtualMachine *vm, uint64_t value) {
2340 vm->stack[vm->stack_top] = value;2654 vm->stack[vm->stack_top + 0] = (uint32_t)(value >> 0);
2341 vm->stack_top += 1;2655 vm->stack[vm->stack_top + 1] = (uint32_t)(value >> 32);
2656 vm->stack_top += 2;
2342}2657}
23432658
2344static void vm_push_i64(struct VirtualMachine *vm, int64_t value) {2659static 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);
2346}2661}
23472662
2348static void vm_push_f32(struct VirtualMachine *vm, float value) {2663static void vm_push_f32(struct VirtualMachine *vm, float value) {
2349 uint32_t integer;2664 uint32_t integer;
2350 memcpy(&integer, &value, 4);2665 memcpy(&integer, &value, sizeof(integer));
2351 return vm_push_u32(vm, integer);2666 vm_push_u32(vm, integer);
2352}2667}
23532668
2354static void vm_push_f64(struct VirtualMachine *vm, double value) {2669static void vm_push_f64(struct VirtualMachine *vm, double value) {
2355 uint64_t integer;2670 uint64_t integer;
2356 memcpy(&integer, &value, 8);2671 memcpy(&integer, &value, sizeof(integer));
2357 return vm_push_u64(vm, integer);2672 vm_push_u64(vm, integer);
2358}2673}
23592674
2360static uint32_t vm_pop_u32(struct VirtualMachine *vm) {2675static uint32_t vm_pop_u32(struct VirtualMachine *vm) {
2361 vm->stack_top -= 1;2676 vm->stack_top -= 1;
2362 return vm->stack[vm->stack_top];2677 return vm->stack[vm->stack_top + 0];
2363}2678}
23642679
2365static int32_t vm_pop_i32(struct VirtualMachine *vm) {2680static int32_t vm_pop_i32(struct VirtualMachine *vm) {
2366 return vm_pop_u32(vm);2681 return (int32_t)vm_pop_u32(vm);
2367}2682}
23682683
2369static uint64_t vm_pop_u64(struct VirtualMachine *vm) {2684static uint64_t vm_pop_u64(struct VirtualMachine *vm) {
2370 vm->stack_top -= 1;2685 vm->stack_top -= 2;
2371 return vm->stack[vm->stack_top];2686 return vm->stack[vm->stack_top + 0] | (uint64_t)vm->stack[vm->stack_top + 1] << 32;
2372}2687}
23732688
2374static int64_t vm_pop_i64(struct VirtualMachine *vm) {2689static int64_t vm_pop_i64(struct VirtualMachine *vm) {
2375 return vm_pop_u64(vm);2690 return (int64_t)vm_pop_u64(vm);
2376}2691}
23772692
2378static float vm_pop_f32(struct VirtualMachine *vm) {2693static float vm_pop_f32(struct VirtualMachine *vm) {
2379 uint32_t integer = vm_pop_u32(vm);2694 uint32_t integer = vm_pop_u32(vm);
2380 float result;2695 float result;
2381 memcpy(&result, &integer, 4);2696 memcpy(&result, &integer, sizeof(result));
2382 return result;2697 return result;
2383}2698}
23842699
2385static double vm_pop_f64(struct VirtualMachine *vm) {2700static double vm_pop_f64(struct VirtualMachine *vm) {
2386 uint64_t integer = vm_pop_u64(vm);2701 uint64_t integer = vm_pop_u64(vm);
2387 double result;2702 double result;
2388 memcpy(&result, &integer, 8);2703 memcpy(&result, &integer, sizeof(result));
2389 return result;2704 return result;
2390}2705}
23912706
2392static void vm_callImport(struct VirtualMachine *vm, struct Import import) {2707static void vm_callImport(struct VirtualMachine *vm, const struct Import *import) {
2393 switch (import.mod) {2708 switch (import->mod) {
2394 case ImpMod_wasi_snapshot_preview1: switch (import.name) {2709 case ImpMod_wasi_snapshot_preview1: switch (import->name) {
2395 case ImpName_fd_prestat_get:2710 case ImpName_fd_prestat_get:
2396 {2711 {
2397 uint32_t buf = vm_pop_u32(vm);2712 uint32_t buf = vm_pop_u32(vm);
...@@ -2613,21 +2928,14 @@ static void vm_callImport(struct VirtualMachine *vm, struct Import import) {...@@ -2613,21 +2928,14 @@ static void vm_callImport(struct VirtualMachine *vm, struct Import import) {
2613 }2928 }
2614}2929}
26152930
2616static void vm_call(struct VirtualMachine *vm, uint32_t fn_id) {2931static void vm_call(struct VirtualMachine *vm, const struct Function *func) {
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
2624 //struct TypeInfo *type_info = &vm->types[func->type_idx];2932 //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",2933 //fprintf(stderr, "enter fn_id: %u, param_count: %u, result_count: %u, locals_size: %u\n",
2626 // fn_id, type_info->param_count, type_info->result_count, func->locals_count);2934 // func->id, type_info->param_count, type_info->result_count, func->locals_size);
26272935
2628 // Push zeroed locals to stack2936 // Push zeroed locals to stack
2629 memset(vm->stack + vm->stack_top, 0, func->locals_count * sizeof(uint64_t));2937 memset(&vm->stack[vm->stack_top], 0, func->locals_size * sizeof(uint32_t));
2630 vm->stack_top += func->locals_count;2938 vm->stack_top += func->locals_size;
26312939
2632 vm_push_u32(vm, vm->pc.opcode);2940 vm_push_u32(vm, vm->pc.opcode);
2633 vm_push_u32(vm, vm->pc.operand);2941 vm_push_u32(vm, vm->pc.operand);
...@@ -2667,36 +2975,41 @@ static void vm_br_u64(struct VirtualMachine *vm) {...@@ -2667,36 +2975,41 @@ static void vm_br_u64(struct VirtualMachine *vm) {
2667}2975}
26682976
2669static void vm_return_void(struct VirtualMachine *vm) {2977static void vm_return_void(struct VirtualMachine *vm) {
2670 uint32_t ret_pc_offset = vm->operands[vm->pc.operand + 0];2978 uint32_t stack_adjust = vm->operands[vm->pc.operand + 0];
2671 uint32_t stack_adjust = vm->operands[vm->pc.operand + 1];2979 uint32_t frame_size = 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];
26752980
2676 vm->stack_top -= stack_adjust;2981 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;
2677}2986}
26782987
2679static void vm_return_u32(struct VirtualMachine *vm) {2988static void vm_return_u32(struct VirtualMachine *vm) {
2680 uint32_t ret_pc_offset = vm->operands[vm->pc.operand + 0];2989 uint32_t stack_adjust = vm->operands[vm->pc.operand + 0];
2681 uint32_t stack_adjust = vm->operands[vm->pc.operand + 1];2990 uint32_t frame_size = 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];
26852991
2686 uint32_t result = vm_pop_u32(vm);2992 uint32_t result = vm_pop_u32(vm);
2993
2687 vm->stack_top -= stack_adjust;2994 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;
2688 vm_push_u32(vm, result);2999 vm_push_u32(vm, result);
2689}3000}
26903001
2691static void vm_return_u64(struct VirtualMachine *vm) {3002static void vm_return_u64(struct VirtualMachine *vm) {
2692 uint32_t ret_pc_offset = vm->operands[vm->pc.operand + 0];3003 uint32_t stack_adjust = vm->operands[vm->pc.operand + 0];
2693 uint32_t stack_adjust = vm->operands[vm->pc.operand + 1];3004 uint32_t frame_size = 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];
26973005
2698 uint64_t result = vm_pop_u64(vm);3006 uint64_t result = vm_pop_u64(vm);
3007
2699 vm->stack_top -= stack_adjust;3008 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;
2700 vm_push_u64(vm, result);3013 vm_push_u64(vm, result);
2701}3014}
27023015
...@@ -2704,77 +3017,68 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2704,77 +3017,68 @@ static void vm_run(struct VirtualMachine *vm) {
2704 uint8_t *opcodes = vm->opcodes;3017 uint8_t *opcodes = vm->opcodes;
2705 uint32_t *operands = vm->operands;3018 uint32_t *operands = vm->operands;
2706 struct ProgramCounter *pc = &vm->pc;3019 struct ProgramCounter *pc = &vm->pc;
3020 uint32_t global_0 = vm->globals[0];
2707 for (;;) {3021 for (;;) {
2708 enum Op op = opcodes[pc->opcode];3022 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);
2709 pc->opcode += 1;3027 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 //}
2714 switch (op) {3028 switch (op) {
2715 case Op_unreachable:3029 case Op_unreachable:
2716 panic("unreachable reached");3030 panic("unreachable reached");
2717
2718 case Op_br_void:3031 case Op_br_void:
2719 vm_br_void(vm);3032 vm_br_void(vm);
2720 break;3033 break;
2721
2722 case Op_br_32:3034 case Op_br_32:
2723 vm_br_u32(vm);3035 vm_br_u32(vm);
2724 break;3036 break;
2725
2726 case Op_br_64:3037 case Op_br_64:
2727 vm_br_u64(vm);3038 vm_br_u64(vm);
2728 break;3039 break;
27293040 case Op_br_nez_void:
2730 case Op_br_if_nez_void:
2731 if (vm_pop_u32(vm) != 0) {3041 if (vm_pop_u32(vm) != 0) {
2732 vm_br_void(vm);3042 vm_br_void(vm);
2733 } else {3043 } else {
2734 pc->operand += 3;3044 pc->operand += 3;
2735 }3045 }
2736 break;3046 break;
27373047 case Op_br_nez_32:
2738 case Op_br_if_nez_32:
2739 if (vm_pop_u32(vm) != 0) {3048 if (vm_pop_u32(vm) != 0) {
2740 vm_br_u32(vm);3049 vm_br_u32(vm);
2741 } else {3050 } else {
2742 pc->operand += 3;3051 pc->operand += 3;
2743 }3052 }
2744 break;3053 break;
27453054 case Op_br_nez_64:
2746 case Op_br_if_nez_64:
2747 if (vm_pop_u32(vm) != 0) {3055 if (vm_pop_u32(vm) != 0) {
2748 vm_br_u64(vm);3056 vm_br_u64(vm);
2749 } else {3057 } else {
2750 pc->operand += 3;3058 pc->operand += 3;
2751 }3059 }
2752 break;3060 break;
27533061 case Op_br_eqz_void:
2754 case Op_br_if_eqz_void:
2755 if (vm_pop_u32(vm) == 0) {3062 if (vm_pop_u32(vm) == 0) {
2756 vm_br_void(vm);3063 vm_br_void(vm);
2757 } else {3064 } else {
2758 pc->operand += 3;3065 pc->operand += 3;
2759 }3066 }
2760 break;3067 break;
27613068 case Op_br_eqz_32:
2762 case Op_br_if_eqz_32:
2763 if (vm_pop_u32(vm) == 0) {3069 if (vm_pop_u32(vm) == 0) {
2764 vm_br_u32(vm);3070 vm_br_u32(vm);
2765 } else {3071 } else {
2766 pc->operand += 3;3072 pc->operand += 3;
2767 }3073 }
2768 break;3074 break;
27693075 case Op_br_eqz_64:
2770 case Op_br_if_eqz_64:
2771 if (vm_pop_u32(vm) == 0) {3076 if (vm_pop_u32(vm) == 0) {
2772 vm_br_u64(vm);3077 vm_br_u64(vm);
2773 } else {3078 } else {
2774 pc->operand += 3;3079 pc->operand += 3;
2775 }3080 }
2776 break;3081 break;
2777
2778 case Op_br_table_void:3082 case Op_br_table_void:
2779 {3083 {
2780 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);3084 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);
...@@ -2782,7 +3086,6 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2782,7 +3086,6 @@ static void vm_run(struct VirtualMachine *vm) {
2782 vm_br_void(vm);3086 vm_br_void(vm);
2783 }3087 }
2784 break;3088 break;
2785
2786 case Op_br_table_32:3089 case Op_br_table_32:
2787 {3090 {
2788 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);3091 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);
...@@ -2790,7 +3093,6 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2790,7 +3093,6 @@ static void vm_run(struct VirtualMachine *vm) {
2790 vm_br_u32(vm);3093 vm_br_u32(vm);
2791 }3094 }
2792 break;3095 break;
2793
2794 case Op_br_table_64:3096 case Op_br_table_64:
2795 {3097 {
2796 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);3098 uint32_t index = min_u32(vm_pop_u32(vm), operands[pc->operand]);
...@@ -2798,32 +3100,45 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2798,32 +3100,45 @@ static void vm_run(struct VirtualMachine *vm) {
2798 vm_br_u64(vm);3100 vm_br_u64(vm);
2799 }3101 }
2800 break;3102 break;
2801
2802 case Op_return_void:3103 case Op_return_void:
2803 vm_return_void(vm);3104 vm_return_void(vm);
2804 break;3105 break;
2805
2806 case Op_return_32:3106 case Op_return_32:
2807 vm_return_u32(vm);3107 vm_return_u32(vm);
2808 break;3108 break;
2809
2810 case Op_return_64:3109 case Op_return_64:
2811 vm_return_u64(vm);3110 vm_return_u64(vm);
2812 break;3111 break;
28133112 case Op_call_import:
2814 case Op_call: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:
2815 {3120 {
2816 uint32_t fn_id = operands[pc->operand];3121 uint32_t func_idx = operands[pc->operand];
2817 pc->operand += 1;3122 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]);
2819 }3133 }
2820 break;3134 break;
28213135
2822 case Op_drop_32:3136 case Op_drop_32:
2823 case Op_drop_64:
2824 vm->stack_top -= 1;3137 vm->stack_top -= 1;
2825 break;3138 break;
28263139 case Op_drop_64:
3140 vm->stack_top -= 2;
3141 break;
2827 case Op_select_32:3142 case Op_select_32:
2828 {3143 {
2829 uint32_t c = vm_pop_u32(vm);3144 uint32_t c = vm_pop_u32(vm);
...@@ -2833,7 +3148,6 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2833,7 +3148,6 @@ static void vm_run(struct VirtualMachine *vm) {
2833 vm_push_u32(vm, result);3148 vm_push_u32(vm, result);
2834 }3149 }
2835 break;3150 break;
2836
2837 case Op_select_64:3151 case Op_select_64:
2838 {3152 {
2839 uint32_t c = vm_pop_u32(vm);3153 uint32_t c = vm_pop_u32(vm);
...@@ -2846,49 +3160,53 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2846,49 +3160,53 @@ static void vm_run(struct VirtualMachine *vm) {
28463160
2847 case Op_local_get_32:3161 case Op_local_get_32:
2848 {3162 {
2849 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];3163 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
2850 pc->operand += 1;3164 pc->operand += 1;
2851 vm_push_u32(vm, *local);3165 vm_push_u32(vm, *local);
2852 }3166 }
2853 break;3167 break;
2854
2855 case Op_local_get_64:3168 case Op_local_get_64:
2856 {3169 {
2857 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];3170 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
2858 pc->operand += 1;3171 pc->operand += 1;
2859 vm_push_u64(vm, *local);3172 vm_push_u64(vm, local[0] | (uint64_t)local[1] << 32);
2860 }3173 }
2861 break;3174 break;
2862
2863 case Op_local_set_32:3175 case Op_local_set_32:
2864 {3176 {
2865 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];3177 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
2866 pc->operand += 1;3178 pc->operand += 1;
2867 *local = vm_pop_u32(vm);3179 *local = vm_pop_u32(vm);
2868 }3180 }
2869 break;3181 break;
2870
2871 case Op_local_set_64:3182 case Op_local_set_64:
2872 {3183 {
2873 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];3184 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
2874 pc->operand += 1;3185 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);
2876 }3189 }
2877 break;3190 break;
2878
2879 case Op_local_tee_32:3191 case Op_local_tee_32:
2880 case Op_local_tee_64:
2881 {3192 {
2882 uint64_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];3193 uint32_t *local = &vm->stack[vm->stack_top - operands[pc->operand]];
2883 pc->operand += 1;3194 pc->operand += 1;
2884 *local = vm->stack[vm->stack_top - 1];3195 *local = vm->stack[vm->stack_top - 1];
2885 }3196 }
2886 break;3197 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
2888 case Op_global_get_0_32:3207 case Op_global_get_0_32:
2889 vm_push_u32(vm, vm->globals[0]);3208 vm_push_u32(vm, global_0);
2890 break;3209 break;
2891
2892 case Op_global_get_32:3210 case Op_global_get_32:
2893 {3211 {
2894 uint32_t idx = operands[pc->operand];3212 uint32_t idx = operands[pc->operand];
...@@ -2896,11 +3214,9 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2896,11 +3214,9 @@ static void vm_run(struct VirtualMachine *vm) {
2896 vm_push_u32(vm, vm->globals[idx]);3214 vm_push_u32(vm, vm->globals[idx]);
2897 }3215 }
2898 break;3216 break;
2899
2900 case Op_global_set_0_32:3217 case Op_global_set_0_32:
2901 vm->globals[0] = vm_pop_u32(vm);3218 global_0 = vm_pop_u32(vm);
2902 break;3219 break;
2903
2904 case Op_global_set_32:3220 case Op_global_set_32:
2905 {3221 {
2906 uint32_t idx = operands[pc->operand];3222 uint32_t idx = operands[pc->operand];
...@@ -2909,1140 +3225,850 @@ static void vm_run(struct VirtualMachine *vm) {...@@ -2909,1140 +3225,850 @@ static void vm_run(struct VirtualMachine *vm) {
2909 }3225 }
2910 break;3226 break;
29113227
2912 case Op_const_32:3228 case Op_load_0_8:
2913 {3229 {
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];
2915 pc->operand += 1;3237 pc->operand += 1;
2916 vm_push_i32(vm, x);3238 vm_push_u32(vm, (uint8_t)vm->memory[address]);
2917 }3239 }
2918 break;3240 break;
29193241 case Op_load_0_16:
2920 case Op_const_64:
2921 {3242 {
2922 uint64_t x = ((uint64_t)operands[pc->operand]) |3243 uint32_t address = vm_pop_u32(vm);
2923 (((uint64_t)operands[pc->operand + 1]) << 32);3244 vm_push_u32(vm, read_u16_le(&vm->memory[address]));
2924 pc->operand += 2;
2925 vm_push_i64(vm, x);
2926 }3245 }
2927 break;3246 break;
29283247 case Op_load_16:
2929 case Op_add_32:
2930 {3248 {
2931 uint32_t rhs = vm_pop_u32(vm);3249 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
2932 uint32_t lhs = vm_pop_u32(vm);3250 pc->operand += 1;
2933 vm_push_u32(vm, lhs + rhs);3251 vm_push_u32(vm, read_u16_le(&vm->memory[address]));
2934 }3252 }
2935 break;3253 break;
29363254 case Op_load_0_32:
2937 case Op_and_32:
2938 {3255 {
2939 uint32_t rhs = vm_pop_u32(vm);3256 uint32_t address = vm_pop_u32(vm);
2940 uint32_t lhs = vm_pop_u32(vm);3257 vm_push_u32(vm, read_u32_le(&vm->memory[address]));
2941 vm_push_u32(vm, lhs & rhs);
2942 }3258 }
2943 break;3259 break;
29443260 case Op_load_32:
2945 case Op_wasm:
2946 {3261 {
2947 enum WasmOp wasm_op = opcodes[pc->opcode];3262 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
2948 //fprintf(stderr, "op2=%x\n", wasm_op);3263 pc->operand += 1;
2949 pc->opcode += 1;3264 vm_push_u32(vm, read_u32_le(&vm->memory[address]));
2950 switch (wasm_op) {3265 }
2951 case WasmOp_unreachable:3266 break;
2952 case WasmOp_nop:3267 case Op_load_0_64:
2953 case WasmOp_block:3268 {
2954 case WasmOp_loop:3269 uint32_t address = vm_pop_u32(vm);
2955 case WasmOp_if:3270 vm_push_u64(vm, read_u64_le(&vm->memory[address]));
2956 case WasmOp_else:3271 }
2957 case WasmOp_end:3272 break;
2958 case WasmOp_br:3273 case Op_load_64:
2959 case WasmOp_br_if:3274 {
2960 case WasmOp_br_table:3275 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
2961 case WasmOp_return:3276 pc->operand += 1;
2962 case WasmOp_call:3277 vm_push_u64(vm, read_u64_le(&vm->memory[address]));
2963 case WasmOp_drop:3278 }
2964 case WasmOp_select:3279 break;
2965 case WasmOp_local_get:3280 case Op_store_0_8:
2966 case WasmOp_local_set:3281 {
2967 case WasmOp_local_tee:3282 uint8_t value = (uint8_t)vm_pop_u32(vm);
2968 case WasmOp_global_get:3283 uint32_t address = vm_pop_u32(vm);
2969 case WasmOp_global_set:3284 vm->memory[address] = value;
2970 case WasmOp_i32_const:3285 }
2971 case WasmOp_i64_const:3286 break;
2972 case WasmOp_f32_const:3287 case Op_store_8:
2973 case WasmOp_f64_const:3288 {
2974 case WasmOp_i32_add:3289 uint8_t value = (uint8_t)vm_pop_u32(vm);
2975 case WasmOp_i32_and:3290 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
2976 case WasmOp_i32_reinterpret_f32:3291 pc->operand += 1;
2977 case WasmOp_i64_reinterpret_f64:3292 vm->memory[address] = value;
2978 case WasmOp_f32_reinterpret_i32:3293 }
2979 case WasmOp_f64_reinterpret_i64:3294 break;
2980 case WasmOp_prefixed:3295 case Op_store_0_16:
2981 panic("not produced by decodeCode");3296 {
2982 break;3297 uint16_t value = (uint16_t)vm_pop_u32(vm);
29833298 uint32_t address = vm_pop_u32(vm);
2984 case WasmOp_call_indirect:3299 write_u16_le(&vm->memory[address], value);
2985 {3300 }
2986 uint32_t fn_id = vm->table[vm_pop_u32(vm)];3301 break;
2987 vm_call(vm, fn_id);3302 case Op_store_16:
2988 }3303 {
2989 break;3304 uint16_t value = (uint16_t)vm_pop_u32(vm);
2990 case WasmOp_i32_load:3305 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
2991 {3306 pc->operand += 1;
2992 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3307 write_u16_le(&vm->memory[address], value);
2993 pc->operand += 1;3308 }
2994 vm_push_u32(vm, read_u32_le(vm->memory + offset));3309 break;
2995 }3310 case Op_store_0_32:
2996 break;3311 {
2997 case WasmOp_i64_load:3312 uint32_t value = vm_pop_u32(vm);
2998 {3313 uint32_t address = vm_pop_u32(vm);
2999 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3314 write_u32_le(&vm->memory[address], value);
3000 pc->operand += 1;3315 }
3001 vm_push_u64(vm, read_u64_le(vm->memory + offset));3316 break;
3002 }3317 case Op_store_32:
3003 break;3318 {
3004 case WasmOp_f32_load:3319 uint32_t value = vm_pop_u32(vm);
3005 {3320 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3006 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3321 pc->operand += 1;
3007 pc->operand += 1;3322 write_u32_le(&vm->memory[address], value);
3008 uint32_t integer = read_u32_le(vm->memory + offset);3323 }
3009 vm_push_u32(vm, integer);3324 break;
3010 }3325 case Op_store_0_64:
3011 break;3326 {
3012 case WasmOp_f64_load:3327 uint64_t value = vm_pop_u64(vm);
3013 {3328 uint32_t address = vm_pop_u32(vm);
3014 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3329 write_u64_le(&vm->memory[address], value);
3015 pc->operand += 1;3330 }
3016 uint64_t integer = read_u64_le(vm->memory + offset);3331 break;
3017 vm_push_u64(vm, integer);3332 case Op_store_64:
3018 }3333 {
3019 break;3334 uint64_t value = vm_pop_u64(vm);
3020 case WasmOp_i32_load8_s:3335 uint32_t address = vm_pop_u32(vm) + operands[pc->operand];
3021 {3336 pc->operand += 1;
3022 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3337 write_u64_le(&vm->memory[address], value);
3023 pc->operand += 1;3338 }
3024 vm_push_i32(vm, (int8_t)vm->memory[offset]);3339 break;
3025 }3340 case Op_mem_size:
3026 break;3341 vm_push_u32(vm, vm->memory_len / wasm_page_size);
3027 case WasmOp_i32_load8_u:3342 break;
3028 {3343 case Op_mem_grow:
3029 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3344 {
3030 pc->operand += 1;3345 uint32_t page_count = vm_pop_u32(vm);
3031 vm_push_u32(vm, (uint8_t)vm->memory[offset]);3346 uint32_t old_page_count = vm->memory_len / wasm_page_size;
3032 }3347 uint32_t new_len = vm->memory_len + page_count * wasm_page_size;
3033 break;3348 if (new_len > max_memory) {
3034 case WasmOp_i32_load16_s:3349 vm_push_i32(vm, -1);
3035 {3350 } else {
3036 uint32_t offset = operands[pc->operand] + vm_pop_u32(vm);3351 vm->memory_len = new_len;
3037 pc->operand += 1;3352 vm_push_u32(vm, old_page_count);
3038 int16_t integer = read_i16_le(vm->memory + offset);3353 }
3039 vm_push_i32(vm, integer);3354 }
3040 }3355 break;
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;
34233356
3424 case WasmOp_i32_clz:3357 case Op_const_0_32:
3425 {3358 vm_push_i32(vm, 0);
3426 uint32_t operand = vm_pop_u32(vm);3359 break;
3427 uint32_t result = (operand == 0) ? 32 : __builtin_clz(operand);3360 case Op_const_0_64:
3428 vm_push_u32(vm, result);3361 vm_push_i64(vm, 0);
3429 }3362 break;
3430 break;3363 case Op_const_1_32:
3431 case WasmOp_i32_ctz:3364 vm_push_i32(vm, 1);
3432 {3365 break;
3433 uint32_t operand = vm_pop_u32(vm);3366 case Op_const_1_64:
3434 uint32_t result = (operand == 0) ? 32 : __builtin_ctz(operand);3367 vm_push_i64(vm, 1);
3435 vm_push_u32(vm, result);3368 break;
3436 }3369 case Op_const_32:
3437 break;3370 {
3438 case WasmOp_i32_popcnt:3371 uint32_t value = operands[pc->operand];
3439 {3372 pc->operand += 1;
3440 uint32_t operand = vm_pop_u32(vm);3373 vm_push_i32(vm, value);
3441 uint32_t result = __builtin_popcount(operand);3374 }
3442 vm_push_u32(vm, result);3375 break;
3443 }3376 case Op_const_64:
3444 break;3377 {
3445 case WasmOp_i32_sub:3378 uint64_t value = ((uint64_t)operands[pc->operand]) |
3446 {3379 (((uint64_t)operands[pc->operand + 1]) << 32);
3447 uint32_t rhs = vm_pop_u32(vm);3380 pc->operand += 2;
3448 uint32_t lhs = vm_pop_u32(vm);3381 vm_push_i64(vm, value);
3449 vm_push_u32(vm, lhs - rhs);3382 }
3450 }3383 break;
3451 break;3384 case Op_const_umax_32:
3452 case WasmOp_i32_mul:3385 vm_push_i32(vm, -1);
3453 {3386 break;
3454 uint32_t rhs = vm_pop_u32(vm);3387 case Op_const_umax_64:
3455 uint32_t lhs = vm_pop_u32(vm);3388 vm_push_i64(vm, -1);
3456 vm_push_u32(vm, lhs * rhs);3389 break;
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;
35363390
3537 case WasmOp_i64_clz:3391 case Op_eqz_32:
3538 {3392 {
3539 uint64_t operand = vm_pop_u64(vm);3393 uint32_t lhs = vm_pop_u32(vm);
3540 uint64_t result = (operand == 0) ? 64 : __builtin_clzll(operand);3394 vm_push_u32(vm, lhs == 0);
3541 vm_push_u64(vm, result);3395 }
3542 }3396 break;
3543 break;3397 case Op_eq_32:
3544 case WasmOp_i64_ctz:3398 {
3545 {3399 uint32_t rhs = vm_pop_u32(vm);
3546 uint64_t operand = vm_pop_u64(vm);3400 uint32_t lhs = vm_pop_u32(vm);
3547 uint64_t result = (operand == 0) ? 64 : __builtin_ctzll(operand);3401 vm_push_u32(vm, lhs == rhs);
3548 vm_push_u64(vm, result);3402 }
3549 }3403 break;
3550 break;3404 case Op_ne_32:
3551 case WasmOp_i64_popcnt:3405 {
3552 {3406 uint32_t rhs = vm_pop_u32(vm);
3553 uint64_t operand = vm_pop_u64(vm);3407 uint32_t lhs = vm_pop_u32(vm);
3554 uint64_t result = __builtin_popcountll(operand);3408 vm_push_u32(vm, lhs != rhs);
3555 vm_push_u64(vm, result);3409 }
3556 }3410 break;
3557 break;3411 case Op_slt_32:
3558 case WasmOp_i64_add:3412 {
3559 {3413 int32_t rhs = vm_pop_i32(vm);
3560 uint64_t rhs = vm_pop_u64(vm);3414 int32_t lhs = vm_pop_i32(vm);
3561 uint64_t lhs = vm_pop_u64(vm);3415 vm_push_u32(vm, lhs < rhs);
3562 vm_push_u64(vm, lhs + rhs);3416 }
3563 }3417 break;
3564 break;3418 case Op_ult_32:
3565 case WasmOp_i64_sub:3419 {
3566 {3420 uint32_t rhs = vm_pop_u32(vm);
3567 uint64_t rhs = vm_pop_u64(vm);3421 uint32_t lhs = vm_pop_u32(vm);
3568 uint64_t lhs = vm_pop_u64(vm);3422 vm_push_u32(vm, lhs < rhs);
3569 vm_push_u64(vm, lhs - rhs);3423 }
3570 }3424 break;
3571 break;3425 case Op_sgt_32:
3572 case WasmOp_i64_mul:3426 {
3573 {3427 int32_t rhs = vm_pop_i32(vm);
3574 uint64_t rhs = vm_pop_u64(vm);3428 int32_t lhs = vm_pop_i32(vm);
3575 uint64_t lhs = vm_pop_u64(vm);3429 vm_push_u32(vm, lhs > rhs);
3576 vm_push_u64(vm, lhs * rhs);3430 }
3577 }3431 break;
3578 break;3432 case Op_ugt_32:
3579 case WasmOp_i64_div_s:3433 {
3580 {3434 uint32_t rhs = vm_pop_u32(vm);
3581 int64_t rhs = vm_pop_i64(vm);3435 uint32_t lhs = vm_pop_u32(vm);
3582 int64_t lhs = vm_pop_i64(vm);3436 vm_push_u32(vm, lhs > rhs);
3583 vm_push_i64(vm, lhs / rhs);3437 }
3584 }3438 break;
3585 break;3439 case Op_sle_32:
3586 case WasmOp_i64_div_u:3440 {
3587 {3441 int32_t rhs = vm_pop_i32(vm);
3588 uint64_t rhs = vm_pop_u64(vm);3442 int32_t lhs = vm_pop_i32(vm);
3589 uint64_t lhs = vm_pop_u64(vm);3443 vm_push_u32(vm, lhs <= rhs);
3590 vm_push_u64(vm, lhs / rhs);3444 }
3591 }3445 break;
3592 break;3446 case Op_ule_32:
3593 case WasmOp_i64_rem_s:3447 {
3594 {3448 uint32_t rhs = vm_pop_u32(vm);
3595 int64_t rhs = vm_pop_i64(vm);3449 uint32_t lhs = vm_pop_u32(vm);
3596 int64_t lhs = vm_pop_i64(vm);3450 vm_push_u32(vm, lhs <= rhs);
3597 vm_push_i64(vm, lhs % rhs);3451 }
3598 }3452 break;
3599 break;3453 case Op_sge_32:
3600 case WasmOp_i64_rem_u:3454 {
3601 {3455 int32_t rhs = vm_pop_i32(vm);
3602 uint64_t rhs = vm_pop_u64(vm);3456 int32_t lhs = vm_pop_i32(vm);
3603 uint64_t lhs = vm_pop_u64(vm);3457 vm_push_u32(vm, lhs >= rhs);
3604 vm_push_u64(vm, lhs % rhs);3458 }
3605 }3459 break;
3606 break;3460 case Op_uge_32:
3607 case WasmOp_i64_and:3461 {
3608 {3462 uint32_t rhs = vm_pop_u32(vm);
3609 uint64_t rhs = vm_pop_u64(vm);3463 uint32_t lhs = vm_pop_u32(vm);
3610 uint64_t lhs = vm_pop_u64(vm);3464 vm_push_u32(vm, lhs >= rhs);
3611 vm_push_u64(vm, lhs & rhs);3465 }
3612 }3466 break;
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;
36633467
3664 case WasmOp_f32_abs:3468 case Op_eqz_64:
3665 {3469 {
3666 vm_push_f32(vm, fabsf(vm_pop_f32(vm)));3470 uint64_t lhs = vm_pop_u64(vm);
3667 }3471 vm_push_u32(vm, lhs == 0);
3668 break;3472 }
3669 case WasmOp_f32_neg:3473 break;
3670 {3474 case Op_eq_64:
3671 vm_push_f32(vm, -vm_pop_f32(vm));3475 {
3672 }3476 uint64_t rhs = vm_pop_u64(vm);
3673 break;3477 uint64_t lhs = vm_pop_u64(vm);
3674 case WasmOp_f32_ceil:3478 vm_push_u32(vm, lhs == rhs);
3675 {3479 }
3676 vm_push_f32(vm, ceilf(vm_pop_f32(vm)));3480 break;
3677 }3481 case Op_ne_64:
3678 break;3482 {
3679 case WasmOp_f32_floor:3483 uint64_t rhs = vm_pop_u64(vm);
3680 {3484 uint64_t lhs = vm_pop_u64(vm);
3681 vm_push_f32(vm, floorf(vm_pop_f32(vm)));3485 vm_push_u32(vm, lhs != rhs);
3682 }3486 }
3683 break;3487 break;
3684 case WasmOp_f32_trunc:3488 case Op_slt_64:
3685 {3489 {
3686 vm_push_f32(vm, truncf(vm_pop_f32(vm)));3490 int64_t rhs = vm_pop_i64(vm);
3687 }3491 int64_t lhs = vm_pop_i64(vm);
3688 break;3492 vm_push_u32(vm, lhs < rhs);
3689 case WasmOp_f32_nearest:3493 }
3690 {3494 break;
3691 vm_push_f32(vm, roundf(vm_pop_f32(vm)));3495 case Op_ult_64:
3692 }3496 {
3693 break;3497 uint64_t rhs = vm_pop_u64(vm);
3694 case WasmOp_f32_sqrt:3498 uint64_t lhs = vm_pop_u64(vm);
3695 {3499 vm_push_u32(vm, lhs < rhs);
3696 vm_push_f32(vm, sqrtf(vm_pop_f32(vm)));3500 }
3697 }3501 break;
3698 break;3502 case Op_sgt_64:
3699 case WasmOp_f32_add:3503 {
3700 {3504 int64_t rhs = vm_pop_i64(vm);
3701 float rhs = vm_pop_f32(vm);3505 int64_t lhs = vm_pop_i64(vm);
3702 float lhs = vm_pop_f32(vm);3506 vm_push_u32(vm, lhs > rhs);
3703 vm_push_f32(vm, lhs + rhs);3507 }
3704 }3508 break;
3705 break;3509 case Op_ugt_64:
3706 case WasmOp_f32_sub:3510 {
3707 {3511 uint64_t rhs = vm_pop_u64(vm);
3708 float rhs = vm_pop_f32(vm);3512 uint64_t lhs = vm_pop_u64(vm);
3709 float lhs = vm_pop_f32(vm);3513 vm_push_u32(vm, lhs > rhs);
3710 vm_push_f32(vm, lhs - rhs);3514 }
3711 }3515 break;
3712 break;3516 case Op_sle_64:
3713 case WasmOp_f32_mul:3517 {
3714 {3518 int64_t rhs = vm_pop_i64(vm);
3715 float rhs = vm_pop_f32(vm);3519 int64_t lhs = vm_pop_i64(vm);
3716 float lhs = vm_pop_f32(vm);3520 vm_push_u32(vm, lhs <= rhs);
3717 vm_push_f32(vm, lhs * rhs);3521 }
3718 }3522 break;
3719 break;3523 case Op_ule_64:
3720 case WasmOp_f32_div:3524 {
3721 {3525 uint64_t rhs = vm_pop_u64(vm);
3722 float rhs = vm_pop_f32(vm);3526 uint64_t lhs = vm_pop_u64(vm);
3723 float lhs = vm_pop_f32(vm);3527 vm_push_u32(vm, lhs <= rhs);
3724 vm_push_f32(vm, lhs / rhs);3528 }
3725 }3529 break;
3726 break;3530 case Op_sge_64:
3727 case WasmOp_f32_min:3531 {
3728 {3532 int64_t rhs = vm_pop_i64(vm);
3729 float rhs = vm_pop_f32(vm);3533 int64_t lhs = vm_pop_i64(vm);
3730 float lhs = vm_pop_f32(vm);3534 vm_push_u32(vm, lhs >= rhs);
3731 vm_push_f32(vm, (lhs < rhs) ? lhs : rhs);3535 }
3732 }3536 break;
3733 break;3537 case Op_uge_64:
3734 case WasmOp_f32_max:3538 {
3735 {3539 uint64_t rhs = vm_pop_u64(vm);
3736 float rhs = vm_pop_f32(vm);3540 uint64_t lhs = vm_pop_u64(vm);
3737 float lhs = vm_pop_f32(vm);3541 vm_push_u32(vm, lhs >= rhs);
3738 vm_push_f32(vm, (lhs > rhs) ? lhs : rhs);3542 }
3739 }3543 break;
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;
38323544
3833 case WasmOp_i32_wrap_i64:3545 case Op_feq_32:
3834 {3546 {
3835 uint64_t operand = vm_pop_u64(vm);3547 float rhs = vm_pop_f32(vm);
3836 vm_push_u32(vm, operand);3548 float lhs = vm_pop_f32(vm);
3837 }3549 vm_push_u32(vm, lhs == rhs);
3838 break;3550 }
3839 case WasmOp_i32_trunc_f32_s:3551 break;
3840 {3552 case Op_fne_32:
3841 float operand = vm_pop_f32(vm);3553 {
3842 vm_push_i32(vm, truncf(operand));3554 float rhs = vm_pop_f32(vm);
3843 }3555 float lhs = vm_pop_f32(vm);
3844 break;3556 vm_push_u32(vm, lhs != rhs);
3845 case WasmOp_i32_trunc_f32_u:3557 }
3846 {3558 break;
3847 float operand = vm_pop_f32(vm);3559 case Op_flt_32:
3848 vm_push_u32(vm, truncf(operand));3560 {
3849 }3561 float rhs = vm_pop_f32(vm);
3850 break;3562 float lhs = vm_pop_f32(vm);
3851 case WasmOp_i32_trunc_f64_s:3563 vm_push_u32(vm, lhs < rhs);
3852 {3564 }
3853 double operand = vm_pop_f64(vm);3565 break;
3854 vm_push_i32(vm, trunc(operand));3566 case Op_fgt_32:
3855 }3567 {
3856 break;3568 float rhs = vm_pop_f32(vm);
3857 case WasmOp_i32_trunc_f64_u:3569 float lhs = vm_pop_f32(vm);
3858 {3570 vm_push_u32(vm, lhs > rhs);
3859 double operand = vm_pop_f64(vm);3571 }
3860 vm_push_u32(vm, trunc(operand));3572 break;
3861 }3573 case Op_fle_32:
3862 break;3574 {
3863 case WasmOp_i64_extend_i32_s:3575 float rhs = vm_pop_f32(vm);
3864 {3576 float lhs = vm_pop_f32(vm);
3865 int32_t operand = vm_pop_i32(vm);3577 vm_push_u32(vm, lhs <= rhs);
3866 vm_push_i64(vm, operand);3578 }
3867 }3579 break;
3868 break;3580 case Op_fge_32:
3869 case WasmOp_i64_extend_i32_u:3581 {
3870 {3582 float rhs = vm_pop_f32(vm);
3871 uint64_t operand = vm_pop_u64(vm);3583 float lhs = vm_pop_f32(vm);
3872 vm_push_u64(vm, operand);3584 vm_push_u32(vm, lhs >= rhs);
3873 }3585 }
3874 break;3586 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;
39493587
3950 case WasmOp_i32_extend8_s:3588 case Op_feq_64:
3951 {3589 {
3952 int8_t operand = vm_pop_i32(vm);3590 double rhs = vm_pop_f64(vm);
3953 vm_push_i32(vm, operand);3591 double lhs = vm_pop_f64(vm);
3954 }3592 vm_push_u32(vm, lhs == rhs);
3955 break;3593 }
3956 case WasmOp_i32_extend16_s:3594 break;
3957 {3595 case Op_fne_64:
3958 int16_t operand = vm_pop_i32(vm);3596 {
3959 vm_push_i32(vm, operand);3597 double rhs = vm_pop_f64(vm);
3960 }3598 double lhs = vm_pop_f64(vm);
3961 break;3599 vm_push_u32(vm, lhs != rhs);
3962 case WasmOp_i64_extend8_s:3600 }
3963 {3601 break;
3964 int8_t operand = vm_pop_i64(vm);3602 case Op_flt_64:
3965 vm_push_i64(vm, operand);3603 {
3966 }3604 double rhs = vm_pop_f64(vm);
3967 break;3605 double lhs = vm_pop_f64(vm);
3968 case WasmOp_i64_extend16_s:3606 vm_push_u32(vm, lhs <= rhs);
3969 {3607 }
3970 int16_t operand = vm_pop_i64(vm);3608 break;
3971 vm_push_i64(vm, operand);3609 case Op_fgt_64:
3972 }3610 {
3973 break;3611 double rhs = vm_pop_f64(vm);
3974 case WasmOp_i64_extend32_s:3612 double lhs = vm_pop_f64(vm);
3975 {3613 vm_push_u32(vm, lhs > rhs);
3976 int32_t operand = vm_pop_i64(vm);3614 }
3977 vm_push_i64(vm, operand);3615 break;
3978 }3616 case Op_fle_64:
3979 break;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:3631 case Op_clz_32:
3982 panic("unreachable");3632 {
3983 }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));
3984 }3755 }
3985 break;3756 break;
39863757
3987 case Op_wasm_prefixed:3758 case Op_clz_64:
3988 {3759 {
3989 enum WasmPrefixedOp wasm_prefixed_op = opcodes[pc->opcode];3760 uint64_t operand = vm_pop_u64(vm);
3990 pc->opcode += 1;3761 uint64_t result = (operand == 0) ? 64 : __builtin_clzll(operand);
3991 switch (wasm_prefixed_op) {3762 vm_push_u64(vm, result);
3992 case WasmPrefixedOp_i32_trunc_sat_f32_s:3763 }
3993 panic("unreachable");3764 break;
3994 case WasmPrefixedOp_i32_trunc_sat_f32_u:3765 case Op_ctz_64:
3995 panic("unreachable");3766 {
3996 case WasmPrefixedOp_i32_trunc_sat_f64_s:3767 uint64_t operand = vm_pop_u64(vm);
3997 panic("unreachable");3768 uint64_t result = (operand == 0) ? 64 : __builtin_ctzll(operand);
3998 case WasmPrefixedOp_i32_trunc_sat_f64_u:3769 vm_push_u64(vm, result);
3999 panic("unreachable");3770 }
4000 case WasmPrefixedOp_i64_trunc_sat_f32_s:3771 break;
4001 panic("unreachable");3772 case Op_popcnt_64:
4002 case WasmPrefixedOp_i64_trunc_sat_f32_u:3773 {
4003 panic("unreachable");3774 uint64_t operand = vm_pop_u64(vm);
4004 case WasmPrefixedOp_i64_trunc_sat_f64_s:3775 uint64_t result = __builtin_popcountll(operand);
4005 panic("unreachable");3776 vm_push_u64(vm, result);
4006 case WasmPrefixedOp_i64_trunc_sat_f64_u:3777 }
4007 panic("unreachable");3778 break;
4008 case WasmPrefixedOp_memory_init:3779 case Op_add_64:
4009 panic("unreachable");3780 {
4010 case WasmPrefixedOp_data_drop:3781 uint64_t rhs = vm_pop_u64(vm);
4011 panic("unreachable");3782 uint64_t lhs = vm_pop_u64(vm);
40123783 vm_push_u64(vm, lhs + rhs);
4013 case WasmPrefixedOp_memory_copy:3784 }
4014 {3785 break;
4015 uint32_t n = vm_pop_u32(vm);3786 case Op_sub_64:
4016 uint32_t src = vm_pop_u32(vm);3787 {
4017 uint32_t dest = vm_pop_u32(vm);3788 uint64_t rhs = vm_pop_u64(vm);
4018 assert(dest + n <= vm->memory_len);3789 uint64_t lhs = vm_pop_u64(vm);
4019 assert(src + n <= vm->memory_len);3790 vm_push_u64(vm, lhs - rhs);
4020 assert(src + n <= dest || dest + n <= src); // overlapping3791 }
4021 memcpy(vm->memory + dest, vm->memory + src, n);3792 break;
4022 }3793 case Op_mul_64:
4023 break;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:3885 case Op_fabs_32:
4026 {3886 vm_push_f32(vm, fabsf(vm_pop_f32(vm)));
4027 uint32_t n = vm_pop_u32(vm);3887 break;
4028 uint8_t value = vm_pop_u32(vm);3888 case Op_fneg_32:
4029 uint32_t dest = vm_pop_u32(vm);3889 vm_push_f32(vm, -vm_pop_f32(vm));
4030 assert(dest + n <= vm->memory_len);3890 break;
4031 memset(vm->memory + dest, value, n);3891 case Op_ceil_32:
4032 }3892 vm_push_f32(vm, ceilf(vm_pop_f32(vm)));
4033 break;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");3956 case Op_fabs_64:
4036 case WasmPrefixedOp_elem_drop: panic("unreachable");3957 vm_push_f64(vm, fabs(vm_pop_f64(vm)));
4037 case WasmPrefixedOp_table_copy: panic("unreachable");3958 break;
4038 case WasmPrefixedOp_table_grow: panic("unreachable");3959 case Op_fneg_64:
4039 case WasmPrefixedOp_table_size: panic("unreachable");3960 vm_push_f64(vm, -vm_pop_f64(vm));
4040 case WasmPrefixedOp_table_fill: panic("unreachable");3961 break;
4041 default: panic("unreachable");3962 case Op_ceil_64:
4042 }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));
4043 }4024 }
4044 break;4025 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;
4046 }4072 }
4047 }4073 }
4048}4074}
...@@ -4064,11 +4090,12 @@ int main(int argc, char **argv) {...@@ -4064,11 +4090,12 @@ int main(int argc, char **argv) {
40644090
4065 size_t cwd_path_len = common_prefix(zig_lib_dir_path, cmake_binary_dir_path);4091 size_t cwd_path_len = common_prefix(zig_lib_dir_path, cmake_binary_dir_path);
4066 const char *rel_cmake_bin_path = cmake_binary_dir_path + cwd_path_len;4092 const char *rel_cmake_bin_path = cmake_binary_dir_path + cwd_path_len;
4093
4067 size_t rel_cmake_bin_path_len = strlen(rel_cmake_bin_path);4094 size_t rel_cmake_bin_path_len = strlen(rel_cmake_bin_path);
40684095
4069 const char *new_argv[30];4096 const char *new_argv[30];
4070 char new_argv_buf[PATH_MAX + 1024];4097 char new_argv_buf[PATH_MAX + 1024];
4071 uint32_t new_argv_i = 0; 4098 uint32_t new_argv_i = 0;
4072 uint32_t new_argv_buf_i = 0;4099 uint32_t new_argv_buf_i = 0;
40734100
4074 int cache_dir = -1;4101 int cache_dir = -1;
...@@ -4102,7 +4129,7 @@ int main(int argc, char **argv) {...@@ -4102,7 +4129,7 @@ int main(int argc, char **argv) {
4102 new_argv_i += 1;4129 new_argv_i += 1;
4103 argv_i += 1;4130 argv_i += 1;
41044131
4105 for(; argv[argv_i]; argv_i += 1) {4132 for (; argv[argv_i]; argv_i += 1) {
4106 new_argv[new_argv_i] = argv[argv_i];4133 new_argv[new_argv_i] = argv[argv_i];
4107 new_argv_i += 1;4134 new_argv_i += 1;
4108 }4135 }
...@@ -4380,6 +4407,7 @@ int main(int argc, char **argv) {...@@ -4380,6 +4407,7 @@ int main(int argc, char **argv) {
4380 functions = arena_alloc(sizeof(struct Function) * functions_len);4407 functions = arena_alloc(sizeof(struct Function) * functions_len);
4381 for (size_t func_i = 0; func_i < functions_len; func_i += 1) {4408 for (size_t func_i = 0; func_i < functions_len; func_i += 1) {
4382 struct Function *func = &functions[func_i];4409 struct Function *func = &functions[func_i];
4410 func->id = imports_len + func_i;
4383 func->type_idx = read32_uleb128(mod_ptr, &i);4411 func->type_idx = read32_uleb128(mod_ptr, &i);
4384 }4412 }
4385 }4413 }
...@@ -4474,7 +4502,7 @@ int main(int argc, char **argv) {...@@ -4474,7 +4502,7 @@ int main(int argc, char **argv) {
4474#ifndef NDEBUG4502#ifndef NDEBUG
4475 memset(&vm, 0xaa, sizeof(struct VirtualMachine)); // to match the zig version4503 memset(&vm, 0xaa, sizeof(struct VirtualMachine)); // to match the zig version
4476#endif4504#endif
4477 vm.stack = arena_alloc(sizeof(uint64_t) * 10000000),4505 vm.stack = arena_alloc(sizeof(uint32_t) * 10000000),
4478 vm.mod_ptr = mod_ptr;4506 vm.mod_ptr = mod_ptr;
4479 vm.opcodes = arena_alloc(2000000);4507 vm.opcodes = arena_alloc(2000000);
4480 vm.operands = arena_alloc(sizeof(uint32_t) * 2000000);4508 vm.operands = arena_alloc(sizeof(uint32_t) * 2000000);
...@@ -4496,42 +4524,43 @@ int main(int argc, char **argv) {...@@ -4496,42 +4524,43 @@ int main(int argc, char **argv) {
4496 struct ProgramCounter pc;4524 struct ProgramCounter pc;
4497 pc.opcode = 0;4525 pc.opcode = 0;
4498 pc.operand = 0;4526 pc.operand = 0;
4527 struct StackInfo stack;
4499 for (uint32_t func_i = 0; func_i < functions_len; func_i += 1) {4528 for (uint32_t func_i = 0; func_i < functions_len; func_i += 1) {
4500 struct Function *func = &functions[func_i];4529 struct Function *func = &functions[func_i];
4501 uint32_t size = read32_uleb128(mod_ptr, &code_i);4530 uint32_t size = read32_uleb128(mod_ptr, &code_i);
4502 uint32_t code_begin = code_i;4531 uint32_t code_begin = code_i;
45034532
4533 stack.top_index = 0;
4534 stack.top_offset = 0;
4504 struct TypeInfo *type_info = &vm.types[func->type_idx];4535 struct TypeInfo *type_info = &vm.types[func->type_idx];
4505 func->locals_count = 0;4536 for (uint32_t param_i = 0; param_i < type_info->param_count; param_i += 1)
4506 func->local_types = malloc(sizeof(uint32_t) * ((type_info->param_count + func->locals_count + 31) / 32));4537 si_push(&stack, bs_isSet(&type_info->param_types, param_i));
4507 func->local_types[0] = type_info->param_types;4538 uint32_t params_size = stack.top_offset;
45084539
4509 for (uint32_t local_sets_count = read32_uleb128(mod_ptr, &code_i);4540 for (uint32_t local_sets_count = read32_uleb128(mod_ptr, &code_i);
4510 local_sets_count > 0; local_sets_count -= 1)4541 local_sets_count > 0; local_sets_count -= 1)
4511 {4542 {
4512 uint32_t set_count = read32_uleb128(mod_ptr, &code_i);4543 uint32_t local_set_count = read32_uleb128(mod_ptr, &code_i);
4513 int64_t local_type = read64_ileb128(mod_ptr, &code_i);4544 enum StackType local_type;
45144545 switch (read64_ileb128(mod_ptr, &code_i)) {
4515 uint32_t i = type_info->param_count + func->locals_count;4546 case -1: case -3: local_type = ST_32; break;
4516 func->locals_count += set_count;4547 case -2: case -4: local_type = ST_64; break;
4517 if ((type_info->param_count + func->locals_count + 31) / 32 > (i + 31) / 32)4548 default: panic("unexpected local type");
4518 func->local_types = realloc(func->local_types, sizeof(uint32_t) * ((type_info->param_count + func->locals_count + 31) / 32));4549 }
4519 for (; i < type_info->param_count + func->locals_count; i += 1)4550 for (; local_set_count > 0; local_set_count -= 1)
4520 switch (local_type) {4551 si_push(&stack, 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 }
4525 }4552 }
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);
4528 func->entry_pc = pc;4555 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);
4530 if (code_i != code_begin + size) panic("bad code size");4558 if (code_i != code_begin + size) panic("bad code size");
4531 }4559 }
4560 //fprintf(stderr, "%u opcodes\n%u operands\n", pc.opcode, pc.operand);
4532 }4561 }
45334562
4534 vm_call(&vm, start_fn_idx);4563 vm_call(&vm, &vm.functions[start_fn_idx - imports_len]);
4535 vm_run(&vm);4564 vm_run(&vm);
45364565
4537 return 0;4566 return 0;