Adds string pool

This commit is contained in:
konsoletyper 2014-07-07 18:00:22 +04:00
parent a32d6d037b
commit 43670ed3ca
3 changed files with 46 additions and 3 deletions

View File

@ -35,8 +35,6 @@ import org.teavm.model.*;
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext { public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext {
private static final MethodReference internRef = new MethodReference("java.lang.String", "intern",
ValueType.object("java.lang.String"));
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz"; private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
private NamingStrategy naming; private NamingStrategy naming;
private SourceWriter writer; private SourceWriter writer;
@ -44,6 +42,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
private ClassLoader classLoader; private ClassLoader classLoader;
private boolean minifying; private boolean minifying;
private Map<MethodReference, InjectorHolder> injectorMap = new HashMap<>(); private Map<MethodReference, InjectorHolder> injectorMap = new HashMap<>();
private Map<String, Integer> stringPoolMap = new HashMap<>();
private List<String> stringPool = new ArrayList<>();
private Properties properties = new Properties(); private Properties properties = new Properties();
private ServiceRepository services; private ServiceRepository services;
@ -107,6 +107,24 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
this.properties.putAll(properties); this.properties.putAll(properties);
} }
public void renderStringPool() throws RenderingException {
if (stringPool.isEmpty()) {
return;
}
try {
writer.append("$rt_stringPool([");
for (int i = 0; i < stringPool.size(); ++i) {
if (i > 0) {
writer.append(',').ws();
}
writer.append('"').append(escapeString(stringPool.get(i))).append('"');
}
writer.append("]);").newLine();
} catch (IOException e) {
throw new RenderingException("IO error", e);
}
}
public void renderRuntime() throws RenderingException { public void renderRuntime() throws RenderingException {
try { try {
renderRuntimeCls(); renderRuntimeCls();
@ -114,6 +132,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
renderRuntimeUnwrapString(); renderRuntimeUnwrapString();
renderRuntimeObjcls(); renderRuntimeObjcls();
renderRuntimeNullCheck(); renderRuntimeNullCheck();
renderRuntimeIntern();
} catch (NamingException e) { } catch (NamingException e) {
throw new RenderingException("Error rendering runtime methods. See a cause for details", e); throw new RenderingException("Error rendering runtime methods. See a cause for details", e);
} catch (IOException e) { } catch (IOException e) {
@ -199,6 +218,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.outdent().append("}").newLine(); writer.outdent().append("}").newLine();
} }
private void renderRuntimeIntern() throws IOException {
writer.append("$rt_intern = function(str) {").indent().softNewLine();
writer.append("return ").appendMethodBody(new MethodReference(String.class, "intern", String.class))
.append("(str);").softNewLine();
writer.outdent().append("}").newLine();
}
private void renderRuntimeObjcls() throws IOException { private void renderRuntimeObjcls() throws IOException {
writer.append("$rt_objcls = function() { return ").appendClass("java.lang.Object").append("; }").newLine(); writer.append("$rt_objcls = function() { return ").appendClass("java.lang.Object").append("; }").newLine();
} }
@ -972,7 +998,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
ValueType type = (ValueType)cst; ValueType type = (ValueType)cst;
return "$rt_cls(" + typeToClsString(naming, type) + ")"; return "$rt_cls(" + typeToClsString(naming, type) + ")";
} else if (cst instanceof String) { } else if (cst instanceof String) {
return naming.getFullNameFor(internRef) + "($rt_str(\"" + escapeString((String)cst) + "\"))"; String string = (String)cst;
Integer index = stringPoolMap.get(string);
if (index == null) {
index = stringPool.size();
stringPool.add(string);
stringPoolMap.put(string, index);
}
return "$rt_s(" + index + ")";
} else if (cst instanceof Long) { } else if (cst instanceof Long) {
long value = (Long)cst; long value = (Long)cst;
if (value == 0) { if (value == 0) {

View File

@ -356,6 +356,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
listener.afterClass(cls); listener.afterClass(cls);
} }
} }
renderer.renderStringPool();
for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) { for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) {
sourceWriter.append(entry.getKey()).ws().append("=").ws().appendMethodBody(entry.getValue().reference) sourceWriter.append(entry.getKey()).ws().append("=").ws().appendMethodBody(entry.getValue().reference)
.append(";").softNewLine(); .append(";").softNewLine();

View File

@ -381,6 +381,15 @@ function $rt_virtualMethods(cls) {
} }
} }
} }
function $rt_stringPool(strings) {
$rt_stringPool_instance = new Array(strings.length);
for (var i = 0; i < strings.length; ++i) {
$rt_stringPool_instance[i] = $rt_intern($rt_str(strings[i]));
}
}
function $rt_s(index) {
return $rt_stringPool_instance[index];
}
Long = function(lo, hi) { Long = function(lo, hi) {
this.lo = lo | 0; this.lo = lo | 0;