@@ -708,6 +708,8 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
708
708
#if DEBUG
709
709
DebugTracer ? debugger = _txTracer . GetTracer < DebugTracer > ( ) ;
710
710
#endif
711
+ ref UInt256 byRef = ref NullRef < UInt256 > ( ) ;
712
+
711
713
SkipInit ( out UInt256 a ) ;
712
714
SkipInit ( out UInt256 b ) ;
713
715
SkipInit ( out UInt256 c ) ;
@@ -741,75 +743,74 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
741
743
{
742
744
goto EmptyReturn ;
743
745
}
746
+ // Arithmetic operations that pop 2 operands and push one result use PeekUInt256Ref that allows
747
+ // to get a ref to the top of the stack.
744
748
case Instruction . ADD :
745
749
{
746
750
gasAvailable -= GasCostOf . VeryLow ;
747
751
748
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
749
752
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
750
- UInt256 . Add ( in a , in b , out result ) ;
751
- stack . PushUInt256 ( in result ) ;
752
-
753
+ byRef = ref stack . PeekUInt256Ref ( ) ;
754
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
755
+ UInt256 . Add ( in a , in byRef , out byRef ) ;
753
756
break ;
754
757
}
755
758
case Instruction . MUL :
756
759
{
757
760
gasAvailable -= GasCostOf . Low ;
758
761
759
762
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
760
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
761
- UInt256 . Multiply ( in a , in b , out result ) ;
762
- stack . PushUInt256 ( in result ) ;
763
+ byRef = ref stack . PeekUInt256Ref ( ) ;
764
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
765
+ UInt256 . Multiply ( in a , in byRef , out byRef ) ;
763
766
break ;
764
767
}
765
768
case Instruction . SUB :
766
769
{
767
770
gasAvailable -= GasCostOf . VeryLow ;
768
771
769
772
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
770
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
771
- UInt256 . Subtract ( in a , in b , out result ) ;
772
-
773
- stack . PushUInt256 ( in result ) ;
773
+ byRef = ref stack . PeekUInt256Ref ( ) ;
774
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
775
+ UInt256 . Subtract ( in a , in byRef , out byRef ) ;
774
776
break ;
775
777
}
776
778
case Instruction . DIV :
777
779
{
778
780
gasAvailable -= GasCostOf . Low ;
779
781
780
782
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
781
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
782
- if ( b . IsZero )
783
+ byRef = ref stack . PeekUInt256Ref ( ) ;
784
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
785
+ if ( byRef . IsZero )
783
786
{
784
- stack . PushZero ( ) ;
787
+ byRef = default ;
785
788
}
786
789
else
787
790
{
788
- UInt256 . Divide ( in a , in b , out result ) ;
789
- stack . PushUInt256 ( in result ) ;
791
+ UInt256 . Divide ( in a , in byRef , out byRef ) ;
790
792
}
791
-
792
793
break ;
793
794
}
794
795
case Instruction . SDIV :
795
796
{
796
797
gasAvailable -= GasCostOf . Low ;
797
798
798
799
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
799
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
800
- if ( b . IsZero )
800
+ byRef = ref stack . PeekUInt256Ref ( ) ;
801
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
802
+ if ( byRef . IsZero )
801
803
{
802
- stack . PushZero ( ) ;
804
+ // NOP
805
+ // byRef = default;
803
806
}
804
- else if ( As < UInt256 , Int256 > ( ref b ) == Int256 . MinusOne && a == P255 )
807
+ else if ( As < UInt256 , Int256 > ( ref byRef ) == Int256 . MinusOne && a == P255 )
805
808
{
806
- result = P255 ;
807
- stack . PushUInt256 ( in result ) ;
809
+ byRef = P255 ;
808
810
}
809
811
else
810
812
{
811
- Int256 . Divide ( in As < UInt256 , Int256 > ( ref a ) , in As < UInt256 , Int256 > ( ref b ) , out As < UInt256 , Int256 > ( ref result ) ) ;
812
- stack . PushUInt256 ( in result ) ;
813
+ Int256 . Divide ( in As < UInt256 , Int256 > ( ref a ) , in As < UInt256 , Int256 > ( ref byRef ) , out As < UInt256 , Int256 > ( ref byRef ) ) ;
813
814
}
814
815
815
816
break ;
@@ -819,26 +820,26 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
819
820
gasAvailable -= GasCostOf . Low ;
820
821
821
822
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
822
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
823
- UInt256 . Mod ( in a , in b , out result ) ;
824
- stack . PushUInt256 ( in result ) ;
823
+ byRef = ref stack . PeekUInt256Ref ( ) ;
824
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
825
+ UInt256 . Mod ( in a , in byRef , out byRef ) ;
825
826
break ;
826
827
}
827
828
case Instruction . SMOD :
828
829
{
829
830
gasAvailable -= GasCostOf . Low ;
830
831
831
832
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
832
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
833
+ byRef = ref stack . PeekUInt256Ref ( ) ;
834
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
833
835
if ( b . IsZeroOrOne )
834
836
{
835
- stack . PushZero ( ) ;
837
+ byRef = default ;
836
838
}
837
839
else
838
840
{
839
841
As < UInt256 , Int256 > ( ref a )
840
- . Mod ( in As < UInt256 , Int256 > ( ref b ) , out As < UInt256 , Int256 > ( ref result ) ) ;
841
- stack . PushUInt256 ( in result ) ;
842
+ . Mod ( in As < UInt256 , Int256 > ( ref byRef ) , out As < UInt256 , Int256 > ( ref byRef ) ) ;
842
843
}
843
844
844
845
break ;
@@ -849,16 +850,17 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
849
850
850
851
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
851
852
if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
852
- if ( ! stack . PopUInt256 ( out c ) ) goto StackUnderflow ;
853
+ byRef = ref stack . PeekUInt256Ref ( ) ;
854
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
853
855
854
- if ( c . IsZero )
856
+ if ( byRef . IsZero )
855
857
{
856
- stack . PushZero ( ) ;
858
+ // NOP
859
+ // byRef = default;
857
860
}
858
861
else
859
862
{
860
- UInt256 . AddMod ( a , b , c , out result ) ;
861
- stack . PushUInt256 ( in result ) ;
863
+ UInt256 . AddMod ( a , b , byRef , out byRef ) ;
862
864
}
863
865
864
866
break ;
@@ -869,16 +871,17 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
869
871
870
872
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
871
873
if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
872
- if ( ! stack . PopUInt256 ( out c ) ) goto StackUnderflow ;
874
+ byRef = ref stack . PeekUInt256Ref ( ) ;
875
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
873
876
874
877
if ( c . IsZero )
875
878
{
876
- stack . PushZero ( ) ;
879
+ // NOP
880
+ // byRef = default;
877
881
}
878
882
else
879
883
{
880
- UInt256 . MultiplyMod ( in a , in b , in c , out result ) ;
881
- stack . PushUInt256 ( in result ) ;
884
+ UInt256 . MultiplyMod ( in a , in b , in byRef , out byRef ) ;
882
885
}
883
886
884
887
break ;
@@ -953,15 +956,10 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
953
956
gasAvailable -= GasCostOf . VeryLow ;
954
957
955
958
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
956
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
957
- if ( a < b )
958
- {
959
- stack . PushOne ( ) ;
960
- }
961
- else
962
- {
963
- stack . PushZero ( ) ;
964
- }
959
+ byRef = ref stack . PeekUInt256Ref ( ) ;
960
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
961
+
962
+ byRef = a < byRef ? UInt256 . One : UInt256 . Zero ;
965
963
966
964
break ;
967
965
}
@@ -970,15 +968,10 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
970
968
gasAvailable -= GasCostOf . VeryLow ;
971
969
972
970
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
973
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
974
- if ( a > b )
975
- {
976
- stack . PushOne ( ) ;
977
- }
978
- else
979
- {
980
- stack . PushZero ( ) ;
981
- }
971
+ byRef = ref stack . PeekUInt256Ref ( ) ;
972
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
973
+
974
+ byRef = a > byRef ? UInt256 . One : UInt256 . Zero ;
982
975
983
976
break ;
984
977
}
@@ -987,16 +980,12 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
987
980
gasAvailable -= GasCostOf . VeryLow ;
988
981
989
982
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
990
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
983
+ byRef = ref stack . PeekUInt256Ref ( ) ;
984
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
991
985
992
- if ( As < UInt256 , Int256 > ( ref a ) . CompareTo ( As < UInt256 , Int256 > ( ref b ) ) < 0 )
993
- {
994
- stack . PushOne ( ) ;
995
- }
996
- else
997
- {
998
- stack . PushZero ( ) ;
999
- }
986
+ byRef = As < UInt256 , Int256 > ( ref a ) . CompareTo ( As < UInt256 , Int256 > ( ref byRef ) ) < 0
987
+ ? UInt256 . One
988
+ : UInt256 . Zero ;
1000
989
1001
990
break ;
1002
991
}
@@ -1005,15 +994,12 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
1005
994
gasAvailable -= GasCostOf . VeryLow ;
1006
995
1007
996
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
1008
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
1009
- if ( As < UInt256 , Int256 > ( ref a ) . CompareTo ( As < UInt256 , Int256 > ( ref b ) ) > 0 )
1010
- {
1011
- stack . PushOne ( ) ;
1012
- }
1013
- else
1014
- {
1015
- stack . PushZero ( ) ;
1016
- }
997
+ byRef = ref stack . PeekUInt256Ref ( ) ;
998
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
999
+
1000
+ byRef = As < UInt256 , Int256 > ( ref a ) . CompareTo ( As < UInt256 , Int256 > ( ref byRef ) ) > 0
1001
+ ? UInt256 . One
1002
+ : UInt256 . Zero ;
1017
1003
1018
1004
break ;
1019
1005
}
@@ -1022,31 +1008,21 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
1022
1008
gasAvailable -= GasCostOf . VeryLow ;
1023
1009
1024
1010
if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
1025
- if ( ! stack . PopUInt256 ( out b ) ) goto StackUnderflow ;
1026
- if ( a . Equals ( b ) )
1027
- {
1028
- stack . PushOne ( ) ;
1029
- }
1030
- else
1031
- {
1032
- stack . PushZero ( ) ;
1033
- }
1011
+ byRef = ref stack . PeekUInt256Ref ( ) ;
1012
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
1013
+
1014
+ byRef = a . Equals ( byRef ) ? UInt256 . One : UInt256 . Zero ;
1034
1015
1035
1016
break ;
1036
1017
}
1037
1018
case Instruction . ISZERO :
1038
1019
{
1039
1020
gasAvailable -= GasCostOf . VeryLow ;
1040
1021
1041
- if ( ! stack . PopUInt256 ( out a ) ) goto StackUnderflow ;
1042
- if ( a . IsZero )
1043
- {
1044
- stack . PushOne ( ) ;
1045
- }
1046
- else
1047
- {
1048
- stack . PushZero ( ) ;
1049
- }
1022
+ byRef = ref stack . PeekUInt256Ref ( ) ;
1023
+ if ( IsNullRef ( ref byRef ) ) goto StackUnderflow ;
1024
+
1025
+ byRef = byRef . IsZero ? UInt256 . One : UInt256 . Zero ;
1050
1026
1051
1027
break ;
1052
1028
}
0 commit comments