Fix compound assignment with string concats. in Java 9 there is no stringbuilder on stack! This closes #18929

This commit is contained in:
Uwe Schindler 2016-06-17 00:30:09 +02:00
parent d741e65da1
commit a7aedbe0a1
3 changed files with 11 additions and 5 deletions

View File

@ -209,15 +209,20 @@ public final class MethodWriter extends GeneratorAdapter {
} }
} }
public void writeNewStrings() { /** Starts a new string concat.
* @return the size of arguments pushed to stack (the object that does string concats, e.g. a StringBuilder)
*/
public int writeNewStrings() {
if (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE != null) { if (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE != null) {
// Java 9+: we just push our argument collector onto deque // Java 9+: we just push our argument collector onto deque
stringConcatArgs.push(new ArrayList<>()); stringConcatArgs.push(new ArrayList<>());
return 0; // nothing added to stack
} else { } else {
// Java 8: create a StringBuilder in bytecode // Java 8: create a StringBuilder in bytecode
newInstance(STRINGBUILDER_TYPE); newInstance(STRINGBUILDER_TYPE);
dup(); dup();
invokeConstructor(STRINGBUILDER_TYPE, STRINGBUILDER_CONSTRUCTOR); invokeConstructor(STRINGBUILDER_TYPE, STRINGBUILDER_CONSTRUCTOR);
return 1; // StringBuilder on stack
} }
} }

View File

@ -131,7 +131,7 @@ public final class WriterConstants {
// not Java 9 - we set it null, so MethodWriter uses StringBuilder: // not Java 9 - we set it null, so MethodWriter uses StringBuilder:
bs = null; bs = null;
} }
INDY_STRING_CONCAT_BOOTSTRAP_HANDLE = null; // Disabled until https://github.com/elastic/elasticsearch/issues/18929 INDY_STRING_CONCAT_BOOTSTRAP_HANDLE = bs;
} }
public final static int MAX_INDY_STRING_CONCAT_ARGS = 200; public final static int MAX_INDY_STRING_CONCAT_ARGS = 200;

View File

@ -294,8 +294,9 @@ public final class EChain extends AExpression {
// track types going onto the stack. This must be done before the // track types going onto the stack. This must be done before the
// links in the chain are read because we need the StringBuilder to // links in the chain are read because we need the StringBuilder to
// be placed on the stack ahead of any potential concatenation arguments. // be placed on the stack ahead of any potential concatenation arguments.
int catElementStackSize = 0;
if (cat) { if (cat) {
writer.writeNewStrings(); catElementStackSize = writer.writeNewStrings();
} }
ALink last = links.get(links.size() - 1); ALink last = links.get(links.size() - 1);
@ -312,7 +313,7 @@ public final class EChain extends AExpression {
// Handle the case where we are doing a compound assignment // Handle the case where we are doing a compound assignment
// representing a String concatenation. // representing a String concatenation.
writer.writeDup(link.size, 1); // dup the StringBuilder writer.writeDup(link.size, catElementStackSize); // dup the top element and insert it before concat helper on stack
link.load(writer); // read the current link's value link.load(writer); // read the current link's value
writer.writeAppendStrings(link.after); // append the link's value using the StringBuilder writer.writeAppendStrings(link.after); // append the link's value using the StringBuilder
@ -323,7 +324,7 @@ public final class EChain extends AExpression {
writer.writeAppendStrings(expression.actual); // append the expression's value unless it's also a concatenation writer.writeAppendStrings(expression.actual); // append the expression's value unless it's also a concatenation
} }
writer.writeToStrings(); // put the value of the StringBuilder on the stack writer.writeToStrings(); // put the value for string concat onto the stack
writer.writeCast(back); // if necessary, cast the String to the lhs actual type writer.writeCast(back); // if necessary, cast the String to the lhs actual type
if (link.load) { if (link.load) {