diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index c21f11d..48e7d3f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler.modules.decompiler; import org.jetbrains.java.decompiler.code.CodeConstants; @@ -618,8 +604,17 @@ public class ExprProcessor implements CodeConstants { stack.pop(); break; case opc_pop: + stack.pop(); + break; case opc_pop2: + if (stack.getByOffset(-1).getExprType().stackSize == 1) { + // Since value at the top of the stack is a value of category 1 (JVMS9 2.11.1) + // we should remove one more item from the stack. + // See JVMS9 pop2 chapter. + stack.pop(); + } stack.pop(); + break; } } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index fd48f0d..2e6c819 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler; import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; @@ -111,6 +97,10 @@ public class SingleClassesTest { @Test public void testLambdaParams() { doTest("pkg/TestLambdaParams"); } @Test public void testInterfaceMethods() { doTest("pkg/TestInterfaceMethods"); } @Test public void testConstType() { doTest("pkg/TestConstType"); } + @Test public void testPop2OneDoublePop2() { doTest("pkg/TestPop2OneDoublePop2"); } + @Test public void testPop2OneLongPop2() { doTest("pkg/TestPop2OneLongPop2"); } + @Test public void testPop2TwoIntPop2() { doTest("pkg/TestPop2TwoIntPop2"); } + @Test public void testPop2TwoIntTwoPop() { doTest("pkg/TestPop2TwoIntTwoPop"); } // TODO: fix all below //@Test public void testPackageInfo() { doTest("pkg/package-info"); } diff --git a/testData/classes/pkg/TestPop2OneDoublePop2.class b/testData/classes/pkg/TestPop2OneDoublePop2.class new file mode 100644 index 0000000..1c41f76 Binary files /dev/null and b/testData/classes/pkg/TestPop2OneDoublePop2.class differ diff --git a/testData/classes/pkg/TestPop2OneLongPop2.class b/testData/classes/pkg/TestPop2OneLongPop2.class new file mode 100644 index 0000000..d19cfde Binary files /dev/null and b/testData/classes/pkg/TestPop2OneLongPop2.class differ diff --git a/testData/classes/pkg/TestPop2TwoIntPop2.class b/testData/classes/pkg/TestPop2TwoIntPop2.class new file mode 100644 index 0000000..f227a65 Binary files /dev/null and b/testData/classes/pkg/TestPop2TwoIntPop2.class differ diff --git a/testData/classes/pkg/TestPop2TwoIntTwoPop.class b/testData/classes/pkg/TestPop2TwoIntTwoPop.class new file mode 100644 index 0000000..419a512 Binary files /dev/null and b/testData/classes/pkg/TestPop2TwoIntTwoPop.class differ diff --git a/testData/results/TestPop2OneDoublePop2.dec b/testData/results/TestPop2OneDoublePop2.dec new file mode 100644 index 0000000..95ceaee --- /dev/null +++ b/testData/results/TestPop2OneDoublePop2.dec @@ -0,0 +1,27 @@ +package pkg; + +public class TestPop2OneDoublePop2 { + public static void main(String... var0) { + double var10002 = 3.14159265358D;// 24 + System.out.println(1234567890);// 22 23 26 + }// 27 +} + +class 'pkg/TestPop2OneDoublePop2' { + method 'main ([Ljava/lang/String;)V' { + 0 5 + 3 5 + 5 4 + 9 5 + c 6 + } +} + +Lines mapping: +22 <-> 6 +23 <-> 6 +24 <-> 5 +26 <-> 6 +27 <-> 7 +Not mapped: +25 diff --git a/testData/results/TestPop2OneLongPop2.dec b/testData/results/TestPop2OneLongPop2.dec new file mode 100644 index 0000000..2d78133 --- /dev/null +++ b/testData/results/TestPop2OneLongPop2.dec @@ -0,0 +1,27 @@ +package pkg; + +public class TestPop2OneLongPop2 { + public static void main(String... var0) { + long var10002 = -889275714L;// 24 + System.out.println(1234567890);// 22 23 26 + }// 27 +} + +class 'pkg/TestPop2OneLongPop2' { + method 'main ([Ljava/lang/String;)V' { + 0 5 + 3 5 + 5 4 + 9 5 + c 6 + } +} + +Lines mapping: +22 <-> 6 +23 <-> 6 +24 <-> 5 +26 <-> 6 +27 <-> 7 +Not mapped: +25 diff --git a/testData/results/TestPop2TwoIntPop2.dec b/testData/results/TestPop2TwoIntPop2.dec new file mode 100644 index 0000000..9d1583c --- /dev/null +++ b/testData/results/TestPop2TwoIntPop2.dec @@ -0,0 +1,30 @@ +package pkg; + +public class TestPop2TwoIntPop2 { + public static void main(String... var0) { + char var10002 = '쫾';// 24 + char var10003 = '몾';// 25 + System.out.println(1234567890);// 22 23 27 + }// 28 +} + +class 'pkg/TestPop2TwoIntPop2' { + method 'main ([Ljava/lang/String;)V' { + 0 6 + 3 6 + 5 4 + 7 5 + a 6 + d 7 + } +} + +Lines mapping: +22 <-> 7 +23 <-> 7 +24 <-> 5 +25 <-> 6 +27 <-> 7 +28 <-> 8 +Not mapped: +26 diff --git a/testData/results/TestPop2TwoIntTwoPop.dec b/testData/results/TestPop2TwoIntTwoPop.dec new file mode 100644 index 0000000..aaa360b --- /dev/null +++ b/testData/results/TestPop2TwoIntTwoPop.dec @@ -0,0 +1,31 @@ +package pkg; + +public class TestPop2TwoIntTwoPop { + public static void main(String... var0) { + char var10002 = '쫾';// 24 + char var10003 = '몾';// 25 + System.out.println(1234567890);// 22 23 28 + }// 29 +} + +class 'pkg/TestPop2TwoIntTwoPop' { + method 'main ([Ljava/lang/String;)V' { + 0 6 + 3 6 + 5 4 + 7 5 + b 6 + e 7 + } +} + +Lines mapping: +22 <-> 7 +23 <-> 7 +24 <-> 5 +25 <-> 6 +28 <-> 7 +29 <-> 8 +Not mapped: +26 +27 diff --git a/testData/src/pkg/TestPop2OneDoublePop2.jasm b/testData/src/pkg/TestPop2OneDoublePop2.jasm new file mode 100644 index 0000000..6f7d5f6 --- /dev/null +++ b/testData/src/pkg/TestPop2OneDoublePop2.jasm @@ -0,0 +1,30 @@ +/** + * This code can be assembled with asmtools + * using asmtools jasm -g *.jasm command line. + */ +package pkg; + +super public class TestPop2OneDoublePop2 + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +public static varargs Method main:"([Ljava/lang/String;)V" + stack 4 locals 1 +{ + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + ldc int 1234567890; + ldc2_w double 3.14159265358D; + pop2; + invokevirtual Method java/io/PrintStream.println:"(I)V"; + return; +} + +} // end Class TestPop2OneDoublePop2 diff --git a/testData/src/pkg/TestPop2OneLongPop2.jasm b/testData/src/pkg/TestPop2OneLongPop2.jasm new file mode 100644 index 0000000..62d3179 --- /dev/null +++ b/testData/src/pkg/TestPop2OneLongPop2.jasm @@ -0,0 +1,30 @@ +/** + * This code can be assembled with asmtools + * using asmtools jasm -g *.jasm command line. + */ +package pkg; + +super public class TestPop2OneLongPop2 + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +public static varargs Method main:"([Ljava/lang/String;)V" + stack 4 locals 1 +{ + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + ldc int 1234567890; + ldc2_w long 0xCAFEBABE; + pop2; + invokevirtual Method java/io/PrintStream.println:"(I)V"; + return; +} + +} // end Class TestPop2OneLongPop2 diff --git a/testData/src/pkg/TestPop2TwoIntPop2.jasm b/testData/src/pkg/TestPop2TwoIntPop2.jasm new file mode 100644 index 0000000..4f2ce8e --- /dev/null +++ b/testData/src/pkg/TestPop2TwoIntPop2.jasm @@ -0,0 +1,31 @@ +/** + * This code can be assembled with asmtools + * using asmtools jasm -g *.jasm command line. + */ +package pkg; + +super public class TestPop2TwoIntPop2 + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +public static varargs Method main:"([Ljava/lang/String;)V" + stack 4 locals 1 +{ + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + ldc int 1234567890; + ldc int 0xCAFE; + ldc int 0xBABE; + pop2; + invokevirtual Method java/io/PrintStream.println:"(I)V"; + return; +} + +} // end Class TestPop2TwoIntPop2 diff --git a/testData/src/pkg/TestPop2TwoIntTwoPop.jasm b/testData/src/pkg/TestPop2TwoIntTwoPop.jasm new file mode 100644 index 0000000..c9292da --- /dev/null +++ b/testData/src/pkg/TestPop2TwoIntTwoPop.jasm @@ -0,0 +1,32 @@ +/** + * This code can be assembled with asmtools + * using asmtools jasm -g *.jasm command line. + */ +package pkg; + +super public class TestPop2TwoIntTwoPop + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +public static varargs Method main:"([Ljava/lang/String;)V" + stack 4 locals 1 +{ + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + ldc int 1234567890; + ldc int 0xCAFE; + ldc int 0xBABE; + pop; + pop; + invokevirtual Method java/io/PrintStream.println:"(I)V"; + return; +} + +} // end Class TestPop2TwoIntTwoPop