@@ -691,6 +691,92 @@ public void xorValues() {
691
691
}
692
692
}
693
693
694
+ public void notValue () {
695
+ Context context = getContext ();
696
+ Type value = context .pop ();
697
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
698
+ if (value == Type .INT_TYPE ) {
699
+ mv .visitInsn (ICONST_M1 ); // Push -1
700
+ mv .visitInsn (IXOR ); // Perform value ^ -1
701
+ context .push (Type .INT_TYPE );
702
+ } else if (value == Type .LONG_TYPE ) {
703
+ mv .visitLdcInsn (-1L ); // Push -1 as a long
704
+ mv .visitInsn (LXOR ); // Perform value ^ -1
705
+ context .push (Type .LONG_TYPE );
706
+ } else {
707
+ throw new RuntimeException ("Unsupported not for " + value );
708
+ }
709
+ }
710
+
711
+ public void negateValue () {
712
+ Context context = getContext ();
713
+ Type value = context .pop ();
714
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
715
+ if (value == Type .INT_TYPE ) {
716
+ mv .visitInsn (INEG );
717
+ context .push (Type .INT_TYPE );
718
+ } else if (value == Type .LONG_TYPE ) {
719
+ mv .visitInsn (LNEG );
720
+ context .push (Type .LONG_TYPE );
721
+ } else if (value == Type .DOUBLE_TYPE ) {
722
+ mv .visitInsn (DNEG );
723
+ context .push (Type .DOUBLE_TYPE );
724
+ } else if (value == Type .FLOAT_TYPE ) {
725
+ mv .visitInsn (FNEG );
726
+ context .push (Type .FLOAT_TYPE );
727
+ } else {
728
+ throw new RuntimeException ("Unsupported negate for " + value );
729
+ }
730
+ }
731
+
732
+ public void leftShiftValues () {
733
+ Context context = getContext ();
734
+ Type left = context .pop ();
735
+ Type right = context .pop ();
736
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
737
+ if (left == Type .INT_TYPE && right == Type .INT_TYPE ) {
738
+ mv .visitInsn (ISHL );
739
+ context .push (Type .INT_TYPE );
740
+ } else if (left == Type .LONG_TYPE && right == Type .INT_TYPE ) {
741
+ mv .visitInsn (LSHL );
742
+ context .push (Type .LONG_TYPE );
743
+ } else if (left == Type .INT_TYPE && right == Type .LONG_TYPE ) {
744
+ mv .visitInsn (L2I );
745
+ mv .visitInsn (LSHL );
746
+ context .push (Type .LONG_TYPE );
747
+ } else if (left == Type .LONG_TYPE && right == Type .LONG_TYPE ) {
748
+ mv .visitInsn (L2I );
749
+ mv .visitInsn (LSHL );
750
+ context .push (Type .LONG_TYPE );
751
+ } else {
752
+ throw new RuntimeException ("Unsupported left shift between " + left + " and " + right );
753
+ }
754
+ }
755
+
756
+ public void rightShiftValues () {
757
+ Context context = getContext ();
758
+ Type left = context .pop ();
759
+ Type right = context .pop ();
760
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
761
+ if (left == Type .INT_TYPE && right == Type .INT_TYPE ) {
762
+ mv .visitInsn (ISHR );
763
+ context .push (Type .INT_TYPE );
764
+ } else if (left == Type .LONG_TYPE && right == Type .INT_TYPE ) {
765
+ mv .visitInsn (LSHR );
766
+ context .push (Type .LONG_TYPE );
767
+ } else if (left == Type .INT_TYPE && right == Type .LONG_TYPE ) {
768
+ mv .visitInsn (L2I );
769
+ mv .visitInsn (LSHR );
770
+ context .push (Type .LONG_TYPE );
771
+ } else if (left == Type .LONG_TYPE && right == Type .LONG_TYPE ) {
772
+ mv .visitInsn (L2I );
773
+ mv .visitInsn (LSHR );
774
+ context .push (Type .LONG_TYPE );
775
+ } else {
776
+ throw new RuntimeException ("Unsupported right shift between " + left + " and " + right );
777
+ }
778
+ }
779
+
694
780
public void jump (Label endLabel ) {
695
781
var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
696
782
mv .visitJumpInsn (Opcodes .GOTO , endLabel );
@@ -849,7 +935,8 @@ public void newArray(Type type) {
849
935
var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
850
936
Context context = getContext ();
851
937
Type pop = context .pop ();
852
- if (pop != Type .INT_TYPE && pop != Type .SHORT_TYPE && pop != Type .BYTE_TYPE ) throw new RuntimeException ("Expected stack int, got " + pop );
938
+ if (pop != Type .INT_TYPE && pop != Type .SHORT_TYPE && pop != Type .BYTE_TYPE )
939
+ throw new RuntimeException ("Expected stack int, got " + pop );
853
940
mv .visitTypeInsn (ANEWARRAY , type .getInternalName ());
854
941
855
942
context .push (Type .getType ("[" + type .getDescriptor ()));
@@ -892,11 +979,75 @@ public void returnLong() {
892
979
mv .visitInsn (LRETURN );
893
980
}
894
981
895
- public void returnFloat () {
982
+ public void returnFloatValues () {
896
983
Context context = getContext ();
897
984
context .pop (Type .FLOAT_TYPE );
898
985
899
986
var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
900
987
mv .visitInsn (FRETURN );
901
988
}
989
+
990
+ public void floorDivideValues () {
991
+ Context context = getContext ();
992
+ Type left = context .pop ();
993
+ Type right = context .pop ();
994
+
995
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
996
+ if (left == Type .INT_TYPE && right == Type .INT_TYPE ) {
997
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "floorDiv" , "(II)I" , false );
998
+ context .push (Type .INT_TYPE );
999
+ } else if (left == Type .LONG_TYPE && right == Type .INT_TYPE ) {
1000
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "floorDiv" , "(JI)J" , false );
1001
+ context .push (Type .LONG_TYPE );
1002
+ } else if (left == Type .INT_TYPE && right == Type .LONG_TYPE ) {
1003
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "floorDiv" , "(JI)J" , false );
1004
+ context .push (Type .LONG_TYPE );
1005
+ } else if (left == Type .LONG_TYPE && right == Type .LONG_TYPE ) {
1006
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "floorDiv" , "(JJ)J" , false );
1007
+ context .push (Type .LONG_TYPE );
1008
+ } else {
1009
+ throw new RuntimeException ("Unsupported floorDiv between " + left + " and " + right );
1010
+ }
1011
+ }
1012
+
1013
+ public void powValues () {
1014
+ Context context = getContext ();
1015
+ Type left = context .pop ();
1016
+ Type right = context .pop ();
1017
+
1018
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
1019
+ if (left == Type .INT_TYPE && right == Type .INT_TYPE ) {
1020
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "pow" , "(II)D" , false );
1021
+ context .push (Type .DOUBLE_TYPE );
1022
+ } else if (left == Type .LONG_TYPE && right == Type .INT_TYPE ) {
1023
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "pow" , "(JI)D" , false );
1024
+ context .push (Type .DOUBLE_TYPE );
1025
+ } else if (left == Type .INT_TYPE && right == Type .LONG_TYPE ) {
1026
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "pow" , "(JI)D" , false );
1027
+ context .push (Type .DOUBLE_TYPE );
1028
+ } else if (left == Type .LONG_TYPE && right == Type .LONG_TYPE ) {
1029
+ mv .visitMethodInsn (INVOKESTATIC , "java/lang/Math" , "pow" , "(JJ)D" , false );
1030
+ context .push (Type .DOUBLE_TYPE );
1031
+ } else {
1032
+ throw new RuntimeException ("Unsupported pow between " + left + " and " + right );
1033
+ }
1034
+ }
1035
+
1036
+ public void positiveValue () {
1037
+ Context context = getContext ();
1038
+ Type pop = context .pop ();
1039
+ var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
1040
+ if (pop == Type .BOOLEAN_TYPE ) {
1041
+ // Assume boolean value is on the stack (1 for true, 0 for false)
1042
+ Label isFalse = new Label ();
1043
+ Label end = new Label ();
1044
+
1045
+ mv .visitJumpInsn (IFEQ , isFalse ); // If value == 0 (false), jump
1046
+ mv .visitInsn (ICONST_1 ); // Push 1 for true
1047
+ mv .visitJumpInsn (GOTO , end );
1048
+ mv .visitLabel (isFalse );
1049
+ mv .visitInsn (ICONST_0 ); // Push 0 for false
1050
+ mv .visitLabel (end );
1051
+ }
1052
+ }
902
1053
}
0 commit comments