@@ -18,8 +18,8 @@ namespace fizzy
18
18
{
19
19
namespace
20
20
{
21
- // code_offset + imm_offset + stack_height
22
- constexpr auto BranchImmediateSize = 3 * sizeof (uint32_t );
21
+ // code_offset + stack_drop
22
+ constexpr auto BranchImmediateSize = 2 * sizeof (uint32_t );
23
23
24
24
constexpr uint32_t F32AbsMask = 0x7fffffff ;
25
25
constexpr uint32_t F32SignMask = ~F32AbsMask;
@@ -453,15 +453,12 @@ __attribute__((no_sanitize("float-cast-overflow"))) inline constexpr float demot
453
453
return static_cast <float >(value);
454
454
}
455
455
456
- void branch (const Code& code, OperandStack& stack, const uint8_t *& pc, const uint8_t *& immediates,
457
- uint32_t arity) noexcept
456
+ void branch (const Code& code, OperandStack& stack, const uint8_t *& pc, uint32_t arity) noexcept
458
457
{
459
- const auto code_offset = read <uint32_t >(immediates);
460
- const auto imm_offset = read <uint32_t >(immediates);
461
- const auto stack_drop = read <uint32_t >(immediates);
458
+ const auto code_offset = read <uint32_t >(pc);
459
+ const auto stack_drop = read <uint32_t >(pc);
462
460
463
461
pc = code.instructions .data () + code_offset;
464
- immediates = code.immediates .data () + imm_offset;
465
462
466
463
// When branch is taken, additional stack items must be dropped.
467
464
assert (static_cast <int >(stack_drop) >= 0 );
@@ -523,7 +520,6 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
523
520
static_cast <size_t >(code.max_stack_height ));
524
521
525
522
const uint8_t * pc = code.instructions .data ();
526
- const uint8_t * immediates = code.immediates .data ();
527
523
528
524
while (true )
529
525
{
@@ -539,27 +535,20 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
539
535
case Instr::if_:
540
536
{
541
537
if (stack.pop ().as <uint32_t >() != 0 )
542
- immediates += 2 * sizeof (uint32_t ); // Skip the immediates for else instruction.
538
+ pc += sizeof (uint32_t ); // Skip the immediate for else instruction.
543
539
else
544
540
{
545
- const auto target_pc = read <uint32_t >(immediates);
546
- const auto target_imm = read <uint32_t >(immediates);
547
-
541
+ const auto target_pc = read <uint32_t >(pc);
548
542
pc = code.instructions .data () + target_pc;
549
- immediates = code.immediates .data () + target_imm;
550
543
}
551
544
break ;
552
545
}
553
546
case Instr::else_:
554
547
{
555
548
// We reach else only after executing if block ("then" part),
556
549
// so we need to skip else block now.
557
- const auto target_pc = read <uint32_t >(immediates);
558
- const auto target_imm = read <uint32_t >(immediates);
559
-
550
+ const auto target_pc = read <uint32_t >(pc);
560
551
pc = code.instructions .data () + target_pc;
561
- immediates = code.immediates .data () + target_imm;
562
-
563
552
break ;
564
553
}
565
554
case Instr::end:
@@ -573,36 +562,36 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
573
562
case Instr::br_if:
574
563
case Instr::return_:
575
564
{
576
- const auto arity = read <uint32_t >(immediates );
565
+ const auto arity = read <uint32_t >(pc );
577
566
578
567
// Check condition for br_if.
579
568
if (instruction == Instr::br_if && stack.pop ().as <uint32_t >() == 0 )
580
569
{
581
- immediates += BranchImmediateSize;
570
+ pc += BranchImmediateSize;
582
571
break ;
583
572
}
584
573
585
- branch (code, stack, pc, immediates, arity);
574
+ branch (code, stack, pc, arity);
586
575
break ;
587
576
}
588
577
case Instr::br_table:
589
578
{
590
- const auto br_table_size = read <uint32_t >(immediates );
591
- const auto arity = read <uint32_t >(immediates );
579
+ const auto br_table_size = read <uint32_t >(pc );
580
+ const auto arity = read <uint32_t >(pc );
592
581
593
582
const auto br_table_idx = stack.pop ().as <uint32_t >();
594
583
595
584
const auto label_idx_offset = br_table_idx < br_table_size ?
596
585
br_table_idx * BranchImmediateSize :
597
586
br_table_size * BranchImmediateSize;
598
- immediates += label_idx_offset;
587
+ pc += label_idx_offset;
599
588
600
- branch (code, stack, pc, immediates, arity);
589
+ branch (code, stack, pc, arity);
601
590
break ;
602
591
}
603
592
case Instr::call:
604
593
{
605
- const auto called_func_idx = read <uint32_t >(immediates );
594
+ const auto called_func_idx = read <uint32_t >(pc );
606
595
const auto & called_func_type = instance.module ->get_function_type (called_func_idx);
607
596
608
597
if (!invoke_function (called_func_type, called_func_idx, instance, stack, depth))
@@ -613,7 +602,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
613
602
{
614
603
assert (instance.table != nullptr );
615
604
616
- const auto expected_type_idx = read <uint32_t >(immediates );
605
+ const auto expected_type_idx = read <uint32_t >(pc );
617
606
assert (expected_type_idx < instance.module ->typesec .size ());
618
607
619
608
const auto elem_idx = stack.pop ().as <uint32_t >();
@@ -655,25 +644,25 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
655
644
}
656
645
case Instr::local_get:
657
646
{
658
- const auto idx = read <uint32_t >(immediates );
647
+ const auto idx = read <uint32_t >(pc );
659
648
stack.push (stack.local (idx));
660
649
break ;
661
650
}
662
651
case Instr::local_set:
663
652
{
664
- const auto idx = read <uint32_t >(immediates );
653
+ const auto idx = read <uint32_t >(pc );
665
654
stack.local (idx) = stack.pop ();
666
655
break ;
667
656
}
668
657
case Instr::local_tee:
669
658
{
670
- const auto idx = read <uint32_t >(immediates );
659
+ const auto idx = read <uint32_t >(pc );
671
660
stack.local (idx) = stack.top ();
672
661
break ;
673
662
}
674
663
case Instr::global_get:
675
664
{
676
- const auto idx = read <uint32_t >(immediates );
665
+ const auto idx = read <uint32_t >(pc );
677
666
assert (idx < instance.imported_globals .size () + instance.globals .size ());
678
667
if (idx < instance.imported_globals .size ())
679
668
{
@@ -689,7 +678,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
689
678
}
690
679
case Instr::global_set:
691
680
{
692
- const auto idx = read <uint32_t >(immediates );
681
+ const auto idx = read <uint32_t >(pc );
693
682
if (idx < instance.imported_globals .size ())
694
683
{
695
684
assert (instance.imported_globals [idx].type .is_mutable );
@@ -706,129 +695,129 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
706
695
}
707
696
case Instr::i32_load:
708
697
{
709
- if (!load_from_memory<uint32_t >(*memory, stack, immediates ))
698
+ if (!load_from_memory<uint32_t >(*memory, stack, pc ))
710
699
goto trap;
711
700
break ;
712
701
}
713
702
case Instr::i64_load:
714
703
{
715
- if (!load_from_memory<uint64_t >(*memory, stack, immediates ))
704
+ if (!load_from_memory<uint64_t >(*memory, stack, pc ))
716
705
goto trap;
717
706
break ;
718
707
}
719
708
case Instr::f32_load:
720
709
{
721
- if (!load_from_memory<float >(*memory, stack, immediates ))
710
+ if (!load_from_memory<float >(*memory, stack, pc ))
722
711
goto trap;
723
712
break ;
724
713
}
725
714
case Instr::f64_load:
726
715
{
727
- if (!load_from_memory<double >(*memory, stack, immediates ))
716
+ if (!load_from_memory<double >(*memory, stack, pc ))
728
717
goto trap;
729
718
break ;
730
719
}
731
720
case Instr::i32_load8_s:
732
721
{
733
- if (!load_from_memory<uint32_t , int8_t >(*memory, stack, immediates ))
722
+ if (!load_from_memory<uint32_t , int8_t >(*memory, stack, pc ))
734
723
goto trap;
735
724
break ;
736
725
}
737
726
case Instr::i32_load8_u:
738
727
{
739
- if (!load_from_memory<uint32_t , uint8_t >(*memory, stack, immediates ))
728
+ if (!load_from_memory<uint32_t , uint8_t >(*memory, stack, pc ))
740
729
goto trap;
741
730
break ;
742
731
}
743
732
case Instr::i32_load16_s:
744
733
{
745
- if (!load_from_memory<uint32_t , int16_t >(*memory, stack, immediates ))
734
+ if (!load_from_memory<uint32_t , int16_t >(*memory, stack, pc ))
746
735
goto trap;
747
736
break ;
748
737
}
749
738
case Instr::i32_load16_u:
750
739
{
751
- if (!load_from_memory<uint32_t , uint16_t >(*memory, stack, immediates ))
740
+ if (!load_from_memory<uint32_t , uint16_t >(*memory, stack, pc ))
752
741
goto trap;
753
742
break ;
754
743
}
755
744
case Instr::i64_load8_s:
756
745
{
757
- if (!load_from_memory<uint64_t , int8_t >(*memory, stack, immediates ))
746
+ if (!load_from_memory<uint64_t , int8_t >(*memory, stack, pc ))
758
747
goto trap;
759
748
break ;
760
749
}
761
750
case Instr::i64_load8_u:
762
751
{
763
- if (!load_from_memory<uint64_t , uint8_t >(*memory, stack, immediates ))
752
+ if (!load_from_memory<uint64_t , uint8_t >(*memory, stack, pc ))
764
753
goto trap;
765
754
break ;
766
755
}
767
756
case Instr::i64_load16_s:
768
757
{
769
- if (!load_from_memory<uint64_t , int16_t >(*memory, stack, immediates ))
758
+ if (!load_from_memory<uint64_t , int16_t >(*memory, stack, pc ))
770
759
goto trap;
771
760
break ;
772
761
}
773
762
case Instr::i64_load16_u:
774
763
{
775
- if (!load_from_memory<uint64_t , uint16_t >(*memory, stack, immediates ))
764
+ if (!load_from_memory<uint64_t , uint16_t >(*memory, stack, pc ))
776
765
goto trap;
777
766
break ;
778
767
}
779
768
case Instr::i64_load32_s:
780
769
{
781
- if (!load_from_memory<uint64_t , int32_t >(*memory, stack, immediates ))
770
+ if (!load_from_memory<uint64_t , int32_t >(*memory, stack, pc ))
782
771
goto trap;
783
772
break ;
784
773
}
785
774
case Instr::i64_load32_u:
786
775
{
787
- if (!load_from_memory<uint64_t , uint32_t >(*memory, stack, immediates ))
776
+ if (!load_from_memory<uint64_t , uint32_t >(*memory, stack, pc ))
788
777
goto trap;
789
778
break ;
790
779
}
791
780
case Instr::i32_store:
792
781
{
793
- if (!store_into_memory<uint32_t >(*memory, stack, immediates ))
782
+ if (!store_into_memory<uint32_t >(*memory, stack, pc ))
794
783
goto trap;
795
784
break ;
796
785
}
797
786
case Instr::i64_store:
798
787
{
799
- if (!store_into_memory<uint64_t >(*memory, stack, immediates ))
788
+ if (!store_into_memory<uint64_t >(*memory, stack, pc ))
800
789
goto trap;
801
790
break ;
802
791
}
803
792
case Instr::f32_store:
804
793
{
805
- if (!store_into_memory<float >(*memory, stack, immediates ))
794
+ if (!store_into_memory<float >(*memory, stack, pc ))
806
795
goto trap;
807
796
break ;
808
797
}
809
798
case Instr::f64_store:
810
799
{
811
- if (!store_into_memory<double >(*memory, stack, immediates ))
800
+ if (!store_into_memory<double >(*memory, stack, pc ))
812
801
goto trap;
813
802
break ;
814
803
}
815
804
case Instr::i32_store8:
816
805
case Instr::i64_store8:
817
806
{
818
- if (!store_into_memory<uint8_t >(*memory, stack, immediates ))
807
+ if (!store_into_memory<uint8_t >(*memory, stack, pc ))
819
808
goto trap;
820
809
break ;
821
810
}
822
811
case Instr::i32_store16:
823
812
case Instr::i64_store16:
824
813
{
825
- if (!store_into_memory<uint16_t >(*memory, stack, immediates ))
814
+ if (!store_into_memory<uint16_t >(*memory, stack, pc ))
826
815
goto trap;
827
816
break ;
828
817
}
829
818
case Instr::i64_store32:
830
819
{
831
- if (!store_into_memory<uint32_t >(*memory, stack, immediates ))
820
+ if (!store_into_memory<uint32_t >(*memory, stack, pc ))
832
821
goto trap;
833
822
break ;
834
823
}
@@ -861,14 +850,14 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
861
850
case Instr::i32_const:
862
851
case Instr::f32_const:
863
852
{
864
- const auto value = read <uint32_t >(immediates );
853
+ const auto value = read <uint32_t >(pc );
865
854
stack.push (value);
866
855
break ;
867
856
}
868
857
case Instr::i64_const:
869
858
case Instr::f64_const:
870
859
{
871
- const auto value = read <uint64_t >(immediates );
860
+ const auto value = read <uint64_t >(pc );
872
861
stack.push (value);
873
862
break ;
874
863
}
0 commit comments