@@ -691,6 +691,92 @@ public void xorValues() {
691691 }
692692 }
693693
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+
694780 public void jump (Label endLabel ) {
695781 var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
696782 mv .visitJumpInsn (Opcodes .GOTO , endLabel );
@@ -849,7 +935,8 @@ public void newArray(Type type) {
849935 var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
850936 Context context = getContext ();
851937 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 );
853940 mv .visitTypeInsn (ANEWARRAY , type .getInternalName ());
854941
855942 context .push (Type .getType ("[" + type .getDescriptor ()));
@@ -892,11 +979,75 @@ public void returnLong() {
892979 mv .visitInsn (LRETURN );
893980 }
894981
895- public void returnFloat () {
982+ public void returnFloatValues () {
896983 Context context = getContext ();
897984 context .pop (Type .FLOAT_TYPE );
898985
899986 var mv = pc .mv == null ? pc .rootInitMv : pc .mv ;
900987 mv .visitInsn (FRETURN );
901988 }
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+ }
9021053}
0 commit comments