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 b55db055f..519c397da 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 @@ -19,6 +19,7 @@ import org.teavm.classlib.impl.charset.ByteBuffer; import org.teavm.classlib.impl.charset.CharBuffer; import org.teavm.classlib.impl.charset.Charset; import org.teavm.classlib.java.lang.TMath; +import org.teavm.classlib.java.lang.TObject; import org.teavm.classlib.java.lang.TString; import org.teavm.classlib.java.lang.TStringBuilder; @@ -175,6 +176,11 @@ public class TPrintStream extends TFilterOutputStream { printSB(); } + public void println(TObject s) { + sb.append(s).append('\n'); + printSB(); + } + public void println() { print('\n'); } diff --git a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java index 477a25121..1fd8cea18 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java @@ -25,14 +25,14 @@ import org.teavm.model.*; */ public class DefaultNamingStrategy implements NamingStrategy { private AliasProvider aliasProvider; - private ClassHolderSource classSource; + private ClassReaderSource classSource; private Map aliases = new HashMap<>(); private Map privateAliases = new HashMap<>(); private Map classAliases = new HashMap<>(); private Map fieldAliases = new HashMap<>(); private boolean minifying; - public DefaultNamingStrategy(AliasProvider aliasProvider, ClassHolderSource classSource) { + public DefaultNamingStrategy(AliasProvider aliasProvider, ClassReaderSource classSource) { this.aliasProvider = aliasProvider; this.classSource = classSource; } @@ -62,9 +62,9 @@ public class DefaultNamingStrategy implements NamingStrategy { if (method == null) { throw new NamingException("Can't provide name for method as it was not found: " + origMethod); } - ClassHolder clsHolder = classSource.get(method.getClassName()); - MethodHolder methodHolder = clsHolder.getMethod(method.getDescriptor()); - if (methodHolder.getModifiers().contains(ElementModifier.STATIC) || + ClassReader clsHolder = classSource.get(method.getClassName()); + MethodReader methodHolder = clsHolder.getMethod(method.getDescriptor()); + if (methodHolder.hasModifier(ElementModifier.STATIC) || method.getDescriptor().getName().equals("") || methodHolder.getLevel() == AccessLevel.PRIVATE) { String key = method.toString(); @@ -125,11 +125,11 @@ public class DefaultNamingStrategy implements NamingStrategy { private MethodReference getRealMethod(MethodReference methodRef) { String className = methodRef.getClassName(); while (className != null) { - ClassHolder cls = classSource.get(className); + ClassReader cls = classSource.get(className); if (cls == null) { return null; } - MethodHolder method = cls.getMethod(methodRef.getDescriptor()); + MethodReader method = cls.getMethod(methodRef.getDescriptor()); if (method != null) { if (method.getLevel() == AccessLevel.PRIVATE && !className.equals(methodRef.getClassName())) { return null; @@ -144,7 +144,7 @@ public class DefaultNamingStrategy implements NamingStrategy { private String getRealFieldOwner(String cls, String field) { String initialCls = cls; while (!fieldExists(cls, field)) { - ClassHolder clsHolder = classSource.get(cls); + ClassReader clsHolder = classSource.get(cls); cls = clsHolder.getParent(); if (cls == null) { throw new NamingException("Can't provide name for field as the field not found: " + @@ -155,7 +155,7 @@ public class DefaultNamingStrategy implements NamingStrategy { } private boolean fieldExists(String cls, String field) { - ClassHolder classHolder = classSource.get(cls); + ClassReader classHolder = classSource.get(cls); return classHolder.getField(field) != null; } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java index d1011fb2e..2062ef039 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java @@ -1,7 +1,21 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.teavm.dependency; import org.teavm.model.ClassHolder; -import org.teavm.model.ClassReaderSource; import org.teavm.model.FieldReference; import org.teavm.model.MethodReference; @@ -12,8 +26,6 @@ import org.teavm.model.MethodReference; public interface DependencyAgent extends DependencyInfo { DependencyNode createNode(); - ClassReaderSource getClassSource(); - String generateClassName(); void submitClass(ClassHolder cls); 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 fd06f3b4f..20d44b8cb 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -49,11 +49,11 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { ConcurrentMap missingClasses = new ConcurrentHashMap<>(); ConcurrentMap missingFields = new ConcurrentHashMap<>(); - public DependencyChecker(ClassHolderSource classSource, ClassLoader classLoader) { + public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader) { this(classSource, classLoader, new SimpleFiniteExecutor()); } - public DependencyChecker(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { + public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { this.classSource = new DependencyClassSource(classSource); this.classLoader = classLoader; this.executor = executor; @@ -135,6 +135,10 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { listener.started(this); } + public void addClassTransformer(ClassHolderTransformer transformer) { + classSource.addTransformer(transformer); + } + public void addEntryPoint(MethodReference methodRef, String... argumentTypes) { ValueType[] parameters = methodRef.getDescriptor().getParameterTypes(); if (parameters.length != argumentTypes.length) { @@ -438,14 +442,4 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { sb.append('\n'); } } - - @Override - public Collection getGeneratedClasses() { - Collection classes = classSource.getGeneratedClasses(); - List copies = new ArrayList<>(classes.size()); - for (ClassHolder cls : classes) { - copies.add(ModelUtils.copyClass(cls)); - } - return classes; - } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java index b2394600d..17b6acc46 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java @@ -15,14 +15,18 @@ */ package org.teavm.dependency; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.teavm.common.ConcurrentCachedMapper; import org.teavm.common.Mapper; import org.teavm.model.ClassHolder; +import org.teavm.model.ClassHolderTransformer; import org.teavm.model.ClassReader; import org.teavm.model.ClassReaderSource; +import org.teavm.model.util.ModelUtils; /** * @@ -31,10 +35,11 @@ import org.teavm.model.ClassReaderSource; class DependencyClassSource implements ClassReaderSource { private ClassReaderSource innerSource; private ConcurrentMap generatedClasses = new ConcurrentHashMap<>(); + private List transformers = new ArrayList<>(); private ConcurrentCachedMapper cache = new ConcurrentCachedMapper<>( new Mapper() { @Override public ClassReader map(String preimage) { - return findClass(preimage); + return findAndTransformClass(preimage); } }); @@ -56,15 +61,30 @@ class DependencyClassSource implements ClassReaderSource { } } - private ClassReader findClass(String name) { - ClassReader cls = innerSource.get(name); - if (cls == null) { - cls = generatedClasses.get(name); + private ClassReader findAndTransformClass(String name) { + ClassHolder cls = findClass(name); + if (cls != null && !transformers.isEmpty()) { + for (ClassHolderTransformer transformer : transformers) { + transformer.transformClass(cls, innerSource); + } + cls = ModelUtils.copyClass(cls); } return cls; } + private ClassHolder findClass(String name) { + ClassReader cls = innerSource.get(name); + if (cls != null) { + return ModelUtils.copyClass(cls); + } + return generatedClasses.get(name); + } + public Collection getGeneratedClasses() { return generatedClasses.values(); } + + public void addTransformer(ClassHolderTransformer transformer) { + transformers.add(transformer); + } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java index bfed04ecd..396b0a284 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java @@ -16,7 +16,7 @@ package org.teavm.dependency; import java.util.Collection; -import org.teavm.model.ClassHolder; +import org.teavm.model.ClassReaderSource; import org.teavm.model.FieldReference; import org.teavm.model.MethodReference; @@ -25,6 +25,8 @@ import org.teavm.model.MethodReference; * @author Alexey Andreev */ public interface DependencyInfo { + ClassReaderSource getClassSource(); + boolean isMethodAchievable(MethodReference methodRef); Collection getAchievableMethods(); @@ -36,6 +38,4 @@ public interface DependencyInfo { FieldDependencyInfo getField(FieldReference fieldRef); MethodDependencyInfo getMethod(MethodReference methodRef); - - Collection getGeneratedClasses(); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/Linker.java b/teavm-core/src/main/java/org/teavm/dependency/Linker.java index 75815b4ad..d3240cc34 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/Linker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/Linker.java @@ -19,33 +19,24 @@ import org.teavm.model.*; import org.teavm.model.instructions.GetFieldInstruction; import org.teavm.model.instructions.InvokeInstruction; import org.teavm.model.instructions.PutFieldInstruction; +import org.teavm.model.util.ModelUtils; /** * * @author Alexey Andreev */ public class Linker { - private DependencyInfo dependency; - - public Linker(DependencyInfo dependency) { - this.dependency = dependency; - } - - public ListableClassHolderSource link(ClassHolderSource classes) { + public ListableClassHolderSource link(DependencyInfo dependency) { MutableClassHolderSource cutClasses = new MutableClassHolderSource(); for (String className : dependency.getAchievableClasses()) { - ClassHolder classHolder = classes.get(className); - cutClasses.putClassHolder(classHolder); - link(classHolder); - } - for (ClassHolder generatedClass : dependency.getGeneratedClasses()) { - cutClasses.putClassHolder(generatedClass); - link(generatedClass); + ClassHolder cls = ModelUtils.copyClass(dependency.getClassSource().get(className)); + cutClasses.putClassHolder(cls); + link(dependency, cls); } return cutClasses; } - public void link(ClassHolder cls) { + private void link(DependencyInfo dependency, ClassHolder cls) { for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { MethodReference methodRef = new MethodReference(cls.getName(), method.getDescriptor()); MethodDependencyInfo methodDep = dependency.getMethod(methodRef); @@ -55,7 +46,7 @@ public class Linker { method.getModifiers().add(ElementModifier.ABSTRACT); method.setProgram(null); } else if (method.getProgram() != null) { - link(method); + link(dependency, method); } } for (FieldHolder field : cls.getFields().toArray(new FieldHolder[0])) { @@ -66,7 +57,7 @@ public class Linker { } } - public void link(MethodHolder method) { + private void link(DependencyInfo dependency, MethodHolder method) { Program program = method.getProgram(); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); diff --git a/teavm-core/src/main/java/org/teavm/model/CopyClassHolderSource.java b/teavm-core/src/main/java/org/teavm/model/CopyClassHolderSource.java index d7091392b..a0de1addd 100644 --- a/teavm-core/src/main/java/org/teavm/model/CopyClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/model/CopyClassHolderSource.java @@ -24,14 +24,14 @@ import org.teavm.resource.MapperClassHolderSource; * @author Alexey Andreev */ public class CopyClassHolderSource implements ClassHolderSource { - private ClassHolderSource innerSource; + private ClassReaderSource innerSource; private MapperClassHolderSource mapperSource = new MapperClassHolderSource(new Mapper() { @Override public ClassHolder map(String preimage) { return copyClass(preimage); } }); - public CopyClassHolderSource(ClassHolderSource innerSource) { + public CopyClassHolderSource(ClassReaderSource innerSource) { this.innerSource = innerSource; } @@ -41,7 +41,7 @@ public class CopyClassHolderSource implements ClassHolderSource { } private ClassHolder copyClass(String className) { - ClassHolder original = innerSource.get(className); + ClassReader original = innerSource.get(className); if (original == null) { return null; } diff --git a/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java b/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java index 310a7f1b7..67cb3bbad 100644 --- a/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java +++ b/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java @@ -97,7 +97,7 @@ class InstructionReadVisitor implements InstructionVisitor { @Override public void visit(CastIntegerInstruction insn) { - reader.cast(insn.getReceiver(), insn.getReceiver(), insn.getTargetType(), insn.getDirection()); + reader.cast(insn.getReceiver(), insn.getValue(), insn.getTargetType(), insn.getDirection()); } @Override diff --git a/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java b/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java index 3b0cc8017..f728d144b 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java +++ b/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java @@ -1,8 +1,22 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.teavm.model.util; import java.util.ArrayList; import java.util.List; -import java.util.Map; import org.teavm.model.*; /** @@ -13,16 +27,16 @@ public final class ModelUtils { private ModelUtils() { } - public static ClassHolder copyClass(ClassHolder original) { + public static ClassHolder copyClass(ClassReader original) { ClassHolder copy = new ClassHolder(original.getName()); copy.setLevel(original.getLevel()); - copy.getModifiers().addAll(original.getModifiers()); + copy.getModifiers().addAll(original.readModifiers()); copy.setParent(original.getParent()); copy.getInterfaces().addAll(original.getInterfaces()); - for (MethodHolder method : original.getMethods()) { + for (MethodReader method : original.getMethods()) { copy.addMethod(copyMethod(method)); } - for (FieldHolder field : original.getFields()) { + for (FieldReader field : original.getFields()) { copy.addField(copyField(field)); } copy.setOwnerName(original.getOwnerName()); @@ -30,35 +44,37 @@ public final class ModelUtils { return copy; } - public static MethodHolder copyMethod(MethodHolder method) { + public static MethodHolder copyMethod(MethodReader method) { MethodHolder copy = new MethodHolder(method.getDescriptor()); copy.setLevel(method.getLevel()); - copy.getModifiers().addAll(method.getModifiers()); - copy.setProgram(ProgramUtils.copy(method.getProgram())); + copy.getModifiers().addAll(method.readModifiers()); + if (method.getProgram() != null) { + copy.setProgram(ProgramUtils.copy(method.getProgram())); + } copyAnnotations(method.getAnnotations(), copy.getAnnotations()); return copy; } - public static FieldHolder copyField(FieldHolder field) { + public static FieldHolder copyField(FieldReader field) { FieldHolder copy = new FieldHolder(field.getName()); copy.setLevel(field.getLevel()); - copy.getModifiers().addAll(field.getModifiers()); + copy.getModifiers().addAll(field.readModifiers()); copy.setType(field.getType()); copy.setInitialValue(field.getInitialValue()); copyAnnotations(field.getAnnotations(), copy.getAnnotations()); return copy; } - private static void copyAnnotations(AnnotationContainer src, AnnotationContainer dst) { - for (AnnotationHolder annot : src.all()) { + private static void copyAnnotations(AnnotationContainerReader src, AnnotationContainer dst) { + for (AnnotationReader annot : src.all()) { dst.add(copyAnnotation(annot)); } } - private static AnnotationHolder copyAnnotation(AnnotationHolder annot) { + private static AnnotationHolder copyAnnotation(AnnotationReader annot) { AnnotationHolder copy = new AnnotationHolder(annot.getType()); - for (Map.Entry entry : annot.getValues().entrySet()) { - copy.getValues().put(entry.getKey(), copyAnnotationValue(entry.getValue())); + for (String fieldName : annot.getAvailableFields()) { + copy.getValues().put(fieldName, copyAnnotationValue(annot.getValue(fieldName))); } return copy; } diff --git a/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java b/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java index 9058d08c6..7ebe718d9 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java +++ b/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java @@ -417,6 +417,5 @@ public final class ProgramUtils { insnCopy.setValue(copyVar(value)); copy = insnCopy; } - } } diff --git a/teavm-core/src/main/java/org/teavm/vm/JavascriptProcessedClassSource.java b/teavm-core/src/main/java/org/teavm/vm/JavascriptProcessedClassSource.java deleted file mode 100644 index a775e28a3..000000000 --- a/teavm-core/src/main/java/org/teavm/vm/JavascriptProcessedClassSource.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.vm; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import org.teavm.common.ConcurrentCachedMapper; -import org.teavm.common.Mapper; -import org.teavm.model.ClassHolder; -import org.teavm.model.ClassHolderSource; -import org.teavm.model.ClassHolderTransformer; - -/** - * - * @author Alexey Andreev - */ -class JavascriptProcessedClassSource implements ClassHolderSource { - private ClassHolderSource innerSource; - private List transformers = new ArrayList<>(); - private ConcurrentCachedMapper mapper = new ConcurrentCachedMapper<>( - new Mapper() { - @Override public ClassHolder map(String preimage) { - return getTransformed(preimage); - } - }); - - public JavascriptProcessedClassSource(ClassHolderSource innerSource) { - this.innerSource = innerSource; - } - - public void addTransformer(ClassHolderTransformer transformer) { - transformers.add(transformer); - } - - @Override - public ClassHolder get(String name) { - return mapper.map(name); - } - - private ClassHolder getTransformed(String name) { - ClassHolder cls = innerSource.get(name); - if (cls != null) { - transformClass(cls); - } - return cls; - } - - private void transformClass(ClassHolder cls) { - for (ClassHolderTransformer transformer : transformers) { - transformer.transformClass(cls, innerSource); - } - } -} diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 03d908c6c..23b37d628 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -63,7 +63,7 @@ import org.teavm.vm.spi.TeaVMPlugin; * @author Alexey Andreev */ public class TeaVM implements TeaVMHost { - private JavascriptProcessedClassSource classSource; + private ClassReaderSource classSource; private DependencyChecker dependencyChecker; private FiniteExecutor executor; private ClassLoader classLoader; @@ -76,8 +76,8 @@ public class TeaVM implements TeaVMHost { private List rendererListeners = new ArrayList<>(); private Properties properties = new Properties(); - TeaVM(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { - this.classSource = new JavascriptProcessedClassSource(classSource); + TeaVM(ClassReaderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { + this.classSource = classSource; this.classLoader = classLoader; dependencyChecker = new DependencyChecker(this.classSource, classLoader, executor); this.executor = executor; @@ -90,7 +90,7 @@ public class TeaVM implements TeaVMHost { @Override public void add(ClassHolderTransformer transformer) { - classSource.addTransformer(transformer); + dependencyChecker.addClassTransformer(transformer); } @Override @@ -137,6 +137,9 @@ public class TeaVM implements TeaVMHost { /** * Specifies configuration properties for TeaVM and its plugins. You should call this method before * installing any plugins or interceptors. + * + * @param properties configuration properties to set. These properties will be copied into this VM instance, + * so VM won't see any further changes in this object. */ public void setProperties(Properties properties) { this.properties.clear(); @@ -196,10 +199,10 @@ public class TeaVM implements TeaVMHost { } /** - * Gets a {@link ClassHolderSource} which is used by this TeaVM instance. It is exactly what was + * Gets a {@link ClassReaderSource} which is used by this TeaVM instance. It is exactly what was * passed to {@link TeaVMBuilder#setClassSource(ClassHolderSource)}. */ - public ClassHolderSource getClassSource() { + public ClassReaderSource getClassSource() { return classSource; } @@ -216,6 +219,8 @@ public class TeaVM implements TeaVMHost { *

After building allows to build report on all items (classes, methods, fields) that are missing. * This can happen when you forgot some items in class path or when your code uses unimplemented * Java class library methods. The behavior of this method before building is not specified.

+ * + * @param target where to append all dependency diagnostics errors. */ public void showMissingItems(Appendable target) throws IOException { dependencyChecker.showMissingItems(target); @@ -243,12 +248,8 @@ public class TeaVM implements TeaVMHost { * plugins or inteceptors that generate additional resources, the build process will fail. */ public void build(Appendable writer, BuildTarget target) throws RenderingException { + // Check dependencies AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider(); - DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, classSource); - naming.setMinifying(minifying); - SourceWriterBuilder builder = new SourceWriterBuilder(naming); - builder.setMinified(minifying); - SourceWriter sourceWriter = builder.build(writer); dependencyChecker.linkMethod(new MethodReference("java.lang.Class", "createNew", ValueType.object("java.lang.Class")), DependencyStack.ROOT).use(); dependencyChecker.linkMethod(new MethodReference("java.lang.String", "", @@ -268,9 +269,12 @@ public class TeaVM implements TeaVMHost { if (hasMissingItems()) { return; } - Linker linker = new Linker(dependencyChecker); - ListableClassHolderSource classSet = linker.link(classSource); - Decompiler decompiler = new Decompiler(classSet, classLoader, executor); + + // Link + Linker linker = new Linker(); + ListableClassHolderSource classSet = linker.link(dependencyChecker); + + // Optimize and allocate registers devirtualize(classSet, dependencyChecker); executor.complete(); ClassSetOptimizer optimizer = new ClassSetOptimizer(executor); @@ -285,10 +289,20 @@ public class TeaVM implements TeaVMHost { // Just don't do anything } } + + // Decompile + Decompiler decompiler = new Decompiler(classSet, classLoader, executor); for (Map.Entry entry : methodGenerators.entrySet()) { decompiler.addGenerator(entry.getKey(), entry.getValue()); } List clsNodes = decompiler.decompile(classSet.getClassNames()); + + // Render + DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, dependencyChecker.getClassSource()); + naming.setMinifying(minifying); + SourceWriterBuilder builder = new SourceWriterBuilder(naming); + builder.setMinified(minifying); + SourceWriter sourceWriter = builder.build(writer); Renderer renderer = new Renderer(sourceWriter, classSet, classLoader); try { for (RendererListener listener : rendererListeners) { @@ -321,7 +335,6 @@ public class TeaVM implements TeaVMHost { } } - // TODO: repair devirtualization private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) { final Devirtualization devirtualization = new Devirtualization(dependency, classes); for (String className : classes.getClassNames()) { diff --git a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java index 59f8fdf47..fc0f2cfbc 100644 --- a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java +++ b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java @@ -26,6 +26,7 @@ import org.teavm.vm.TeaVMBuilder; /** *

A host of plugins for TeaVM. Plugins are provided with this interface * in order to give them ability to extend TeaVM.

+ * * @author Alexey Andreev */ public interface TeaVMHost { @@ -45,7 +46,10 @@ public interface TeaVMHost { /** * Gets configuration properties. These properties are usually specified by - * {@link TeaVM#setProperties(Properties)} + * {@link TeaVM#setProperties(Properties)}. + * + * @return a copy of all of the VM properties. Any further changes to returned objects will not be + * visible to VM. */ Properties getProperties(); }