@@ -252,7 +252,10 @@ func (m *Machine) doOpQuo() {
252
252
}
253
253
254
254
// lv / rv
255
- quoAssign (lv , rv )
255
+ err := quoAssign (lv , rv )
256
+ if err != nil {
257
+ panic (err )
258
+ }
256
259
}
257
260
258
261
func (m * Machine ) doOpRem () {
@@ -266,7 +269,10 @@ func (m *Machine) doOpRem() {
266
269
}
267
270
268
271
// lv % rv
269
- remAssign (lv , rv )
272
+ err := remAssign (lv , rv )
273
+ if err != nil {
274
+ panic (err )
275
+ }
270
276
}
271
277
272
278
func (m * Machine ) doOpShl () {
@@ -845,45 +851,94 @@ func mulAssign(lv, rv *TypedValue) {
845
851
}
846
852
847
853
// for doOpQuo and doOpQuoAssign.
848
- func quoAssign (lv , rv * TypedValue ) {
854
+ func quoAssign (lv , rv * TypedValue ) * Exception {
855
+ expt := & Exception {
856
+ Value : typedString ("division by zero" ),
857
+ }
858
+
849
859
// set the result in lv.
850
860
// NOTE this block is replicated in op_assign.go
851
861
switch baseOf (lv .T ) {
852
862
case IntType :
863
+ if rv .GetInt () == 0 {
864
+ return expt
865
+ }
853
866
lv .SetInt (lv .GetInt () / rv .GetInt ())
854
867
case Int8Type :
868
+ if rv .GetInt8 () == 0 {
869
+ return expt
870
+ }
855
871
lv .SetInt8 (lv .GetInt8 () / rv .GetInt8 ())
856
872
case Int16Type :
873
+ if rv .GetInt16 () == 0 {
874
+ return expt
875
+ }
857
876
lv .SetInt16 (lv .GetInt16 () / rv .GetInt16 ())
858
877
case Int32Type , UntypedRuneType :
878
+ if rv .GetInt32 () == 0 {
879
+ return expt
880
+ }
859
881
lv .SetInt32 (lv .GetInt32 () / rv .GetInt32 ())
860
882
case Int64Type :
883
+ if rv .GetInt64 () == 0 {
884
+ return expt
885
+ }
861
886
lv .SetInt64 (lv .GetInt64 () / rv .GetInt64 ())
862
887
case UintType :
888
+ if rv .GetUint () == 0 {
889
+ return expt
890
+ }
863
891
lv .SetUint (lv .GetUint () / rv .GetUint ())
864
892
case Uint8Type :
893
+ if rv .GetUint8 () == 0 {
894
+ return expt
895
+ }
865
896
lv .SetUint8 (lv .GetUint8 () / rv .GetUint8 ())
866
897
case DataByteType :
898
+ if rv .GetUint8 () == 0 {
899
+ return expt
900
+ }
867
901
lv .SetDataByte (lv .GetDataByte () / rv .GetUint8 ())
868
902
case Uint16Type :
903
+ if rv .GetUint16 () == 0 {
904
+ return expt
905
+ }
869
906
lv .SetUint16 (lv .GetUint16 () / rv .GetUint16 ())
870
907
case Uint32Type :
908
+ if rv .GetUint32 () == 0 {
909
+ return expt
910
+ }
871
911
lv .SetUint32 (lv .GetUint32 () / rv .GetUint32 ())
872
912
case Uint64Type :
913
+ if rv .GetUint64 () == 0 {
914
+ return expt
915
+ }
873
916
lv .SetUint64 (lv .GetUint64 () / rv .GetUint64 ())
874
917
case Float32Type :
875
918
// NOTE: gno doesn't fuse *+.
919
+ if rv .GetFloat32 () == 0 {
920
+ return expt
921
+ }
876
922
lv .SetFloat32 (lv .GetFloat32 () / rv .GetFloat32 ())
877
923
// XXX FOR DETERMINISM, PANIC IF NAN.
878
924
case Float64Type :
879
925
// NOTE: gno doesn't fuse *+.
926
+ if rv .GetFloat64 () == 0 {
927
+ return expt
928
+ }
880
929
lv .SetFloat64 (lv .GetFloat64 () / rv .GetFloat64 ())
881
930
// XXX FOR DETERMINISM, PANIC IF NAN.
882
931
case BigintType , UntypedBigintType :
932
+ if rv .GetBigInt ().Sign () == 0 {
933
+ return expt
934
+ }
883
935
lb := lv .GetBigInt ()
884
936
lb = big .NewInt (0 ).Quo (lb , rv .GetBigInt ())
885
937
lv .V = BigintValue {V : lb }
886
938
case BigdecType , UntypedBigdecType :
939
+ if rv .GetBigDec ().Cmp (apd .New (0 , 0 )) == 0 {
940
+ return expt
941
+ }
887
942
lb := lv .GetBigDec ()
888
943
rb := rv .GetBigDec ()
889
944
quo := apd .New (0 , 0 )
@@ -898,36 +953,79 @@ func quoAssign(lv, rv *TypedValue) {
898
953
lv .T ,
899
954
))
900
955
}
956
+
957
+ return nil
901
958
}
902
959
903
960
// for doOpRem and doOpRemAssign.
904
- func remAssign (lv , rv * TypedValue ) {
961
+ func remAssign (lv , rv * TypedValue ) * Exception {
962
+ expt := & Exception {
963
+ Value : typedString ("division by zero" ),
964
+ }
965
+
905
966
// set the result in lv.
906
967
// NOTE this block is replicated in op_assign.go
907
968
switch baseOf (lv .T ) {
908
969
case IntType :
970
+ if rv .GetInt () == 0 {
971
+ return expt
972
+ }
909
973
lv .SetInt (lv .GetInt () % rv .GetInt ())
910
974
case Int8Type :
975
+ if rv .GetInt8 () == 0 {
976
+ return expt
977
+ }
911
978
lv .SetInt8 (lv .GetInt8 () % rv .GetInt8 ())
912
979
case Int16Type :
980
+ if rv .GetInt16 () == 0 {
981
+ return expt
982
+ }
913
983
lv .SetInt16 (lv .GetInt16 () % rv .GetInt16 ())
914
984
case Int32Type , UntypedRuneType :
985
+ if rv .GetInt32 () == 0 {
986
+ return expt
987
+ }
915
988
lv .SetInt32 (lv .GetInt32 () % rv .GetInt32 ())
916
989
case Int64Type :
990
+ if rv .GetInt64 () == 0 {
991
+ return expt
992
+ }
917
993
lv .SetInt64 (lv .GetInt64 () % rv .GetInt64 ())
918
994
case UintType :
995
+ if rv .GetUint () == 0 {
996
+ return expt
997
+ }
919
998
lv .SetUint (lv .GetUint () % rv .GetUint ())
920
999
case Uint8Type :
1000
+ if rv .GetUint8 () == 0 {
1001
+ return expt
1002
+ }
921
1003
lv .SetUint8 (lv .GetUint8 () % rv .GetUint8 ())
922
1004
case DataByteType :
1005
+ if rv .GetUint8 () == 0 {
1006
+ return expt
1007
+ }
923
1008
lv .SetDataByte (lv .GetDataByte () % rv .GetUint8 ())
924
1009
case Uint16Type :
1010
+ if rv .GetUint16 () == 0 {
1011
+ return expt
1012
+ }
925
1013
lv .SetUint16 (lv .GetUint16 () % rv .GetUint16 ())
926
1014
case Uint32Type :
1015
+ if rv .GetUint32 () == 0 {
1016
+ return expt
1017
+ }
927
1018
lv .SetUint32 (lv .GetUint32 () % rv .GetUint32 ())
928
1019
case Uint64Type :
1020
+ if rv .GetUint64 () == 0 {
1021
+ return expt
1022
+ }
929
1023
lv .SetUint64 (lv .GetUint64 () % rv .GetUint64 ())
930
1024
case BigintType , UntypedBigintType :
1025
+ if rv .GetBigInt ().Sign () == 0 {
1026
+ return expt
1027
+ }
1028
+
931
1029
lb := lv .GetBigInt ()
932
1030
lb = big .NewInt (0 ).Rem (lb , rv .GetBigInt ())
933
1031
lv .V = BigintValue {V : lb }
@@ -937,6 +1035,8 @@ func remAssign(lv, rv *TypedValue) {
937
1035
lv .T ,
938
1036
))
939
1037
}
1038
+
1039
+ return nil
940
1040
}
941
1041
942
1042
// for doOpBand and doOpBandAssign.
0 commit comments