From 56991af700ef29e6aeaad8a113fa3ca26bf49572 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 19 Dec 2013 12:13:31 +0400 Subject: [PATCH] Adds fixes to make `samples' project to work properly --- .../teavm/classlib/java/io/TPrintStream.java | 23 ++++++++++++++---- .../classlib/java/lang/StringBuilderTest.java | 7 ++++++ .../org/teavm/classlib/java/lang/VMTest.java | 9 ++++++- .../teavm/dependency/DependencyChecker.java | 23 ++++++++++++++---- .../dependency/DependencyGraphBuilder.java | 5 ++++ .../teavm/javascript/JavascriptBuilder.java | 1 - .../teavm/javascript/OptimizingVisitor.java | 5 ++++ .../javascript/ReadWriteStatsBuilder.java | 4 ++++ .../javascript/ReferenceCountingVisitor.java | 3 +++ .../java/org/teavm/javascript/Renderer.java | 12 +++++++++- .../teavm/javascript/StatementGenerator.java | 5 ++++ .../javascript/UnusedVariableEliminator.java | 4 ++++ .../javascript/ast/InitClassStatement.java | 22 +++++++++++++++++ .../teavm/javascript/ast/RenamingVisitor.java | 4 ++++ .../org/teavm/javascript/ast/Statement.java | 6 +++++ .../javascript/ast/StatementVisitor.java | 2 ++ .../instructions/InitClassInstruction.java | 24 +++++++++++++++++++ .../instructions/InstructionVisitor.java | 2 ++ .../model/resource/ClassRefsRenamer.java | 5 ++++ .../teavm/model/util/DefinitionExtractor.java | 4 ++++ .../model/util/InstructionStringifier.java | 5 ++++ .../util/InstructionTransitionExtractor.java | 5 ++++ .../CommonSubexpressionElimination.java | 4 ++++ .../UnusedVariableElimination.java | 4 ++++ .../optimization/VariableEscapeAnalyzer.java | 4 ++++ .../VariableUsageGraphBuilder.java | 4 ++++ .../main/java/org/teavm/parsing/Parser.java | 6 ++--- .../java/org/teavm/parsing/ProgramParser.java | 14 ++++++++++- .../org/teavm/parsing/SSATransformer.java | 4 ++++ .../resources/org/teavm/javascript/runtime.js | 4 ++-- teavm-samples/pom.xml | 16 ++++++------- .../java/org/teavm/samples/HelloWorld.java | 10 ++++++++ 32 files changed, 223 insertions(+), 27 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/javascript/ast/InitClassStatement.java create mode 100644 teavm-core/src/main/java/org/teavm/model/instructions/InitClassInstruction.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java index 1ceba6a99..33a7d2cf6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java @@ -117,7 +117,7 @@ public class TPrintStream extends TFilterOutputStream { private void print(char[] s, int begin, int end) { CharBuffer src = new CharBuffer(s, begin, end); byte[] destBytes = new byte[TMath.max(16, TMath.min(s.length, 1024))]; - ByteBuffer dest = new ByteBuffer(new byte[TMath.max(16, TMath.min(s.length, 1024))]); + ByteBuffer dest = new ByteBuffer(destBytes); while (!src.end()) { charset.encode(src, dest); write(destBytes, 0, dest.position()); @@ -135,13 +135,28 @@ public class TPrintStream extends TFilterOutputStream { printSB(); } + public void println(int i) { + sb.append(i).append('\n'); + printSB(); + } + + public void print(long l) { + sb.append(l); + printSB(); + } + + public void println(long l) { + sb.append(l).append('\n'); + printSB(); + } + public void print(TString s) { - sb.append(s).append('\n'); + sb.append(s); printSB(); } public void println(TString s) { - sb.append(s); + sb.append(s).append('\n'); printSB(); } @@ -152,7 +167,7 @@ public class TPrintStream extends TFilterOutputStream { private void printSB() { char[] buffer = sb.length() > this.buffer.length ? new char[sb.length()] : this.buffer; sb.getChars(0, sb.length(), buffer, 0); - print(buffer); + print(buffer, 0, sb.length()); sb.setLength(0); } } diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/StringBuilderTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/StringBuilderTest.java index 3737ff41d..11b541a47 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/StringBuilderTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/StringBuilderTest.java @@ -43,6 +43,13 @@ public class StringBuilderTest { assertEquals("23", sb.toString()); } + @Test + public void longAppended2() { + StringBuilder sb = new StringBuilder(); + sb.append(2971215073L); + assertEquals("2971215073", sb.toString()); + } + @Test public void negativeLongAppended() { StringBuilder sb = new StringBuilder(); diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/VMTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/VMTest.java index 762876f9c..a874ebc0a 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/VMTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/VMTest.java @@ -1,6 +1,6 @@ package org.teavm.classlib.java.lang; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Test; /** @@ -36,4 +36,11 @@ public class VMTest { assertEquals(11997458712L, a / b); assertEquals(-11997458712L, a / -b); } + + @Test + public void longAdditionWorks() { + long a = 1134903170; + long b = 1836311903; + assertEquals(2971215073L, a + b); + } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index df314b9b6..14251082e 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -146,7 +146,7 @@ public class DependencyChecker { return methodCache.map(methodRef); } - private void initClass(String className) { + public void initClass(String className) { MethodDescriptor clinitDesc = new MethodDescriptor("", ValueType.VOID); while (className != null) { if (initializedClasses.putIfAbsent(className, clinitDesc) != null) { @@ -184,8 +184,7 @@ public class DependencyChecker { for (int i = 0; i < varCount; ++i) { parameterNodes[i] = new DependencyNode(this); if (shouldLog) { - parameterNodes[i].setTag(method.getOwner().getName() + "#" + - method.getName() + method.getDescriptor() + ":" + i); + parameterNodes[i].setTag(method.getOwner().getName() + "#" + method.getDescriptor() + ":" + i); } } DependencyNode resultNode; @@ -194,8 +193,7 @@ public class DependencyChecker { } else { resultNode = new DependencyNode(this); if (shouldLog) { - resultNode.setTag(method.getOwner().getName() + "#" + - method.getName() + MethodDescriptor.get(method) + ":RESULT"); + resultNode.setTag(method.getOwner().getName() + "#" + method.getDescriptor() + ":RESULT"); } } final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this); @@ -236,6 +234,21 @@ public class DependencyChecker { private DependencyNode createFieldNode(FieldReference fieldRef) { initClass(fieldRef.getClassName()); + ClassHolder cls = classSource.getClassHolder(fieldRef.getClassName()); + if (cls == null) { + throw new RuntimeException("Class not found: " + fieldRef.getClassName()); + } + FieldHolder field = cls.getField(fieldRef.getFieldName()); + if (field == null) { + while (cls != null) { + field = cls.getField(fieldRef.getFieldName()); + if (field != null) { + return fieldCache.map(new FieldReference(cls.getName(), fieldRef.getFieldName())); + } + cls = cls.getParent() != null ? classSource.getClassHolder(cls.getParent()) : null; + } + throw new RuntimeException("Field not found: " + fieldRef); + } DependencyNode node = new DependencyNode(this); if (shouldLog) { node.setTag(fieldRef.getClassName() + "#" + fieldRef.getFieldName()); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index eeab37d2d..6c4a192b6 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -334,5 +334,10 @@ class DependencyGraphBuilder { @Override public void visit(EmptyInstruction insn) { } + + @Override + public void visit(InitClassInstruction insn) { + dependencyChecker.initClass(insn.getClassName()); + } }; } diff --git a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java index e388f9174..fef3c10bf 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java @@ -77,7 +77,6 @@ public class JavascriptBuilder { builder.setMinified(minifying); SourceWriter sourceWriter = builder.build(writer); Renderer renderer = new Renderer(sourceWriter, classSource); - renderer.renderRuntime(); dependencyChecker.attachMethodGraph(new MethodReference("java.lang.Class", new MethodDescriptor("createNew", ValueType.object("java.lang.Class")))); dependencyChecker.attachMethodGraph(new MethodReference("java.lang.String", new MethodDescriptor("", diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index c82e5db9f..fbc250e83 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -478,4 +478,9 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { public void visit(IncrementStatement statement) { resultStmt = Statement.increment(statement.getVar(), statement.getAmount()); } + + @Override + public void visit(InitClassStatement statement) { + resultStmt = statement; + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java index 6a1fa952d..9bf75287f 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java @@ -191,4 +191,8 @@ class ReadWriteStatsBuilder implements StatementVisitor, ExprVisitor { reads[statement.getVar()]++; writes[statement.getVar()]++; } + + @Override + public void visit(InitClassStatement statement) { + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java index 679997c87..ff1493e36 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java @@ -100,4 +100,7 @@ class ReferenceCountingVisitor implements StatementVisitor { public void visit(IncrementStatement statement) { } + @Override + public void visit(InitClassStatement statement) { + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 68937b44b..51f93dd53 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -174,7 +174,8 @@ public class Renderer implements ExprVisitor, StatementVisitor { writer.ws().append("};").softNewLine(); writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws().append("function()").ws() .append("{").softNewLine().indent(); - writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws().append("null;").newLine(); + writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws() + .append("function(){};").newLine(); List stubNames = new ArrayList<>(); for (MethodNode method : cls.getMethods()) { renderBody(method); @@ -529,6 +530,15 @@ public class Renderer implements ExprVisitor, StatementVisitor { } } + @Override + public void visit(InitClassStatement statement) { + try { + writer.appendClass(statement.getClassName()).append("_$clinit();").softNewLine(); + } catch (IOException e) { + throw new RenderingException("IO error occured", e); + } + } + public String variableName(int index) { if (index == 0) { return minifying ? "$t" : "$this"; diff --git a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java index 86c0045be..f594d73ee 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java @@ -628,4 +628,9 @@ class StatementGenerator implements InstructionVisitor { private Expr compare(BinaryOperation op, Variable value) { return Expr.binary(op, Expr.var(value.getIndex()), Expr.constant(0)); } + + @Override + public void visit(InitClassInstruction insn) { + statements.add(Statement.initClass(insn.getClassName())); + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java index 7b9f1d8e6..7832f4e17 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java @@ -196,4 +196,8 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor { @Override public void visit(StaticClassExpr expr) { } + + @Override + public void visit(InitClassStatement statement) { + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/InitClassStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/InitClassStatement.java new file mode 100644 index 000000000..e76cbd132 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/InitClassStatement.java @@ -0,0 +1,22 @@ +package org.teavm.javascript.ast; + +/** + * + * @author Alexey Andreev + */ +public class InitClassStatement extends Statement { + private String className; + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + @Override + public void acceptVisitor(StatementVisitor visitor) { + visitor.visit(this); + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java index b3890e565..31d961b03 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java @@ -166,4 +166,8 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor { public void visit(IncrementStatement statement) { statement.setVar(varNames[statement.getVar()]); } + + @Override + public void visit(InitClassStatement statement) { + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/Statement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/Statement.java index 036a0a4be..6175254cd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/Statement.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/Statement.java @@ -63,4 +63,10 @@ public abstract class Statement { public static Statement cond(Expr predicate, Statement consequent) { return cond(predicate, consequent, null); } + + public static Statement initClass(String className) { + InitClassStatement stmt = new InitClassStatement(); + stmt.setClassName(className); + return stmt; + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java index 4db6787c6..67136506a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java @@ -43,4 +43,6 @@ public interface StatementVisitor { void visit(ThrowStatement statement); void visit(IncrementStatement statement); + + void visit(InitClassStatement statement); } diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/InitClassInstruction.java b/teavm-core/src/main/java/org/teavm/model/instructions/InitClassInstruction.java new file mode 100644 index 000000000..89155750a --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/instructions/InitClassInstruction.java @@ -0,0 +1,24 @@ +package org.teavm.model.instructions; + +import org.teavm.model.Instruction; + +/** + * + * @author Alexey Andreev + */ +public class InitClassInstruction extends Instruction { + private String className; + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + @Override + public void acceptVisitor(InstructionVisitor visitor) { + visitor.visit(this); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/InstructionVisitor.java b/teavm-core/src/main/java/org/teavm/model/instructions/InstructionVisitor.java index c7c277319..d53d5534c 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/InstructionVisitor.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/InstructionVisitor.java @@ -68,4 +68,6 @@ public interface InstructionVisitor { void visit(InvokeInstruction insn); void visit(IsInstanceInstruction insn); + + void visit(InitClassInstruction insn); } diff --git a/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java b/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java index 33259996a..a108391c2 100644 --- a/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java +++ b/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java @@ -249,4 +249,9 @@ class ClassRefsRenamer implements InstructionVisitor { public void visit(IsInstanceInstruction insn) { insn.setType(rename(insn.getType())); } + + @Override + public void visit(InitClassInstruction insn) { + insn.setClassName(classNameMapper.map(insn.getClassName())); + } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/DefinitionExtractor.java b/teavm-core/src/main/java/org/teavm/model/util/DefinitionExtractor.java index d2401b9ab..1413d4c29 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/DefinitionExtractor.java +++ b/teavm-core/src/main/java/org/teavm/model/util/DefinitionExtractor.java @@ -177,4 +177,8 @@ public class DefinitionExtractor implements InstructionVisitor { public void visit(CloneArrayInstruction insn) { definedVariables = new Variable[] { insn.getReceiver() }; } + + @Override + public void visit(InitClassInstruction insn) { + } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java b/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java index bfdb7a9ce..be039b0bf 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java +++ b/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java @@ -331,4 +331,9 @@ public class InstructionStringifier implements InstructionVisitor { sb.append("@").append(insn.getReceiver().getIndex()).append("@") .append(insn.getArray().getIndex()).append(".clone()"); } + + @Override + public void visit(InitClassInstruction insn) { + sb.append("initclass ").append(insn.getClassName()); + } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/InstructionTransitionExtractor.java b/teavm-core/src/main/java/org/teavm/model/util/InstructionTransitionExtractor.java index 32faadf33..c266bc14b 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/InstructionTransitionExtractor.java +++ b/teavm-core/src/main/java/org/teavm/model/util/InstructionTransitionExtractor.java @@ -179,4 +179,9 @@ public class InstructionTransitionExtractor implements InstructionVisitor { public void visit(CloneArrayInstruction insn) { targets = null; } + + @Override + public void visit(InitClassInstruction insn) { + targets = null; + } } diff --git a/teavm-core/src/main/java/org/teavm/optimization/CommonSubexpressionElimination.java b/teavm-core/src/main/java/org/teavm/optimization/CommonSubexpressionElimination.java index d4a00f33a..9c2657cf5 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/CommonSubexpressionElimination.java +++ b/teavm-core/src/main/java/org/teavm/optimization/CommonSubexpressionElimination.java @@ -358,5 +358,9 @@ public class CommonSubexpressionElimination implements MethodOptimization { insn.setValue(program.variableAt(val)); bind(insn.getReceiver().getIndex(), "@" + val + " :? " + insn.getType()); } + + @Override + public void visit(InitClassInstruction insn) { + } }; } diff --git a/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java b/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java index 24f64c65e..77ba05786 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java +++ b/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java @@ -225,5 +225,9 @@ public class UnusedVariableElimination implements MethodOptimization { public void visit(IsInstanceInstruction insn) { requestUsage(insn.getReceiver()); } + + @Override + public void visit(InitClassInstruction insn) { + } } } diff --git a/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java b/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java index 09ea0f861..dac5dd7a4 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java +++ b/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java @@ -178,5 +178,9 @@ public class VariableEscapeAnalyzer { @Override public void visit(IsInstanceInstruction insn) { } + + @Override + public void visit(InitClassInstruction insn) { + } } } diff --git a/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java b/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java index 73ea2acd4..cbd0672c8 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java @@ -183,5 +183,9 @@ public class VariableUsageGraphBuilder { public void visit(IsInstanceInstruction insn) { use(insn.getReceiver(), insn.getValue()); } + + @Override + public void visit(InitClassInstruction insn) { + } } } diff --git a/teavm-core/src/main/java/org/teavm/parsing/Parser.java b/teavm-core/src/main/java/org/teavm/parsing/Parser.java index 432b13499..d7e046ce2 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/Parser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/Parser.java @@ -13,12 +13,12 @@ import org.teavm.optimization.UnreachableBasicBlockEliminator; * @author Alexey Andreev */ public class Parser { - public static MethodHolder parseMethod(MethodNode node) { + public static MethodHolder parseMethod(MethodNode node, String className) { ValueType[] signature = MethodDescriptor.parseSignature(node.desc); MethodHolder method = new MethodHolder(node.name, signature); parseModifiers(node.access, method); ProgramParser programParser = new ProgramParser(); - Program program = programParser.parse(node); + Program program = programParser.parse(node, className); new UnreachableBasicBlockEliminator().optimize(program); SSATransformer ssaProducer = new SSATransformer(); ssaProducer.transformToSSA(program, method.getParameterTypes()); @@ -44,7 +44,7 @@ public class Parser { } for (Object obj : node.methods) { MethodNode methodNode = (MethodNode)obj; - cls.addMethod(parseMethod(methodNode)); + cls.addMethod(parseMethod(methodNode, node.name)); } parseAnnotations(cls.getAnnotations(), node); return cls; diff --git a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java index 145dfd3ad..18bc8ae6e 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -42,6 +42,7 @@ public class ProgramParser { private int[] localsMap; private int minLocal; private Program program; + private String currentClassName; private static class Step { public final int source; @@ -53,8 +54,9 @@ public class ProgramParser { } } - public Program parse(MethodNode method) { + public Program parse(MethodNode method, String className) { program = new Program(); + this.currentClassName = className; InsnList instructions = method.instructions; if (instructions.size() == 0) { return program; @@ -1402,6 +1404,11 @@ public class ProgramParser { if (desc.equals("D") || desc.equals("J")) { currentDepth++; } + if (!owner.equals(currentClassName)) { + InitClassInstruction initInsn = new InitClassInstruction(); + initInsn.setClassName(ownerCls); + builder.add(initInsn); + } GetFieldInstruction insn = new GetFieldInstruction(); insn.setField(new FieldReference(ownerCls, name)); insn.setFieldType(type); @@ -1413,6 +1420,11 @@ public class ProgramParser { if (desc.equals("D") || desc.equals("J")) { currentDepth--; } + if (!owner.equals(currentClassName)) { + InitClassInstruction initInsn = new InitClassInstruction(); + initInsn.setClassName(ownerCls); + builder.add(initInsn); + } int value = --currentDepth; PutFieldInstruction insn = new PutFieldInstruction(); insn.setField(new FieldReference(ownerCls, name)); diff --git a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java index 95e656634..d3373ca2d 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java +++ b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java @@ -374,5 +374,9 @@ public class SSATransformer { insn.setArray(use(insn.getArray())); insn.setReceiver(define(insn.getReceiver())); } + + @Override + public void visit(InitClassInstruction insn) { + } }; } diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index e926a7980..8fbbcd3c7 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -250,7 +250,7 @@ $rt_methodStubs = function(clinit, names) { } $rt_stdoutBuffer = ""; $rt_putStdout = function(ch) { - if (ch == '\n') { + if (ch === 0xA) { if (console) { console.info($rt_stdoutBuffer); } @@ -261,7 +261,7 @@ $rt_putStdout = function(ch) { } $rt_stderrBuffer = ""; $rt_putStderr = function(ch) { - if (ch == '\n') { + if (ch === 0xA) { if (console) { console.info($rt_stderrBuffer); } diff --git a/teavm-samples/pom.xml b/teavm-samples/pom.xml index 0138fde8b..bdfc89456 100644 --- a/teavm-samples/pom.xml +++ b/teavm-samples/pom.xml @@ -8,21 +8,19 @@ teavm-samples - - - org.teavm - teavm-classlib - 0.0.1-SNAPSHOT - provided - - - org.teavm teavm-maven-plugin ${project.version} + + + org.teavm + teavm-classlib + 0.0.1-SNAPSHOT + + generate-javascript diff --git a/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java b/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java index e8789289b..7bbf1febc 100644 --- a/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java +++ b/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java @@ -7,5 +7,15 @@ package org.teavm.samples; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, world!"); + System.out.println("Here is the Fibonacci sequence:"); + long a = 0; + long b = 1; + for (int i = 0; i < 70; ++i) { + System.out.println(a); + long c = a + b; + a = b; + b = c; + } + System.out.println("And so on..."); } }