Skip to content

Commit

Permalink
Fix one too many pops arising from string concat invoke dynamic (#1740)
Browse files Browse the repository at this point in the history
* Fix one too many pops arising from string concat invoke dynamic

* Fixes #1394
  • Loading branch information
srikanth-sankaran authored and noopur2507 committed Dec 15, 2023
1 parent 20ef68e commit ad593d4
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2614,12 +2614,14 @@ public void generateReturnBytecode(Expression expression) {
public void invokeDynamicForStringConcat(StringBuilder recipe, List<TypeBinding> arguments) {
int invokeDynamicNumber = this.classFile.recordBootstrapMethod(recipe.toString());
StringBuilder signature = new StringBuilder("("); //$NON-NLS-1$
for(int i = 0; i < arguments.size(); i++) {
signature.append(arguments.get(i).signature());
int argsSize = 0;
for (TypeBinding argument : arguments) {
signature.append(argument.signature());
argsSize += TypeIds.getCategory(argument.id);
}
signature.append(")Ljava/lang/String;"); //$NON-NLS-1$
this.invokeDynamic(invokeDynamicNumber,
2,
argsSize,
1, // int
ConstantPool.ConcatWithConstants,
signature.toString().toCharArray(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ public void test009() throws Exception {

String expectedOutput9OrLater =
" // Method descriptor #15 ([Ljava/lang/String;)V\n" +
" // Stack: 2, Locals: 4\n" +
" // Stack: 3, Locals: 4\n" +
" public static void main(java.lang.String[] args);\n" +
" 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
" 3 ldc <String \"1\"> [22]\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36615,7 +36615,7 @@ public void test1066() throws Exception {
// check presence of checkcast
String expectedOutput;
if (this.complianceLevel >= ClassFileConstants.JDK9) {
expectedOutput = " // Stack: 3, Locals: 8\n" +
expectedOutput = " // Stack: 4, Locals: 8\n" +
" public static void main(java.lang.String[] args);\n" +
" 0 new X [1]\n" +
" 3 dup\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public void test002() throws IOException, ClassFormatException {
},
"one=1"
);
String expectedOutput = " // Stack: 2, Locals: 3\n" +
String expectedOutput = " // Stack: 3, Locals: 3\n" +
" public void foo();\n" +
" 0 iconst_1\n" +
" 1 istore_1 [one]\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6329,4 +6329,123 @@ public void testGH520() throws Exception {
"m cannot be resolved\n" +
"----------\n");
}
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1394
// switch statement with yield and try/catch produces EmptyStackException
public void testGHI1394() {
Map<String, String> options = getCompilerOptions();
options.put(CompilerOptions.OPTION_UseStringConcatFactory, CompilerOptions.ENABLED);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n"
+ " protected static int switchWithYield() {\n"
+ " String myStringNumber = \"1\";\n"
+ " return switch (myStringNumber) {\n"
+ " case \"1\" -> {\n"
+ " try {\n"
+ " yield Integer.parseInt(myStringNumber);\n"
+ " } catch (NumberFormatException e) {\n"
+ " throw new RuntimeException(\"Failed parsing number\", e); //$NON-NLS-1$\n"
+ " }\n"
+ " }\n"
+ " default -> throw new IllegalArgumentException(\"Unexpected value: \" + myStringNumber);\n"
+ " };\n"
+ " }\n"
+ " public static void main(String[] args) {\n"
+ " System.out.println(switchWithYield());\n"
+ " }\n"
+ "} "
},
"1",
options);
}
public void testGHI1394_2() {
Map<String, String> options = getCompilerOptions();
options.put(CompilerOptions.OPTION_UseStringConcatFactory, CompilerOptions.ENABLED);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n"
+ " static String myStringNumber = \"1\";\n"
+ " protected static int switchWithYield() {\n"
+ " return switch (myStringNumber) {\n"
+ " case \"10\" -> {\n"
+ " try {\n"
+ " yield Integer.parseInt(myStringNumber);\n"
+ " } catch (NumberFormatException e) {\n"
+ " throw new RuntimeException(\"Failed parsing number\", e); //$NON-NLS-1$\n"
+ " }\n"
+ " }\n"
+ " default -> throw new IllegalArgumentException(\"Unexpected value: \" + myStringNumber);\n"
+ " };\n"
+ " }\n"
+ " public static void main(String[] args) {\n"
+ " try {\n"
+ " System.out.println(switchWithYield());\n"
+ " } catch(IllegalArgumentException iae) {\n"
+ " if (!iae.getMessage().equals(\"Unexpected value: \" + myStringNumber))\n"
+ " throw iae;\n"
+ " }\n"
+ " System.out.println(\"Done\");\n"
+ " }\n"
+ "} "
},
"Done",
options);
}
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1394
// switch statement with yield and try/catch produces EmptyStackException
public void testGHI1394_min() {
Map<String, String> options = getCompilerOptions();
options.put(CompilerOptions.OPTION_UseStringConcatFactory, CompilerOptions.ENABLED);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" static int foo() {\n" +
" int x = 1;\n" +
" return switch (x) {\n" +
" case 1 -> {\n" +
" try {\n" +
" yield x;\n" +
" } finally {\n" +
" \n" +
" }\n" +
" }\n" +
" default -> throw new RuntimeException(\"\" + x + \" \".toLowerCase());\n" +
" };\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo());\n" +
" }\n" +
"}\n"
},
"1",
options);
}
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1727
// Internal compiler error: java.util.EmptyStackException
public void testGHI1727() {
if (this.complianceLevel < ClassFileConstants.JDK21)
return;
this.runConformTest(
new String[] {
"X.java",
"class X {\n" +
" private Object foo(Object value) {\n" +
" return switch (value) {\n" +
" case String string -> {\n" +
" try {\n" +
" yield string;\n" +
" } catch (IllegalArgumentException exception) {\n" +
" yield string;\n" +
" }\n" +
" }\n" +
" default -> throw new IllegalArgumentException(\"Argument of type \" + value.getClass());\n" +
" };\n" +
" }\n" +
"}\n"
},
"");
}
}

0 comments on commit ad593d4

Please sign in to comment.