From 8bfcb5f086fb446da5757ab128d855b90deb3a0b Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 16 Sep 2016 22:56:50 +0300 Subject: [PATCH] frontend: fix support of Integer.TYPE, Long.TYPE, etc. --- .../backend/javascript/JavaScriptTarget.java | 1 + .../javascript/rendering/Renderer.java | 4 +- .../main/java/org/teavm/parsing/Parser.java | 7 --- .../java/org/teavm/parsing/ProgramParser.java | 47 ++++++++++++++++--- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java b/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java index 4bb697c2e..7348ae8a3 100644 --- a/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java +++ b/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java @@ -263,6 +263,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost { renderer.renderRuntime(); renderer.render(clsNodes); renderer.renderStringPool(); + renderer.renderStringConstants(); for (Map.Entry entry : controller.getEntryPoints().entrySet()) { sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws(); MethodReference ref = entry.getValue().getReference(); diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java index fac7b76c8..8e082c21b 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java @@ -147,7 +147,7 @@ public class Renderer implements RenderingManager { try { for (PostponedFieldInitializer initializer : postponedFieldInitializers) { writer.appendStaticField(initializer.field).ws().append("=").ws() - .append(constantToString(initializer.value)).append(";").softNewLine(); + .append(context.constantToString(initializer.value)).append(";").softNewLine(); } } catch (IOException e) { throw new RenderingException("IO error", e); @@ -331,7 +331,7 @@ public class Renderer implements RenderingManager { } FieldReference fieldRef = new FieldReference(cls.getName(), field.getName()); if (value instanceof String) { - constantToString(value); + context.constantToString(value); postponedFieldInitializers.add(new PostponedFieldInitializer(fieldRef, (String) value)); value = null; } diff --git a/core/src/main/java/org/teavm/parsing/Parser.java b/core/src/main/java/org/teavm/parsing/Parser.java index 016d4bd54..4b4c8be53 100644 --- a/core/src/main/java/org/teavm/parsing/Parser.java +++ b/core/src/main/java/org/teavm/parsing/Parser.java @@ -49,7 +49,6 @@ import org.teavm.model.Phi; import org.teavm.model.PrimitiveType; import org.teavm.model.Program; import org.teavm.model.ReferenceCache; -import org.teavm.model.TryCatchJoint; import org.teavm.model.ValueType; import org.teavm.model.Variable; import org.teavm.model.optimization.UnreachableBasicBlockEliminator; @@ -122,12 +121,10 @@ public class Parser { debugNames = newDebugNames; } for (Variable definedVar : defExtractor.getDefinedVariables()) { - /* int sourceVar = phiUpdater.getSourceVariable(definedVar.getIndex()); if (sourceVar >= 0) { varMap.put(sourceVar, definedVar.getIndex()); } - */ } for (Map.Entry debugName : debugNames.entrySet()) { int receiver = varMap.getOrDefault(debugName.getKey(), -1); @@ -175,12 +172,10 @@ public class Parser { for (Phi phi : block.getPhis()) { int receiver = phi.getReceiver().getIndex(); - /* int sourceVar = phiUpdater.getSourceVariable(receiver); if (sourceVar >= 0) { varMap.put(sourceVar, receiver); } - */ } result[node] = new IntIntOpenHashMap(varMap); @@ -188,12 +183,10 @@ public class Parser { for (Instruction insn : block.getInstructions()) { insn.acceptVisitor(defExtractor); for (Variable definedVar : defExtractor.getDefinedVariables()) { - /* int sourceVar = phiUpdater.getSourceVariable(definedVar.getIndex()); if (sourceVar >= 0) { varMap.put(sourceVar, definedVar.getIndex()); } - */ } } diff --git a/core/src/main/java/org/teavm/parsing/ProgramParser.java b/core/src/main/java/org/teavm/parsing/ProgramParser.java index 9586023b1..34069b9b6 100644 --- a/core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -1682,13 +1682,21 @@ public class ProgramParser { break; } case Opcodes.GETSTATIC: { - ValueType type = referenceCache.parseValueTypeCached(desc); - int value = desc.equals("D") || desc.equals("J") ? pushDouble() : pushSingle(); - GetFieldInstruction insn = new GetFieldInstruction(); - insn.setField(referenceCache.getCached(new FieldReference(ownerCls, name))); - insn.setFieldType(type); - insn.setReceiver(getVariable(value)); - addInstruction(insn); + ValueType primitiveClassLiteral = getPrimitiveTypeField(owner + "." + name); + if (primitiveClassLiteral != null) { + ClassConstantInstruction insn = new ClassConstantInstruction(); + insn.setConstant(primitiveClassLiteral); + insn.setReceiver(getVariable(pushSingle())); + addInstruction(insn); + } else { + ValueType type = referenceCache.parseValueTypeCached(desc); + int value = desc.equals("D") || desc.equals("J") ? pushDouble() : pushSingle(); + GetFieldInstruction insn = new GetFieldInstruction(); + insn.setField(referenceCache.getCached(new FieldReference(ownerCls, name))); + insn.setFieldType(type); + insn.setReceiver(getVariable(value)); + addInstruction(insn); + } break; } case Opcodes.PUTSTATIC: { @@ -1763,4 +1771,29 @@ public class ProgramParser { throw new IllegalArgumentException("Unknown handle tag: " + handle.getTag()); } } + + private static ValueType getPrimitiveTypeField(String fieldName) { + switch (fieldName) { + case "java/lang/Boolean.TYPE": + return ValueType.BOOLEAN; + case "java/lang/Byte.TYPE": + return ValueType.BYTE; + case "java/lang/Short.TYPE": + return ValueType.SHORT; + case "java/lang/Character.TYPE": + return ValueType.CHARACTER; + case "java/lang/Integer.TYPE": + return ValueType.INTEGER; + case "java/lang/Long.TYPE": + return ValueType.LONG; + case "java/lang/Float.TYPE": + return ValueType.FLOAT; + case "java/lang/Double.TYPE": + return ValueType.DOUBLE; + case "java/lang/Void.TYPE": + return ValueType.VOID; + default: + return null; + } + } }