Skip to content
Permalink
Browse files
JDK11 indy string concatenation handler
  • Loading branch information
Jaroslav Tulach committed Jul 18, 2021
1 parent 54a04c7 commit 95c99ef9f90e0bc3d1d4fdac370c033ed48f1f25
Showing 4 changed files with 77 additions and 0 deletions.
@@ -45,6 +45,7 @@ protected ByteCodeToJavaScript(final Appendable out) {
this.output = out;
this.indyHandlers = new IndyHandler[] {
new MetafactoryHandler(),
new StringConcatHandler(),
};
}

@@ -0,0 +1,70 @@
/**
* Back 2 Browser Bytecode Translator
* Copyright (C) 2012-2018 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://opensource.org/licenses/GPL-2.0.
*/
package org.apidesign.vm4brwsr;

import java.io.IOException;

final class StringConcatHandler extends IndyHandler {
StringConcatHandler() {
super("java/lang/invoke/StringConcatFactory", "makeConcatWithConstants");
}

@Override
protected boolean handle(Ctx ctx) throws IOException {
final int fixedArgsCount;
String recipe = ctx.bm.clazz.StringValue(ctx.bm.args[0]);
final String sig = ctx.mt[1];
StringBuilder sigB = new StringBuilder();
StringBuilder cnt = new StringBuilder();
char[] returnType = {'V'};
ByteCodeToJavaScript.countArgs(sig, returnType, sigB, cnt);
assert returnType[0] == 'L';

fixedArgsCount = cnt.length();
final CharSequence[] vars = new CharSequence[fixedArgsCount];
for (int j = fixedArgsCount - 1; j >= 0; --j) {
vars[j] = ctx.stackMapper.popValue();
}


ctx.stackMapper.flush(ctx.out);

final Variable stringVar = ctx.stackMapper.pushA();
ctx.out.append("var ").append(stringVar).append(" = ");

StringBuilder sep = new StringBuilder();
sep.append("'");
int atVar = 0;
for (int j = 0; j < recipe.length(); j++) {
char ch = recipe.charAt(j);
switch (ch) {
case '\1':
ctx.out.append(sep).append("' + ");
ctx.out.append(vars[atVar++]);
sep = new StringBuilder(" + '");
break;
case '\2':
throw new IllegalStateException("#2 stackvalue not supported yet");
default:
sep.append(ch);
}
}
ctx.out.append(sep).append("'");
return true;
}
}
@@ -35,6 +35,7 @@
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<target>11</target>
<testTarget>11</testTarget>
</configuration>
</plugin>
<plugin>
@@ -32,6 +32,11 @@ public String callProtectedMethod() throws Exception {
return NestMates.protectedMessage();
}

@Compare
public String concatenateBothMethods() throws Exception {
return NestMates.privateMessage() + NestMates.protectedMessage();
}

@Factory
public static Object[] create() {
return VMTest.create(NestMatesTest.class);

0 comments on commit 95c99ef

Please sign in to comment.