mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Rename DependencyChecker to DependencyAnalyzer
This commit is contained in:
parent
0f39dbbdd4
commit
2bbdf6caba
|
@ -45,7 +45,7 @@ import org.teavm.backend.javascript.spi.Injector;
|
||||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||||
import org.teavm.debugging.information.DummyDebugInformationEmitter;
|
import org.teavm.debugging.information.DummyDebugInformationEmitter;
|
||||||
import org.teavm.debugging.information.SourceLocation;
|
import org.teavm.debugging.information.SourceLocation;
|
||||||
import org.teavm.dependency.DependencyChecker;
|
import org.teavm.dependency.DependencyAnalyzer;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
|
@ -168,40 +168,40 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contributeDependencies(DependencyChecker dependencyChecker) {
|
public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) {
|
||||||
dependencyChecker.linkMethod(new MethodReference(Class.class.getName(), "getClass",
|
dependencyAnalyzer.linkMethod(new MethodReference(Class.class.getName(), "getClass",
|
||||||
ValueType.object("org.teavm.platform.PlatformClass"), ValueType.parse(Class.class)), null).use();
|
ValueType.object("org.teavm.platform.PlatformClass"), ValueType.parse(Class.class)), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(String.class, "<init>", char[].class, void.class),
|
dependencyAnalyzer.linkMethod(new MethodReference(String.class, "<init>", char[].class, void.class),
|
||||||
null).use();
|
null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(String.class, "getChars", int.class, int.class, char[].class,
|
dependencyAnalyzer.linkMethod(new MethodReference(String.class, "getChars", int.class, int.class, char[].class,
|
||||||
int.class, void.class), null).use();
|
int.class, void.class), null).use();
|
||||||
|
|
||||||
MethodDependency internDep = dependencyChecker.linkMethod(new MethodReference(String.class, "intern",
|
MethodDependency internDep = dependencyAnalyzer.linkMethod(new MethodReference(String.class, "intern",
|
||||||
String.class), null);
|
String.class), null);
|
||||||
internDep.getVariable(0).propagate(dependencyChecker.getType("java.lang.String"));
|
internDep.getVariable(0).propagate(dependencyAnalyzer.getType("java.lang.String"));
|
||||||
internDep.use();
|
internDep.use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(String.class, "length", int.class), null).use();
|
dependencyAnalyzer.linkMethod(new MethodReference(String.class, "length", int.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(Object.class, "clone", Object.class), null).use();
|
dependencyAnalyzer.linkMethod(new MethodReference(Object.class, "clone", Object.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(Thread.class, "currentThread", Thread.class), null).use();
|
dependencyAnalyzer.linkMethod(new MethodReference(Thread.class, "currentThread", Thread.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(Thread.class, "getMainThread", Thread.class), null).use();
|
dependencyAnalyzer.linkMethod(new MethodReference(Thread.class, "getMainThread", Thread.class), null).use();
|
||||||
dependencyChecker.linkMethod(
|
dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Thread.class, "setCurrentThread", Thread.class, void.class), null).use();
|
new MethodReference(Thread.class, "setCurrentThread", Thread.class, void.class), null).use();
|
||||||
MethodDependency exceptionCons = dependencyChecker.linkMethod(new MethodReference(
|
MethodDependency exceptionCons = dependencyAnalyzer.linkMethod(new MethodReference(
|
||||||
NoClassDefFoundError.class, "<init>", String.class, void.class), null);
|
NoClassDefFoundError.class, "<init>", String.class, void.class), null);
|
||||||
|
|
||||||
exceptionCons.getVariable(0).propagate(dependencyChecker.getType(NoClassDefFoundError.class.getName()));
|
exceptionCons.getVariable(0).propagate(dependencyAnalyzer.getType(NoClassDefFoundError.class.getName()));
|
||||||
exceptionCons.getVariable(1).propagate(dependencyChecker.getType("java.lang.String"));
|
exceptionCons.getVariable(1).propagate(dependencyAnalyzer.getType("java.lang.String"));
|
||||||
exceptionCons = dependencyChecker.linkMethod(new MethodReference(NoSuchFieldError.class, "<init>",
|
exceptionCons = dependencyAnalyzer.linkMethod(new MethodReference(NoSuchFieldError.class, "<init>",
|
||||||
String.class, void.class), null);
|
String.class, void.class), null);
|
||||||
exceptionCons.use();
|
exceptionCons.use();
|
||||||
exceptionCons.getVariable(0).propagate(dependencyChecker.getType(NoSuchFieldError.class.getName()));
|
exceptionCons.getVariable(0).propagate(dependencyAnalyzer.getType(NoSuchFieldError.class.getName()));
|
||||||
exceptionCons.getVariable(1).propagate(dependencyChecker.getType("java.lang.String"));
|
exceptionCons.getVariable(1).propagate(dependencyAnalyzer.getType("java.lang.String"));
|
||||||
exceptionCons = dependencyChecker.linkMethod(new MethodReference(NoSuchMethodError.class, "<init>",
|
exceptionCons = dependencyAnalyzer.linkMethod(new MethodReference(NoSuchMethodError.class, "<init>",
|
||||||
String.class, void.class), null);
|
String.class, void.class), null);
|
||||||
exceptionCons.use();
|
exceptionCons.use();
|
||||||
exceptionCons.getVariable(0).propagate(dependencyChecker.getType(NoSuchMethodError.class.getName()));
|
exceptionCons.getVariable(0).propagate(dependencyAnalyzer.getType(NoSuchMethodError.class.getName()));
|
||||||
exceptionCons.getVariable(1).propagate(dependencyChecker.getType("java.lang.String"));
|
exceptionCons.getVariable(1).propagate(dependencyAnalyzer.getType("java.lang.String"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -81,7 +81,7 @@ import org.teavm.backend.wasm.transformation.IndirectCallTraceTransformation;
|
||||||
import org.teavm.backend.wasm.transformation.MemoryAccessTraceTransformation;
|
import org.teavm.backend.wasm.transformation.MemoryAccessTraceTransformation;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.dependency.ClassDependency;
|
import org.teavm.dependency.ClassDependency;
|
||||||
import org.teavm.dependency.DependencyChecker;
|
import org.teavm.dependency.DependencyAnalyzer;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
|
@ -210,62 +210,62 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contributeDependencies(DependencyChecker dependencyChecker) {
|
public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) {
|
||||||
for (Class<?> type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
for (Class<?> type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
||||||
MethodReference method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
MethodReference method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
||||||
dependencyChecker.linkMethod(method, null).use();
|
dependencyAnalyzer.linkMethod(method, null).use();
|
||||||
}
|
}
|
||||||
for (Class<?> type : Arrays.asList(float.class, double.class)) {
|
for (Class<?> type : Arrays.asList(float.class, double.class)) {
|
||||||
MethodReference method = new MethodReference(WasmRuntime.class, "remainder", type, type, type);
|
MethodReference method = new MethodReference(WasmRuntime.class, "remainder", type, type, type);
|
||||||
dependencyChecker.linkMethod(method, null).use();
|
dependencyAnalyzer.linkMethod(method, null).use();
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "align", Address.class, int.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "align", Address.class, int.class,
|
||||||
Address.class), null).use();
|
Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "fillZero", Address.class, int.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "fillZero", Address.class, int.class,
|
||||||
void.class), null).use();
|
void.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "moveMemoryBlock", Address.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "moveMemoryBlock", Address.class,
|
||||||
Address.class, int.class, void.class), null).use();
|
Address.class, int.class, void.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "allocStack",
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "allocStack",
|
||||||
int.class, Address.class), null).use();
|
int.class, Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackTop", Address.class),
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "getStackTop", Address.class),
|
||||||
null) .use();
|
null) .use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getNextStackFrame", Address.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "getNextStackFrame", Address.class,
|
||||||
Address.class), null).use();
|
Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootCount", Address.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootCount", Address.class,
|
||||||
int.class), null).use();
|
int.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootPointer", Address.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootPointer", Address.class,
|
||||||
Address.class), null).use();
|
Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "setExceptionHandlerId", Address.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "setExceptionHandlerId", Address.class,
|
||||||
int.class, void.class), null).use();
|
int.class, void.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getCallSiteId", Address.class,
|
dependencyAnalyzer.linkMethod(new MethodReference(WasmRuntime.class, "getCallSiteId", Address.class,
|
||||||
int.class), null).use();
|
int.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocate",
|
dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "allocate",
|
||||||
RuntimeClass.class, Address.class), null).use();
|
RuntimeClass.class, Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocateArray",
|
dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "allocateArray",
|
||||||
RuntimeClass.class, int.class, Address.class), null).use();
|
RuntimeClass.class, int.class, Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocateMultiArray",
|
dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "allocateMultiArray",
|
||||||
RuntimeClass.class, Address.class, int.class, RuntimeArray.class), null).use();
|
RuntimeClass.class, Address.class, int.class, RuntimeArray.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class), null).use();
|
dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(ExceptionHandling.class, "throwException",
|
dependencyAnalyzer.linkMethod(new MethodReference(ExceptionHandling.class, "throwException",
|
||||||
Throwable.class, void.class), null).use();
|
Throwable.class, void.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(ExceptionHandling.class, "catchException",
|
dependencyAnalyzer.linkMethod(new MethodReference(ExceptionHandling.class, "catchException",
|
||||||
Throwable.class), null).use();
|
Throwable.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkField(new FieldReference("java.lang.Object", "monitor"), null);
|
dependencyAnalyzer.linkField(new FieldReference("java.lang.Object", "monitor"), null);
|
||||||
|
|
||||||
ClassDependency runtimeClassDep = dependencyChecker.linkClass(RuntimeClass.class.getName(), null);
|
ClassDependency runtimeClassDep = dependencyAnalyzer.linkClass(RuntimeClass.class.getName(), null);
|
||||||
ClassDependency runtimeObjectDep = dependencyChecker.linkClass(RuntimeObject.class.getName(), null);
|
ClassDependency runtimeObjectDep = dependencyAnalyzer.linkClass(RuntimeObject.class.getName(), null);
|
||||||
ClassDependency runtimeJavaObjectDep = dependencyChecker.linkClass(RuntimeJavaObject.class.getName(), null);
|
ClassDependency runtimeJavaObjectDep = dependencyAnalyzer.linkClass(RuntimeJavaObject.class.getName(), null);
|
||||||
ClassDependency runtimeArrayDep = dependencyChecker.linkClass(RuntimeArray.class.getName(), null);
|
ClassDependency runtimeArrayDep = dependencyAnalyzer.linkClass(RuntimeArray.class.getName(), null);
|
||||||
for (ClassDependency classDep : Arrays.asList(runtimeClassDep, runtimeObjectDep, runtimeJavaObjectDep,
|
for (ClassDependency classDep : Arrays.asList(runtimeClassDep, runtimeObjectDep, runtimeJavaObjectDep,
|
||||||
runtimeArrayDep)) {
|
runtimeArrayDep)) {
|
||||||
for (FieldReader field : classDep.getClassReader().getFields()) {
|
for (FieldReader field : classDep.getClassReader().getFields()) {
|
||||||
dependencyChecker.linkField(field.getReference(), null);
|
dependencyAnalyzer.linkField(field.getReference(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,12 @@ import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
|
|
||||||
public class ClassDependency implements ClassDependencyInfo {
|
public class ClassDependency implements ClassDependencyInfo {
|
||||||
private DependencyChecker checker;
|
private DependencyAnalyzer analyzer;
|
||||||
private String className;
|
private String className;
|
||||||
private ClassReader classReader;
|
private ClassReader classReader;
|
||||||
|
|
||||||
ClassDependency(DependencyChecker checker, String className, ClassReader classReader) {
|
ClassDependency(DependencyAnalyzer analyzer, String className, ClassReader classReader) {
|
||||||
this.checker = checker;
|
this.analyzer = analyzer;
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.classReader = classReader;
|
this.classReader = classReader;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public class ClassDependency implements ClassDependencyInfo {
|
||||||
|
|
||||||
public void initClass(CallLocation callLocation) {
|
public void initClass(CallLocation callLocation) {
|
||||||
if (!isMissing()) {
|
if (!isMissing()) {
|
||||||
checker.initClass(this, callLocation);
|
analyzer.initClass(this, callLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,104 +22,104 @@ import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
|
||||||
public class DependencyAgent implements DependencyInfo, ServiceRepository {
|
public class DependencyAgent implements DependencyInfo, ServiceRepository {
|
||||||
private DependencyChecker checker;
|
private DependencyAnalyzer analyzer;
|
||||||
|
|
||||||
DependencyAgent(DependencyChecker checker) {
|
DependencyAgent(DependencyAnalyzer analyzer) {
|
||||||
this.checker = checker;
|
this.analyzer = analyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyNode createNode() {
|
public DependencyNode createNode() {
|
||||||
return checker.createNode();
|
return analyzer.createNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyType getType(String name) {
|
public DependencyType getType(String name) {
|
||||||
return checker.getType(name);
|
return analyzer.getType(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateClassName() {
|
public String generateClassName() {
|
||||||
return checker.generateClassName();
|
return analyzer.generateClassName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String submitClassFile(byte[] data) {
|
public String submitClassFile(byte[] data) {
|
||||||
return checker.submitClassFile(data);
|
return analyzer.submitClassFile(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submitClass(ClassHolder cls) {
|
public void submitClass(ClassHolder cls) {
|
||||||
checker.submitClass(cls);
|
analyzer.submitClass(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submitMethod(MethodReference method, Program program) {
|
public void submitMethod(MethodReference method, Program program) {
|
||||||
checker.submitMethod(method, program);
|
analyzer.submitMethod(method, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) {
|
public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) {
|
||||||
return checker.linkMethod(methodRef, callLocation);
|
return analyzer.linkMethod(methodRef, callLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassDependency linkClass(String className, CallLocation callLocation) {
|
public ClassDependency linkClass(String className, CallLocation callLocation) {
|
||||||
return checker.linkClass(className, callLocation);
|
return analyzer.linkClass(className, callLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldDependency linkField(FieldReference fieldRef, CallLocation callLocation) {
|
public FieldDependency linkField(FieldReference fieldRef, CallLocation callLocation) {
|
||||||
return checker.linkField(fieldRef, callLocation);
|
return analyzer.linkField(fieldRef, callLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Diagnostics getDiagnostics() {
|
public Diagnostics getDiagnostics() {
|
||||||
return checker.getDiagnostics();
|
return analyzer.getDiagnostics();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T getService(Class<T> type) {
|
public <T> T getService(Class<T> type) {
|
||||||
return checker.getService(type);
|
return analyzer.getService(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassReaderSource getClassSource() {
|
public ClassReaderSource getClassSource() {
|
||||||
return checker.getClassSource();
|
return analyzer.getClassSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return checker.getClassLoader();
|
return analyzer.getClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<MethodReference> getReachableMethods() {
|
public Collection<MethodReference> getReachableMethods() {
|
||||||
return checker.getReachableMethods();
|
return analyzer.getReachableMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<FieldReference> getReachableFields() {
|
public Collection<FieldReference> getReachableFields() {
|
||||||
return checker.getReachableFields();
|
return analyzer.getReachableFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getReachableClasses() {
|
public Collection<String> getReachableClasses() {
|
||||||
return checker.getReachableClasses();
|
return analyzer.getReachableClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldDependencyInfo getField(FieldReference fieldRef) {
|
public FieldDependencyInfo getField(FieldReference fieldRef) {
|
||||||
return checker.getField(fieldRef);
|
return analyzer.getField(fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodDependencyInfo getMethod(MethodReference methodRef) {
|
public MethodDependencyInfo getMethod(MethodReference methodRef) {
|
||||||
return checker.getMethod(methodRef);
|
return analyzer.getMethod(methodRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodDependencyInfo getMethodImplementation(MethodReference methodRef) {
|
public MethodDependencyInfo getMethodImplementation(MethodReference methodRef) {
|
||||||
return checker.getMethodImplementation(methodRef);
|
return analyzer.getMethodImplementation(methodRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDependencyInfo getClass(String className) {
|
public ClassDependencyInfo getClass(String className) {
|
||||||
return checker.getClass(className);
|
return analyzer.getClass(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CallGraph getCallGraph() {
|
public CallGraph getCallGraph() {
|
||||||
return checker.getCallGraph();
|
return analyzer.getCallGraph();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ import org.teavm.model.util.ModelUtils;
|
||||||
import org.teavm.model.util.ProgramUtils;
|
import org.teavm.model.util.ProgramUtils;
|
||||||
import org.teavm.parsing.Parser;
|
import org.teavm.parsing.Parser;
|
||||||
|
|
||||||
public class DependencyChecker implements DependencyInfo {
|
public class DependencyAnalyzer implements DependencyInfo {
|
||||||
private static final int PROPAGATION_STACK_THRESHOLD = 50;
|
private static final int PROPAGATION_STACK_THRESHOLD = 50;
|
||||||
static final boolean shouldLog = System.getProperty("org.teavm.logDependencies", "false").equals("true");
|
static final boolean shouldLog = System.getProperty("org.teavm.logDependencies", "false").equals("true");
|
||||||
static final boolean shouldTag = System.getProperty("org.teavm.tagDependencies", "false").equals("true")
|
static final boolean shouldTag = System.getProperty("org.teavm.tagDependencies", "false").equals("true")
|
||||||
|
@ -77,7 +77,7 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
private Queue<Runnable> deferredTasks = new ArrayDeque<>();
|
private Queue<Runnable> deferredTasks = new ArrayDeque<>();
|
||||||
List<DependencyType> types = new ArrayList<>();
|
List<DependencyType> types = new ArrayList<>();
|
||||||
private Map<String, DependencyType> typeMap = new HashMap<>();
|
private Map<String, DependencyType> typeMap = new HashMap<>();
|
||||||
private DependencyCheckerInterruptor interruptor;
|
private DependencyAnalyzerInterruptor interruptor;
|
||||||
private boolean interrupted;
|
private boolean interrupted;
|
||||||
private Diagnostics diagnostics;
|
private Diagnostics diagnostics;
|
||||||
DefaultCallGraph callGraph = new DefaultCallGraph();
|
DefaultCallGraph callGraph = new DefaultCallGraph();
|
||||||
|
@ -86,7 +86,7 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
private boolean completing;
|
private boolean completing;
|
||||||
private Map<String, SuperClassFilter> superClassFilters = new HashMap<>();
|
private Map<String, SuperClassFilter> superClassFilters = new HashMap<>();
|
||||||
|
|
||||||
public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
|
public DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
|
||||||
Diagnostics diagnostics) {
|
Diagnostics diagnostics) {
|
||||||
this.diagnostics = diagnostics;
|
this.diagnostics = diagnostics;
|
||||||
this.classSource = new DependencyClassSource(classSource, diagnostics);
|
this.classSource = new DependencyClassSource(classSource, diagnostics);
|
||||||
|
@ -118,11 +118,11 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyCheckerInterruptor getInterruptor() {
|
public DependencyAnalyzerInterruptor getInterruptor() {
|
||||||
return interruptor;
|
return interruptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterruptor(DependencyCheckerInterruptor interruptor) {
|
public void setInterruptor(DependencyAnalyzerInterruptor interruptor) {
|
||||||
this.interruptor = interruptor;
|
this.interruptor = interruptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
dep.used = false;
|
dep.used = false;
|
||||||
lock(dep, false);
|
lock(dep, false);
|
||||||
deferredTasks.add(() -> {
|
deferredTasks.add(() -> {
|
||||||
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyAnalyzer.this);
|
||||||
graphBuilder.buildGraph(dep);
|
graphBuilder.buildGraph(dep);
|
||||||
dep.used = true;
|
dep.used = true;
|
||||||
});
|
});
|
||||||
|
@ -448,7 +448,7 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
|
|
||||||
void scheduleMethodAnalysis(MethodDependency dep) {
|
void scheduleMethodAnalysis(MethodDependency dep) {
|
||||||
deferredTasks.add(() -> {
|
deferredTasks.add(() -> {
|
||||||
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyAnalyzer.this);
|
||||||
graphBuilder.buildGraph(dep);
|
graphBuilder.buildGraph(dep);
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -15,6 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
public interface DependencyCheckerInterruptor {
|
public interface DependencyAnalyzerInterruptor {
|
||||||
boolean shouldContinue();
|
boolean shouldContinue();
|
||||||
}
|
}
|
|
@ -58,7 +58,7 @@ import org.teavm.model.instructions.NullConstantInstruction;
|
||||||
import org.teavm.model.text.ListingBuilder;
|
import org.teavm.model.text.ListingBuilder;
|
||||||
|
|
||||||
class DependencyGraphBuilder {
|
class DependencyGraphBuilder {
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyAnalyzer dependencyAnalyzer;
|
||||||
private DependencyNode[] nodes;
|
private DependencyNode[] nodes;
|
||||||
private DependencyNode resultNode;
|
private DependencyNode resultNode;
|
||||||
private Program program;
|
private Program program;
|
||||||
|
@ -66,12 +66,12 @@ class DependencyGraphBuilder {
|
||||||
private TextLocation currentLocation;
|
private TextLocation currentLocation;
|
||||||
private ExceptionConsumer currentExceptionConsumer;
|
private ExceptionConsumer currentExceptionConsumer;
|
||||||
|
|
||||||
DependencyGraphBuilder(DependencyChecker dependencyChecker) {
|
DependencyGraphBuilder(DependencyAnalyzer dependencyAnalyzer) {
|
||||||
this.dependencyChecker = dependencyChecker;
|
this.dependencyAnalyzer = dependencyAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildGraph(MethodDependency dep) {
|
public void buildGraph(MethodDependency dep) {
|
||||||
caller = dependencyChecker.callGraph.getNode(dep.getReference());
|
caller = dependencyAnalyzer.callGraph.getNode(dep.getReference());
|
||||||
MethodHolder method = dep.method;
|
MethodHolder method = dep.method;
|
||||||
if (method.getProgram() == null || method.getProgram().basicBlockCount() == 0) {
|
if (method.getProgram() == null || method.getProgram().basicBlockCount() == 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -93,7 +93,7 @@ class DependencyGraphBuilder {
|
||||||
int[] nodeMapping = dfgBuilder.buildMapping(program, significantParams,
|
int[] nodeMapping = dfgBuilder.buildMapping(program, significantParams,
|
||||||
!(method.getResultType() instanceof ValueType.Primitive) && method.getResultType() != ValueType.VOID);
|
!(method.getResultType() instanceof ValueType.Primitive) && method.getResultType() != ValueType.VOID);
|
||||||
|
|
||||||
if (DependencyChecker.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
System.out.println("Method reached: " + method.getReference());
|
System.out.println("Method reached: " + method.getReference());
|
||||||
System.out.print(new ListingBuilder().buildListing(program, " "));
|
System.out.print(new ListingBuilder().buildListing(program, " "));
|
||||||
for (int i = 0; i < nodeMapping.length; ++i) {
|
for (int i = 0; i < nodeMapping.length; ++i) {
|
||||||
|
@ -110,9 +110,9 @@ class DependencyGraphBuilder {
|
||||||
DependencyNode[] nodeClasses = Arrays.copyOf(dep.getVariables(), nodeClassCount);
|
DependencyNode[] nodeClasses = Arrays.copyOf(dep.getVariables(), nodeClassCount);
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
for (int i = dep.getVariableCount(); i < nodeClasses.length; ++i) {
|
for (int i = dep.getVariableCount(); i < nodeClasses.length; ++i) {
|
||||||
nodeClasses[i] = dependencyChecker.createNode();
|
nodeClasses[i] = dependencyAnalyzer.createNode();
|
||||||
nodeClasses[i].method = ref;
|
nodeClasses[i].method = ref;
|
||||||
if (DependencyChecker.shouldTag) {
|
if (DependencyAnalyzer.shouldTag) {
|
||||||
nodeClasses[i].setTag(dep.getMethod().getReference() + ":" + i);
|
nodeClasses[i].setTag(dep.getMethod().getReference() + ":" + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ class DependencyGraphBuilder {
|
||||||
|
|
||||||
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
||||||
if (tryCatch.getExceptionType() != null) {
|
if (tryCatch.getExceptionType() != null) {
|
||||||
dependencyChecker.linkClass(tryCatch.getExceptionType(), new CallLocation(caller.getMethod()));
|
dependencyAnalyzer.linkClass(tryCatch.getExceptionType(), new CallLocation(caller.getMethod()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,29 +148,29 @@ class DependencyGraphBuilder {
|
||||||
if (method.hasModifier(ElementModifier.SYNCHRONIZED)) {
|
if (method.hasModifier(ElementModifier.SYNCHRONIZED)) {
|
||||||
List<DependencyNode> syncNodes = new ArrayList<>();
|
List<DependencyNode> syncNodes = new ArrayList<>();
|
||||||
|
|
||||||
MethodDependency methodDep = dependencyChecker.linkMethod(
|
MethodDependency methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorEnter", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorEnter", Object.class, void.class), null);
|
||||||
syncNodes.add(methodDep.getVariable(1));
|
syncNodes.add(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
||||||
methodDep = dependencyChecker.linkMethod(
|
methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorEnterSync", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorEnterSync", Object.class, void.class), null);
|
||||||
syncNodes.add(methodDep.getVariable(1));
|
syncNodes.add(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
||||||
methodDep = dependencyChecker.linkMethod(
|
methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorExit", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorExit", Object.class, void.class), null);
|
||||||
syncNodes.add(methodDep.getVariable(1));
|
syncNodes.add(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
||||||
methodDep = dependencyChecker.linkMethod(
|
methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorExitSync", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorExitSync", Object.class, void.class), null);
|
||||||
syncNodes.add(methodDep.getVariable(1));
|
syncNodes.add(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
||||||
if (method.hasModifier(ElementModifier.STATIC)) {
|
if (method.hasModifier(ElementModifier.STATIC)) {
|
||||||
for (DependencyNode node : syncNodes) {
|
for (DependencyNode node : syncNodes) {
|
||||||
node.propagate(dependencyChecker.getType("java.lang.Class"));
|
node.propagate(dependencyAnalyzer.getType("java.lang.Class"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (DependencyNode node : syncNodes) {
|
for (DependencyNode node : syncNodes) {
|
||||||
|
@ -184,7 +184,7 @@ class DependencyGraphBuilder {
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProgramEmitter pe = ProgramEmitter.create(program, dependencyChecker.getClassSource());
|
ProgramEmitter pe = ProgramEmitter.create(program, dependencyAnalyzer.getClassSource());
|
||||||
boolean hasIndy = false;
|
boolean hasIndy = false;
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
@ -197,7 +197,7 @@ class DependencyGraphBuilder {
|
||||||
InvokeDynamicInstruction indy = (InvokeDynamicInstruction) insn;
|
InvokeDynamicInstruction indy = (InvokeDynamicInstruction) insn;
|
||||||
MethodReference bootstrapMethod = new MethodReference(indy.getBootstrapMethod().getClassName(),
|
MethodReference bootstrapMethod = new MethodReference(indy.getBootstrapMethod().getClassName(),
|
||||||
indy.getBootstrapMethod().getName(), indy.getBootstrapMethod().signature());
|
indy.getBootstrapMethod().getName(), indy.getBootstrapMethod().signature());
|
||||||
BootstrapMethodSubstitutor substitutor = dependencyChecker.bootstrapMethodSubstitutors
|
BootstrapMethodSubstitutor substitutor = dependencyAnalyzer.bootstrapMethodSubstitutors
|
||||||
.get(bootstrapMethod);
|
.get(bootstrapMethod);
|
||||||
if (substitutor == null) {
|
if (substitutor == null) {
|
||||||
NullConstantInstruction nullInsn = new NullConstantInstruction();
|
NullConstantInstruction nullInsn = new NullConstantInstruction();
|
||||||
|
@ -205,7 +205,7 @@ class DependencyGraphBuilder {
|
||||||
nullInsn.setLocation(indy.getLocation());
|
nullInsn.setLocation(indy.getLocation());
|
||||||
insn.replace(nullInsn);
|
insn.replace(nullInsn);
|
||||||
CallLocation location = new CallLocation(caller.getMethod(), currentLocation);
|
CallLocation location = new CallLocation(caller.getMethod(), currentLocation);
|
||||||
dependencyChecker.getDiagnostics().error(location, "Substitutor for bootstrap "
|
dependencyAnalyzer.getDiagnostics().error(location, "Substitutor for bootstrap "
|
||||||
+ "method {{m0}} was not found", bootstrapMethod);
|
+ "method {{m0}} was not found", bootstrapMethod);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ class DependencyGraphBuilder {
|
||||||
indy.getInstance() != null ? pe.var(indy.getInstance(),
|
indy.getInstance() != null ? pe.var(indy.getInstance(),
|
||||||
ValueType.object(methodDep.getMethod().getOwnerName())) : null,
|
ValueType.object(methodDep.getMethod().getOwnerName())) : null,
|
||||||
arguments, indy.getBootstrapMethod(), indy.getBootstrapArguments(),
|
arguments, indy.getBootstrapMethod(), indy.getBootstrapArguments(),
|
||||||
dependencyChecker.getAgent());
|
dependencyAnalyzer.getAgent());
|
||||||
ValueEmitter result = substitutor.substitute(callSite, pe);
|
ValueEmitter result = substitutor.substitute(callSite, pe);
|
||||||
if (result.getVariable() != null && result.getVariable() != indy.getReceiver()) {
|
if (result.getVariable() != null && result.getVariable() != indy.getReceiver()) {
|
||||||
AssignInstruction assign = new AssignInstruction();
|
AssignInstruction assign = new AssignInstruction();
|
||||||
|
@ -265,24 +265,24 @@ class DependencyGraphBuilder {
|
||||||
for (int i = 0; i < tryCatchBlocks.size(); ++i) {
|
for (int i = 0; i < tryCatchBlocks.size(); ++i) {
|
||||||
TryCatchBlockReader tryCatch = tryCatchBlocks.get(i);
|
TryCatchBlockReader tryCatch = tryCatchBlocks.get(i);
|
||||||
if (tryCatch.getExceptionType() != null) {
|
if (tryCatch.getExceptionType() != null) {
|
||||||
exceptions[i] = dependencyChecker.getClassSource().get(tryCatch.getExceptionType());
|
exceptions[i] = dependencyAnalyzer.getClassSource().get(tryCatch.getExceptionType());
|
||||||
}
|
}
|
||||||
if (tryCatch.getHandler().getExceptionVariable() != null) {
|
if (tryCatch.getHandler().getExceptionVariable() != null) {
|
||||||
vars[i] = methodDep.getVariable(tryCatch.getHandler().getExceptionVariable().getIndex());
|
vars[i] = methodDep.getVariable(tryCatch.getHandler().getExceptionVariable().getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ExceptionConsumer(dependencyChecker, exceptions, vars, methodDep);
|
return new ExceptionConsumer(dependencyAnalyzer, exceptions, vars, methodDep);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ExceptionConsumer implements DependencyConsumer {
|
static class ExceptionConsumer implements DependencyConsumer {
|
||||||
private DependencyChecker checker;
|
private DependencyAnalyzer analyzer;
|
||||||
private ClassReader[] exceptions;
|
private ClassReader[] exceptions;
|
||||||
private DependencyNode[] vars;
|
private DependencyNode[] vars;
|
||||||
private MethodDependency method;
|
private MethodDependency method;
|
||||||
|
|
||||||
ExceptionConsumer(DependencyChecker checker, ClassReader[] exceptions, DependencyNode[] vars,
|
ExceptionConsumer(DependencyAnalyzer analyzer, ClassReader[] exceptions, DependencyNode[] vars,
|
||||||
MethodDependency method) {
|
MethodDependency method) {
|
||||||
this.checker = checker;
|
this.analyzer = analyzer;
|
||||||
this.exceptions = exceptions;
|
this.exceptions = exceptions;
|
||||||
this.vars = vars;
|
this.vars = vars;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
@ -290,7 +290,7 @@ class DependencyGraphBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void consume(DependencyType type) {
|
public void consume(DependencyType type) {
|
||||||
ClassReaderSource classSource = checker.getClassSource();
|
ClassReaderSource classSource = analyzer.getClassSource();
|
||||||
for (int i = 0; i < exceptions.length; ++i) {
|
for (int i = 0; i < exceptions.length; ++i) {
|
||||||
if (exceptions[i] == null || classSource.isSuperType(exceptions[i].getName(), type.getName())
|
if (exceptions[i] == null || classSource.isSuperType(exceptions[i].getName(), type.getName())
|
||||||
.orElse(false)) {
|
.orElse(false)) {
|
||||||
|
@ -307,7 +307,7 @@ class DependencyGraphBuilder {
|
||||||
static class VirtualCallConsumer implements DependencyConsumer {
|
static class VirtualCallConsumer implements DependencyConsumer {
|
||||||
private final DependencyNode node;
|
private final DependencyNode node;
|
||||||
private final MethodDescriptor methodDesc;
|
private final MethodDescriptor methodDesc;
|
||||||
private final DependencyChecker checker;
|
private final DependencyAnalyzer analyzer;
|
||||||
private final DependencyNode[] parameters;
|
private final DependencyNode[] parameters;
|
||||||
private final DependencyNode result;
|
private final DependencyNode result;
|
||||||
private final DefaultCallGraphNode caller;
|
private final DefaultCallGraphNode caller;
|
||||||
|
@ -318,13 +318,13 @@ class DependencyGraphBuilder {
|
||||||
private SuperClassFilter filter;
|
private SuperClassFilter filter;
|
||||||
|
|
||||||
VirtualCallConsumer(DependencyNode node, String filterClass,
|
VirtualCallConsumer(DependencyNode node, String filterClass,
|
||||||
MethodDescriptor methodDesc, DependencyChecker checker, DependencyNode[] parameters,
|
MethodDescriptor methodDesc, DependencyAnalyzer analyzer, DependencyNode[] parameters,
|
||||||
DependencyNode result, DefaultCallGraphNode caller, TextLocation location,
|
DependencyNode result, DefaultCallGraphNode caller, TextLocation location,
|
||||||
ExceptionConsumer exceptionConsumer) {
|
ExceptionConsumer exceptionConsumer) {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.filter = checker.getSuperClassFilter(filterClass);
|
this.filter = analyzer.getSuperClassFilter(filterClass);
|
||||||
this.methodDesc = methodDesc;
|
this.methodDesc = methodDesc;
|
||||||
this.checker = checker;
|
this.analyzer = analyzer;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.caller = caller;
|
this.caller = caller;
|
||||||
|
@ -340,26 +340,26 @@ class DependencyGraphBuilder {
|
||||||
knownTypes.set(type.index);
|
knownTypes.set(type.index);
|
||||||
|
|
||||||
String className = type.getName();
|
String className = type.getName();
|
||||||
if (DependencyChecker.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
System.out.println("Virtual call of " + methodDesc + " detected on " + node.getTag() + ". "
|
System.out.println("Virtual call of " + methodDesc + " detected on " + node.getTag() + ". "
|
||||||
+ "Target class is " + className);
|
+ "Target class is " + className);
|
||||||
}
|
}
|
||||||
if (className.startsWith("[")) {
|
if (className.startsWith("[")) {
|
||||||
className = "java.lang.Object";
|
className = "java.lang.Object";
|
||||||
type = checker.getType(className);
|
type = analyzer.getType(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filter.match(type)) {
|
if (!filter.match(type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MethodReference methodRef = new MethodReference(className, methodDesc);
|
MethodReference methodRef = new MethodReference(className, methodDesc);
|
||||||
MethodDependency methodDep = checker.linkMethod(methodRef, new CallLocation(caller.getMethod(), location));
|
MethodDependency methodDep = analyzer.linkMethod(methodRef, new CallLocation(caller.getMethod(), location));
|
||||||
if (!methodDep.isMissing() && knownMethods.add(methodRef)) {
|
if (!methodDep.isMissing() && knownMethods.add(methodRef)) {
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
DependencyNode[] targetParams = methodDep.getVariables();
|
DependencyNode[] targetParams = methodDep.getVariables();
|
||||||
if (parameters[0] != null && targetParams[0] != null) {
|
if (parameters[0] != null && targetParams[0] != null) {
|
||||||
parameters[0].connect(targetParams[0],
|
parameters[0].connect(targetParams[0],
|
||||||
checker.getSuperClassFilter(methodDep.getMethod().getOwnerName()));
|
analyzer.getSuperClassFilter(methodDep.getMethod().getOwnerName()));
|
||||||
}
|
}
|
||||||
for (int i = 1; i < parameters.length; ++i) {
|
for (int i = 1; i < parameters.length; ++i) {
|
||||||
if (parameters[i] != null && targetParams[i] != null) {
|
if (parameters[i] != null && targetParams[i] != null) {
|
||||||
|
@ -384,7 +384,7 @@ class DependencyGraphBuilder {
|
||||||
public void classConstant(VariableReader receiver, ValueType cst) {
|
public void classConstant(VariableReader receiver, ValueType cst) {
|
||||||
DependencyNode node = nodes[receiver.getIndex()];
|
DependencyNode node = nodes[receiver.getIndex()];
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.propagate(dependencyChecker.getType("java.lang.Class"));
|
node.propagate(dependencyAnalyzer.getType("java.lang.Class"));
|
||||||
if (!(cst instanceof ValueType.Primitive)) {
|
if (!(cst instanceof ValueType.Primitive)) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
while (cst instanceof ValueType.Array) {
|
while (cst instanceof ValueType.Array) {
|
||||||
|
@ -396,7 +396,7 @@ class DependencyGraphBuilder {
|
||||||
} else {
|
} else {
|
||||||
sb.append(cst.toString());
|
sb.append(cst.toString());
|
||||||
}
|
}
|
||||||
node.getClassValueNode().propagate(dependencyChecker.getType(sb.toString()));
|
node.getClassValueNode().propagate(dependencyAnalyzer.getType(sb.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (cst instanceof ValueType.Array) {
|
while (cst instanceof ValueType.Array) {
|
||||||
|
@ -404,7 +404,7 @@ class DependencyGraphBuilder {
|
||||||
}
|
}
|
||||||
if (cst instanceof ValueType.Object) {
|
if (cst instanceof ValueType.Object) {
|
||||||
final String className = ((ValueType.Object) cst).getClassName();
|
final String className = ((ValueType.Object) cst).getClassName();
|
||||||
dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
dependencyAnalyzer.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,9 +412,9 @@ class DependencyGraphBuilder {
|
||||||
public void stringConstant(VariableReader receiver, String cst) {
|
public void stringConstant(VariableReader receiver, String cst) {
|
||||||
DependencyNode node = nodes[receiver.getIndex()];
|
DependencyNode node = nodes[receiver.getIndex()];
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.propagate(dependencyChecker.getType("java.lang.String"));
|
node.propagate(dependencyAnalyzer.getType("java.lang.String"));
|
||||||
}
|
}
|
||||||
MethodDependency method = dependencyChecker.linkMethod(new MethodReference(String.class,
|
MethodDependency method = dependencyAnalyzer.linkMethod(new MethodReference(String.class,
|
||||||
"<init>", char[].class, void.class), new CallLocation(caller.getMethod(), currentLocation));
|
"<init>", char[].class, void.class), new CallLocation(caller.getMethod(), currentLocation));
|
||||||
method.use();
|
method.use();
|
||||||
}
|
}
|
||||||
|
@ -432,13 +432,13 @@ class DependencyGraphBuilder {
|
||||||
public void cast(VariableReader receiver, VariableReader value, ValueType targetType) {
|
public void cast(VariableReader receiver, VariableReader value, ValueType targetType) {
|
||||||
DependencyNode valueNode = nodes[value.getIndex()];
|
DependencyNode valueNode = nodes[value.getIndex()];
|
||||||
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
||||||
ClassReaderSource classSource = dependencyChecker.getClassSource();
|
ClassReaderSource classSource = dependencyAnalyzer.getClassSource();
|
||||||
if (targetType instanceof ValueType.Object) {
|
if (targetType instanceof ValueType.Object) {
|
||||||
String targetClsName = ((ValueType.Object) targetType).getClassName();
|
String targetClsName = ((ValueType.Object) targetType).getClassName();
|
||||||
final ClassReader targetClass = classSource.get(targetClsName);
|
final ClassReader targetClass = classSource.get(targetClsName);
|
||||||
if (targetClass != null && !(targetClass.getName().equals("java.lang.Object"))) {
|
if (targetClass != null && !(targetClass.getName().equals("java.lang.Object"))) {
|
||||||
if (valueNode != null && receiverNode != null) {
|
if (valueNode != null && receiverNode != null) {
|
||||||
valueNode.connect(receiverNode, dependencyChecker.getSuperClassFilter(targetClass.getName()));
|
valueNode.connect(receiverNode, dependencyAnalyzer.getSuperClassFilter(targetClass.getName()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -466,11 +466,11 @@ class DependencyGraphBuilder {
|
||||||
public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) {
|
public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) {
|
||||||
DependencyNode node = nodes[receiver.getIndex()];
|
DependencyNode node = nodes[receiver.getIndex()];
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.propagate(dependencyChecker.getType("[" + itemType));
|
node.propagate(dependencyAnalyzer.getType("[" + itemType));
|
||||||
}
|
}
|
||||||
String className = extractClassName(itemType);
|
String className = extractClassName(itemType);
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
dependencyAnalyzer.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,28 +501,28 @@ class DependencyGraphBuilder {
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node.propagate(dependencyChecker.getType(sb.substring(i, sb.length())));
|
node.propagate(dependencyAnalyzer.getType(sb.substring(i, sb.length())));
|
||||||
node = node.getArrayItem();
|
node = node.getArrayItem();
|
||||||
}
|
}
|
||||||
String className = extractClassName(itemType);
|
String className = extractClassName(itemType);
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
dependencyAnalyzer.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create(VariableReader receiver, String type) {
|
public void create(VariableReader receiver, String type) {
|
||||||
dependencyChecker.linkClass(type, new CallLocation(caller.getMethod(), currentLocation));
|
dependencyAnalyzer.linkClass(type, new CallLocation(caller.getMethod(), currentLocation));
|
||||||
DependencyNode node = nodes[receiver.getIndex()];
|
DependencyNode node = nodes[receiver.getIndex()];
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.propagate(dependencyChecker.getType(type));
|
node.propagate(dependencyAnalyzer.getType(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getField(VariableReader receiver, VariableReader instance, FieldReference field,
|
public void getField(VariableReader receiver, VariableReader instance, FieldReference field,
|
||||||
ValueType fieldType) {
|
ValueType fieldType) {
|
||||||
FieldDependency fieldDep = dependencyChecker.linkField(field,
|
FieldDependency fieldDep = dependencyAnalyzer.linkField(field,
|
||||||
new CallLocation(caller.getMethod(), currentLocation));
|
new CallLocation(caller.getMethod(), currentLocation));
|
||||||
if (!(fieldType instanceof ValueType.Primitive)) {
|
if (!(fieldType instanceof ValueType.Primitive)) {
|
||||||
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
||||||
|
@ -536,7 +536,7 @@ class DependencyGraphBuilder {
|
||||||
@Override
|
@Override
|
||||||
public void putField(VariableReader instance, FieldReference field, VariableReader value,
|
public void putField(VariableReader instance, FieldReference field, VariableReader value,
|
||||||
ValueType fieldType) {
|
ValueType fieldType) {
|
||||||
FieldDependency fieldDep = dependencyChecker.linkField(field,
|
FieldDependency fieldDep = dependencyAnalyzer.linkField(field,
|
||||||
new CallLocation(caller.getMethod(), currentLocation));
|
new CallLocation(caller.getMethod(), currentLocation));
|
||||||
if (!(fieldType instanceof ValueType.Primitive)) {
|
if (!(fieldType instanceof ValueType.Primitive)) {
|
||||||
DependencyNode valueNode = nodes[value.getIndex()];
|
DependencyNode valueNode = nodes[value.getIndex()];
|
||||||
|
@ -555,7 +555,7 @@ class DependencyGraphBuilder {
|
||||||
arrayNode.addConsumer(receiverNode::propagate);
|
arrayNode.addConsumer(receiverNode::propagate);
|
||||||
arrayNode.getArrayItem().connect(receiverNode.getArrayItem());
|
arrayNode.getArrayItem().connect(receiverNode.getArrayItem());
|
||||||
}
|
}
|
||||||
MethodDependency cloneDep = dependencyChecker.linkMethod(
|
MethodDependency cloneDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "clone", Object.class),
|
new MethodReference(Object.class, "clone", Object.class),
|
||||||
new CallLocation(caller.getMethod(), currentLocation));
|
new CallLocation(caller.getMethod(), currentLocation));
|
||||||
arrayNode.connect(cloneDep.getVariable(0));
|
arrayNode.connect(cloneDep.getVariable(0));
|
||||||
|
@ -615,8 +615,8 @@ class DependencyGraphBuilder {
|
||||||
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method,
|
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||||
List<? extends VariableReader> arguments) {
|
List<? extends VariableReader> arguments) {
|
||||||
CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
|
CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
|
||||||
dependencyChecker.linkClass(method.getClassName(), callLocation).initClass(callLocation);
|
dependencyAnalyzer.linkClass(method.getClassName(), callLocation).initClass(callLocation);
|
||||||
MethodDependency methodDep = dependencyChecker.linkMethod(method, callLocation);
|
MethodDependency methodDep = dependencyAnalyzer.linkMethod(method, callLocation);
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
if (methodDep.isMissing()) {
|
if (methodDep.isMissing()) {
|
||||||
return;
|
return;
|
||||||
|
@ -650,14 +650,14 @@ class DependencyGraphBuilder {
|
||||||
}
|
}
|
||||||
actualArgs[0] = nodes[instance.getIndex()];
|
actualArgs[0] = nodes[instance.getIndex()];
|
||||||
DependencyConsumer listener = new VirtualCallConsumer(nodes[instance.getIndex()],
|
DependencyConsumer listener = new VirtualCallConsumer(nodes[instance.getIndex()],
|
||||||
method.getClassName(), method.getDescriptor(), dependencyChecker, actualArgs,
|
method.getClassName(), method.getDescriptor(), dependencyAnalyzer, actualArgs,
|
||||||
receiver != null ? nodes[receiver.getIndex()] : null, caller, currentLocation,
|
receiver != null ? nodes[receiver.getIndex()] : null, caller, currentLocation,
|
||||||
currentExceptionConsumer);
|
currentExceptionConsumer);
|
||||||
nodes[instance.getIndex()].addConsumer(listener);
|
nodes[instance.getIndex()].addConsumer(listener);
|
||||||
|
|
||||||
dependencyChecker.getClassSource().overriddenMethods(method).forEach(methodImpl -> {
|
dependencyAnalyzer.getClassSource().overriddenMethods(method).forEach(methodImpl -> {
|
||||||
CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
|
CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
|
||||||
dependencyChecker.linkMethod(methodImpl.getReference(), callLocation);
|
dependencyAnalyzer.linkMethod(methodImpl.getReference(), callLocation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,7 +665,7 @@ class DependencyGraphBuilder {
|
||||||
public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) {
|
public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) {
|
||||||
String className = extractClassName(type);
|
String className = extractClassName(type);
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
dependencyAnalyzer.linkClass(className, new CallLocation(caller.getMethod(), currentLocation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,7 +679,7 @@ class DependencyGraphBuilder {
|
||||||
@Override
|
@Override
|
||||||
public void initClass(final String className) {
|
public void initClass(final String className) {
|
||||||
CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
|
CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
|
||||||
dependencyChecker.linkClass(className, callLocation).initClass(callLocation);
|
dependencyAnalyzer.linkClass(className, callLocation).initClass(callLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -687,19 +687,19 @@ class DependencyGraphBuilder {
|
||||||
DependencyNode valueNode = nodes[value.getIndex()];
|
DependencyNode valueNode = nodes[value.getIndex()];
|
||||||
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
||||||
valueNode.connect(receiverNode);
|
valueNode.connect(receiverNode);
|
||||||
dependencyChecker.linkMethod(new MethodReference(NullPointerException.class, "<init>", void.class),
|
dependencyAnalyzer.linkMethod(new MethodReference(NullPointerException.class, "<init>", void.class),
|
||||||
new CallLocation(caller.getMethod(), currentLocation)).use();
|
new CallLocation(caller.getMethod(), currentLocation)).use();
|
||||||
currentExceptionConsumer.consume(dependencyChecker.getType("java.lang.NullPointerException"));
|
currentExceptionConsumer.consume(dependencyAnalyzer.getType("java.lang.NullPointerException"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void monitorEnter(VariableReader objectRef) {
|
public void monitorEnter(VariableReader objectRef) {
|
||||||
MethodDependency methodDep = dependencyChecker.linkMethod(
|
MethodDependency methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorEnter", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorEnter", Object.class, void.class), null);
|
||||||
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
||||||
methodDep = dependencyChecker.linkMethod(
|
methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorEnterSync", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorEnterSync", Object.class, void.class), null);
|
||||||
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
@ -707,12 +707,12 @@ class DependencyGraphBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void monitorExit(VariableReader objectRef) {
|
public void monitorExit(VariableReader objectRef) {
|
||||||
MethodDependency methodDep = dependencyChecker.linkMethod(
|
MethodDependency methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorExit", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorExit", Object.class, void.class), null);
|
||||||
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
||||||
methodDep = dependencyChecker.linkMethod(
|
methodDep = dependencyAnalyzer.linkMethod(
|
||||||
new MethodReference(Object.class, "monitorExitSync", Object.class, void.class), null);
|
new MethodReference(Object.class, "monitorExitSync", Object.class, void.class), null);
|
||||||
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
nodes[objectRef.getIndex()].connect(methodDep.getVariable(1));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.teavm.model.ValueType;
|
||||||
|
|
||||||
public class DependencyNode implements ValueDependencyInfo {
|
public class DependencyNode implements ValueDependencyInfo {
|
||||||
private static final int SMALL_TYPES_THRESHOLD = 6;
|
private static final int SMALL_TYPES_THRESHOLD = 6;
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyAnalyzer dependencyAnalyzer;
|
||||||
private List<DependencyConsumer> followers;
|
private List<DependencyConsumer> followers;
|
||||||
private int[] smallTypes;
|
private int[] smallTypes;
|
||||||
private BitSet types;
|
private BitSet types;
|
||||||
|
@ -35,12 +35,12 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
private ValueType typeFilter;
|
private ValueType typeFilter;
|
||||||
private SuperClassFilter cachedTypeFilter;
|
private SuperClassFilter cachedTypeFilter;
|
||||||
|
|
||||||
DependencyNode(DependencyChecker dependencyChecker, ValueType typeFilter) {
|
DependencyNode(DependencyAnalyzer dependencyAnalyzer, ValueType typeFilter) {
|
||||||
this(dependencyChecker, typeFilter, 0);
|
this(dependencyAnalyzer, typeFilter, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DependencyNode(DependencyChecker dependencyChecker, ValueType typeFilter, int degree) {
|
private DependencyNode(DependencyAnalyzer dependencyAnalyzer, ValueType typeFilter, int degree) {
|
||||||
this.dependencyChecker = dependencyChecker;
|
this.dependencyAnalyzer = dependencyAnalyzer;
|
||||||
this.degree = degree;
|
this.degree = degree;
|
||||||
this.typeFilter = typeFilter;
|
this.typeFilter = typeFilter;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (smallTypes.length == SMALL_TYPES_THRESHOLD) {
|
if (smallTypes.length == SMALL_TYPES_THRESHOLD) {
|
||||||
types = new BitSet(dependencyChecker.types.size() * 2);
|
types = new BitSet(dependencyAnalyzer.types.size() * 2);
|
||||||
for (int existingType : smallTypes) {
|
for (int existingType : smallTypes) {
|
||||||
types.set(existingType);
|
types.set(existingType);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (addType(type) && filter(type)) {
|
if (addType(type) && filter(type)) {
|
||||||
if (DependencyChecker.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
System.out.println(tag + " -> " + type.getName());
|
System.out.println(tag + " -> " + type.getName());
|
||||||
}
|
}
|
||||||
scheduleSingleType(type);
|
scheduleSingleType(type);
|
||||||
|
@ -103,13 +103,13 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
private void scheduleSingleType(DependencyType type) {
|
private void scheduleSingleType(DependencyType type) {
|
||||||
if (followers != null) {
|
if (followers != null) {
|
||||||
for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) {
|
for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) {
|
||||||
dependencyChecker.schedulePropagation(consumer, type);
|
dependencyAnalyzer.schedulePropagation(consumer, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transitions != null) {
|
if (transitions != null) {
|
||||||
for (DependencyNodeToNodeTransition consumer : transitions.toArray(
|
for (DependencyNodeToNodeTransition consumer : transitions.toArray(
|
||||||
new DependencyNodeToNodeTransition[transitions.size()])) {
|
new DependencyNodeToNodeTransition[transitions.size()])) {
|
||||||
dependencyChecker.schedulePropagation(consumer, type);
|
dependencyAnalyzer.schedulePropagation(consumer, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DependencyChecker.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
for (int i = 0; i < j; ++i) {
|
for (int i = 0; i < j; ++i) {
|
||||||
System.out.println(tag + " -> " + newTypes[i].getName());
|
System.out.println(tag + " -> " + newTypes[i].getName());
|
||||||
}
|
}
|
||||||
|
@ -147,13 +147,13 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
}
|
}
|
||||||
if (followers != null) {
|
if (followers != null) {
|
||||||
for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) {
|
for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) {
|
||||||
dependencyChecker.schedulePropagation(consumer, newTypes);
|
dependencyAnalyzer.schedulePropagation(consumer, newTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transitions != null) {
|
if (transitions != null) {
|
||||||
for (DependencyNodeToNodeTransition consumer : transitions.toArray(
|
for (DependencyNodeToNodeTransition consumer : transitions.toArray(
|
||||||
new DependencyNodeToNodeTransition[transitions.size()])) {
|
new DependencyNodeToNodeTransition[transitions.size()])) {
|
||||||
dependencyChecker.schedulePropagation(consumer, newTypes);
|
dependencyAnalyzer.schedulePropagation(consumer, newTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
} else {
|
} else {
|
||||||
superClass = "java.lang.Object";
|
superClass = "java.lang.Object";
|
||||||
}
|
}
|
||||||
cachedTypeFilter = dependencyChecker.getSuperClassFilter(superClass);
|
cachedTypeFilter = dependencyAnalyzer.getSuperClassFilter(superClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedTypeFilter.match(type);
|
return cachedTypeFilter.match(type);
|
||||||
|
@ -208,7 +208,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
transitions.add(transition);
|
transitions.add(transition);
|
||||||
if (DependencyChecker.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
System.out.println("Connecting " + tag + " to " + node.tag);
|
System.out.println("Connecting " + tag + " to " + node.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,17 +220,17 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
DependencyType[] types = new DependencyType[this.types.cardinality()];
|
DependencyType[] types = new DependencyType[this.types.cardinality()];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) {
|
for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) {
|
||||||
DependencyType type = dependencyChecker.types.get(index);
|
DependencyType type = dependencyAnalyzer.types.get(index);
|
||||||
types[j++] = type;
|
types[j++] = type;
|
||||||
}
|
}
|
||||||
dependencyChecker.schedulePropagation(transition, types);
|
dependencyAnalyzer.schedulePropagation(transition, types);
|
||||||
} else if (this.smallTypes != null) {
|
} else if (this.smallTypes != null) {
|
||||||
DependencyType[] types = new DependencyType[smallTypes.length];
|
DependencyType[] types = new DependencyType[smallTypes.length];
|
||||||
for (int i = 0; i < types.length; ++i) {
|
for (int i = 0; i < types.length; ++i) {
|
||||||
DependencyType type = dependencyChecker.types.get(smallTypes[i]);
|
DependencyType type = dependencyAnalyzer.types.get(smallTypes[i]);
|
||||||
types[i] = type;
|
types[i] = type;
|
||||||
}
|
}
|
||||||
dependencyChecker.schedulePropagation(transition, types);
|
dependencyAnalyzer.schedulePropagation(transition, types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,17 +239,17 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
DependencyType[] types = new DependencyType[this.types.cardinality()];
|
DependencyType[] types = new DependencyType[this.types.cardinality()];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) {
|
for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) {
|
||||||
DependencyType type = dependencyChecker.types.get(index);
|
DependencyType type = dependencyAnalyzer.types.get(index);
|
||||||
types[j++] = type;
|
types[j++] = type;
|
||||||
}
|
}
|
||||||
dependencyChecker.schedulePropagation(transition, types);
|
dependencyAnalyzer.schedulePropagation(transition, types);
|
||||||
} else if (this.smallTypes != null) {
|
} else if (this.smallTypes != null) {
|
||||||
DependencyType[] types = new DependencyType[smallTypes.length];
|
DependencyType[] types = new DependencyType[smallTypes.length];
|
||||||
for (int i = 0; i < types.length; ++i) {
|
for (int i = 0; i < types.length; ++i) {
|
||||||
DependencyType type = dependencyChecker.types.get(smallTypes[i]);
|
DependencyType type = dependencyAnalyzer.types.get(smallTypes[i]);
|
||||||
types[i] = type;
|
types[i] = type;
|
||||||
}
|
}
|
||||||
dependencyChecker.schedulePropagation(transition, types);
|
dependencyAnalyzer.schedulePropagation(transition, types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,8 +263,8 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
ValueType itemTypeFilter = typeFilter instanceof ValueType.Array
|
ValueType itemTypeFilter = typeFilter instanceof ValueType.Array
|
||||||
? ((ValueType.Array) typeFilter).getItemType()
|
? ((ValueType.Array) typeFilter).getItemType()
|
||||||
: null;
|
: null;
|
||||||
arrayItemNode = new DependencyNode(dependencyChecker, itemTypeFilter, degree + 1);
|
arrayItemNode = new DependencyNode(dependencyAnalyzer, itemTypeFilter, degree + 1);
|
||||||
if (DependencyChecker.shouldTag) {
|
if (DependencyAnalyzer.shouldTag) {
|
||||||
arrayItemNode.tag = tag + "[";
|
arrayItemNode.tag = tag + "[";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,9 +274,9 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
@Override
|
@Override
|
||||||
public DependencyNode getClassValueNode() {
|
public DependencyNode getClassValueNode() {
|
||||||
if (classValueNode == null) {
|
if (classValueNode == null) {
|
||||||
classValueNode = new DependencyNode(dependencyChecker, null, degree);
|
classValueNode = new DependencyNode(dependencyAnalyzer, null, degree);
|
||||||
classValueNode.classValueNode = classValueNode;
|
classValueNode.classValueNode = classValueNode;
|
||||||
if (DependencyChecker.shouldTag) {
|
if (DependencyAnalyzer.shouldTag) {
|
||||||
classValueNode.tag = tag + "@";
|
classValueNode.tag = tag + "@";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +302,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasType(String type) {
|
public boolean hasType(String type) {
|
||||||
return hasType(dependencyChecker.getType(type));
|
return hasType(dependencyAnalyzer.getType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -311,7 +311,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
String[] result = new String[smallTypes.length];
|
String[] result = new String[smallTypes.length];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < result.length; ++i) {
|
for (int i = 0; i < result.length; ++i) {
|
||||||
DependencyType type = dependencyChecker.types.get(smallTypes[i]);
|
DependencyType type = dependencyAnalyzer.types.get(smallTypes[i]);
|
||||||
if (filter(type)) {
|
if (filter(type)) {
|
||||||
result[j++] = type.getName();
|
result[j++] = type.getName();
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
String[] result = new String[types.cardinality()];
|
String[] result = new String[types.cardinality()];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int index = types.nextSetBit(0); index >= 0; index = types.nextSetBit(index + 1)) {
|
for (int index = types.nextSetBit(0); index >= 0; index = types.nextSetBit(index + 1)) {
|
||||||
DependencyType type = dependencyChecker.types.get(index);
|
DependencyType type = dependencyAnalyzer.types.get(index);
|
||||||
if (filter(type)) {
|
if (filter(type)) {
|
||||||
result[j++] = type.getName();
|
result[j++] = type.getName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,18 @@
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
public class DependencyType {
|
public class DependencyType {
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyAnalyzer dependencyAnalyzer;
|
||||||
private String name;
|
private String name;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
DependencyType(DependencyChecker dependencyChecker, String name, int index) {
|
DependencyType(DependencyAnalyzer dependencyAnalyzer, String name, int index) {
|
||||||
this.dependencyChecker = dependencyChecker;
|
this.dependencyAnalyzer = dependencyAnalyzer;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyChecker getDependencyChecker() {
|
DependencyAnalyzer getDependencyAnalyzer() {
|
||||||
return dependencyChecker;
|
return dependencyAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -35,6 +35,6 @@ public class DependencyType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyAgent getDependencyAgent() {
|
public DependencyAgent getDependencyAgent() {
|
||||||
return dependencyChecker.getAgent();
|
return dependencyAnalyzer.getAgent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class MethodDependency implements MethodDependencyInfo {
|
public class MethodDependency implements MethodDependencyInfo {
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyAnalyzer dependencyAnalyzer;
|
||||||
DependencyNode[] variableNodes;
|
DependencyNode[] variableNodes;
|
||||||
private int parameterCount;
|
private int parameterCount;
|
||||||
DependencyNode resultNode;
|
DependencyNode resultNode;
|
||||||
|
@ -32,9 +32,9 @@ public class MethodDependency implements MethodDependencyInfo {
|
||||||
DependencyPlugin dependencyPlugin;
|
DependencyPlugin dependencyPlugin;
|
||||||
boolean dependencyPluginAttached;
|
boolean dependencyPluginAttached;
|
||||||
|
|
||||||
MethodDependency(DependencyChecker dependencyChecker, DependencyNode[] variableNodes, int parameterCount,
|
MethodDependency(DependencyAnalyzer dependencyAnalyzer, DependencyNode[] variableNodes, int parameterCount,
|
||||||
DependencyNode resultNode, DependencyNode thrown, MethodHolder method, MethodReference reference) {
|
DependencyNode resultNode, DependencyNode thrown, MethodHolder method, MethodReference reference) {
|
||||||
this.dependencyChecker = dependencyChecker;
|
this.dependencyAnalyzer = dependencyAnalyzer;
|
||||||
this.variableNodes = Arrays.copyOf(variableNodes, variableNodes.length);
|
this.variableNodes = Arrays.copyOf(variableNodes, variableNodes.length);
|
||||||
this.parameterCount = parameterCount;
|
this.parameterCount = parameterCount;
|
||||||
this.thrown = thrown;
|
this.thrown = thrown;
|
||||||
|
@ -44,7 +44,7 @@ public class MethodDependency implements MethodDependencyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyAgent getDependencyAgent() {
|
public DependencyAgent getDependencyAgent() {
|
||||||
return dependencyChecker.getAgent();
|
return dependencyAnalyzer.getAgent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,11 +101,11 @@ public class MethodDependency implements MethodDependencyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDependency propagate(int parameterIndex, Class<?> type) {
|
public MethodDependency propagate(int parameterIndex, Class<?> type) {
|
||||||
return propagate(parameterIndex, dependencyChecker.getType(type.getName()));
|
return propagate(parameterIndex, dependencyAnalyzer.getType(type.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDependency propagate(int parameterIndex, String type) {
|
public MethodDependency propagate(int parameterIndex, String type) {
|
||||||
return propagate(parameterIndex, dependencyChecker.getType(type));
|
return propagate(parameterIndex, dependencyAnalyzer.getType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDependency propagate(int parameterIndex, DependencyType type) {
|
public MethodDependency propagate(int parameterIndex, DependencyType type) {
|
||||||
|
@ -117,7 +117,7 @@ public class MethodDependency implements MethodDependencyInfo {
|
||||||
if (!used) {
|
if (!used) {
|
||||||
used = true;
|
used = true;
|
||||||
if (!isMissing()) {
|
if (!isMissing()) {
|
||||||
dependencyChecker.scheduleMethodAnalysis(this);
|
dependencyAnalyzer.scheduleMethodAnalysis(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
||||||
import org.teavm.cache.NoCache;
|
import org.teavm.cache.NoCache;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
||||||
import org.teavm.dependency.DependencyChecker;
|
import org.teavm.dependency.DependencyAnalyzer;
|
||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.dependency.Linker;
|
import org.teavm.dependency.Linker;
|
||||||
|
@ -103,7 +103,7 @@ import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
*/
|
*/
|
||||||
public class TeaVM implements TeaVMHost, ServiceRepository {
|
public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
private final ClassReaderSource classSource;
|
private final ClassReaderSource classSource;
|
||||||
private final DependencyChecker dependencyChecker;
|
private final DependencyAnalyzer dependencyAnalyzer;
|
||||||
private final AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
|
private final AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
private final Map<String, TeaVMEntryPoint> entryPoints = new HashMap<>();
|
private final Map<String, TeaVMEntryPoint> entryPoints = new HashMap<>();
|
||||||
|
@ -125,7 +125,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
target = builder.target;
|
target = builder.target;
|
||||||
classSource = builder.classSource;
|
classSource = builder.classSource;
|
||||||
classLoader = builder.classLoader;
|
classLoader = builder.classLoader;
|
||||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, diagnostics);
|
dependencyAnalyzer = new DependencyAnalyzer(this.classSource, classLoader, this, diagnostics);
|
||||||
progressListener = new TeaVMProgressListener() {
|
progressListener = new TeaVMProgressListener() {
|
||||||
@Override public TeaVMProgressFeedback progressReached(int progress) {
|
@Override public TeaVMProgressFeedback progressReached(int progress) {
|
||||||
return TeaVMProgressFeedback.CONTINUE;
|
return TeaVMProgressFeedback.CONTINUE;
|
||||||
|
@ -136,10 +136,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (ClassHolderTransformer transformer : target.getTransformers()) {
|
for (ClassHolderTransformer transformer : target.getTransformers()) {
|
||||||
dependencyChecker.addClassTransformer(transformer);
|
dependencyAnalyzer.addClassTransformer(transformer);
|
||||||
}
|
}
|
||||||
for (DependencyListener listener : target.getDependencyListeners()) {
|
for (DependencyListener listener : target.getDependencyListeners()) {
|
||||||
dependencyChecker.addDependencyListener(listener);
|
dependencyAnalyzer.addDependencyListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TeaVMHostExtension extension : target.getHostExtensions()) {
|
for (TeaVMHostExtension extension : target.getHostExtensions()) {
|
||||||
|
@ -151,17 +151,17 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(DependencyListener listener) {
|
public void add(DependencyListener listener) {
|
||||||
dependencyChecker.addDependencyListener(listener);
|
dependencyAnalyzer.addDependencyListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(ClassHolderTransformer transformer) {
|
public void add(ClassHolderTransformer transformer) {
|
||||||
dependencyChecker.addClassTransformer(transformer);
|
dependencyAnalyzer.addClassTransformer(transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor) {
|
public void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor) {
|
||||||
dependencyChecker.addBootstrapMethodSubstitutor(methodRef, substitutor);
|
dependencyAnalyzer.addBootstrapMethodSubstitutor(methodRef, substitutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -248,8 +248,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
+ "for method " + ref);
|
+ "for method " + ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, ref, dependencyChecker.linkMethod(ref, null));
|
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, ref, dependencyAnalyzer.linkMethod(ref, null));
|
||||||
dependencyChecker.linkClass(ref.getClassName(), null).initClass(null);
|
dependencyAnalyzer.linkClass(ref.getClassName(), null).initClass(null);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
entryPoints.put(name, entryPoint);
|
entryPoints.put(name, entryPoint);
|
||||||
}
|
}
|
||||||
|
@ -273,8 +273,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TeaVMEntryPoint linkMethod(MethodReference ref) {
|
public TeaVMEntryPoint linkMethod(MethodReference ref) {
|
||||||
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint("", ref, dependencyChecker.linkMethod(ref, null));
|
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint("", ref, dependencyAnalyzer.linkMethod(ref, null));
|
||||||
dependencyChecker.linkClass(ref.getClassName(), null).initClass(null);
|
dependencyAnalyzer.linkClass(ref.getClassName(), null).initClass(null);
|
||||||
return entryPoint;
|
return entryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
throw new IllegalArgumentException("Class with public name `" + name + "' already defined for class "
|
throw new IllegalArgumentException("Class with public name `" + name + "' already defined for class "
|
||||||
+ className);
|
+ className);
|
||||||
}
|
}
|
||||||
dependencyChecker.linkClass(className, null).initClass(null);
|
dependencyAnalyzer.linkClass(className, null).initClass(null);
|
||||||
exportedClasses.put(name, className);
|
exportedClasses.put(name, className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,22 +300,22 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
/**
|
/**
|
||||||
* Gets a {@link ClassReaderSource} which is similar to that of {@link #getClassSource()},
|
* Gets a {@link ClassReaderSource} which is similar to that of {@link #getClassSource()},
|
||||||
* except that it also contains classes with applied transformations together with
|
* except that it also contains classes with applied transformations together with
|
||||||
* classes, generated via {@link DependencyChecker#submitClass(ClassHolder)}.
|
* classes, generated via {@link DependencyAnalyzer#submitClass(ClassHolder)}.
|
||||||
*/
|
*/
|
||||||
public ClassReaderSource getDependencyClassSource() {
|
public ClassReaderSource getDependencyClassSource() {
|
||||||
return dependencyChecker.getClassSource();
|
return dependencyAnalyzer.getClassSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getClasses() {
|
public Collection<String> getClasses() {
|
||||||
return dependencyChecker.getReachableClasses();
|
return dependencyAnalyzer.getReachableClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MethodReference> getMethods() {
|
public Collection<MethodReference> getMethods() {
|
||||||
return dependencyChecker.getReachableMethods();
|
return dependencyAnalyzer.getReachableMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyInfo getDependencyInfo() {
|
public DependencyInfo getDependencyInfo() {
|
||||||
return dependencyChecker;
|
return dependencyAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListableClassReaderSource getWrittenClasses() {
|
public ListableClassReaderSource getWrittenClasses() {
|
||||||
|
@ -337,14 +337,14 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
target.setController(targetController);
|
target.setController(targetController);
|
||||||
|
|
||||||
// Check dependencies
|
// Check dependencies
|
||||||
reportPhase(TeaVMPhase.DEPENDENCY_CHECKING, 1);
|
reportPhase(TeaVMPhase.DEPENDENCY_ANALYSIS, 1);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyChecker.setInterruptor(() -> progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE);
|
dependencyAnalyzer.setInterruptor(() -> progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE);
|
||||||
target.contributeDependencies(dependencyChecker);
|
target.contributeDependencies(dependencyAnalyzer);
|
||||||
dependencyChecker.processDependencies();
|
dependencyAnalyzer.processDependencies();
|
||||||
if (wasCancelled() || !diagnostics.getSevereProblems().isEmpty()) {
|
if (wasCancelled() || !diagnostics.getSevereProblems().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ListableClassHolderSource classSet = link(dependencyChecker);
|
ListableClassHolderSource classSet = link(dependencyAnalyzer);
|
||||||
writtenClasses = classSet;
|
writtenClasses = classSet;
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
|
@ -364,12 +364,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
reportPhase(TeaVMPhase.OPTIMIZATION, 1);
|
reportPhase(TeaVMPhase.OPTIMIZATION, 1);
|
||||||
|
|
||||||
if (!incremental) {
|
if (!incremental) {
|
||||||
devirtualize(classSet, dependencyChecker);
|
devirtualize(classSet, dependencyAnalyzer);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline(classSet, dependencyChecker);
|
inline(classSet, dependencyAnalyzer);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -543,7 +543,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DependencyInfo getDependencyInfo() {
|
public DependencyInfo getDependencyInfo() {
|
||||||
return dependencyChecker;
|
return dependencyAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -629,12 +629,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassReaderSource getUnprocessedClassSource() {
|
public ClassReaderSource getUnprocessedClassSource() {
|
||||||
return dependencyChecker.getClassSource();
|
return dependencyAnalyzer.getClassSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DependencyInfo getDependencyInfo() {
|
public DependencyInfo getDependencyInfo() {
|
||||||
return dependencyChecker;
|
return dependencyAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
package org.teavm.vm;
|
package org.teavm.vm;
|
||||||
|
|
||||||
public enum TeaVMPhase {
|
public enum TeaVMPhase {
|
||||||
DEPENDENCY_CHECKING,
|
DEPENDENCY_ANALYSIS,
|
||||||
LINKING,
|
LINKING,
|
||||||
OPTIMIZATION,
|
OPTIMIZATION,
|
||||||
DECOMPILATION,
|
DECOMPILATION,
|
||||||
|
|
|
@ -17,7 +17,7 @@ package org.teavm.vm;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.teavm.dependency.DependencyChecker;
|
import org.teavm.dependency.DependencyAnalyzer;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
import org.teavm.model.ListableClassHolderSource;
|
import org.teavm.model.ListableClassHolderSource;
|
||||||
|
@ -37,7 +37,7 @@ public interface TeaVMTarget {
|
||||||
|
|
||||||
boolean requiresRegisterAllocation();
|
boolean requiresRegisterAllocation();
|
||||||
|
|
||||||
void contributeDependencies(DependencyChecker dependencyChecker);
|
void contributeDependencies(DependencyAnalyzer dependencyAnalyzer);
|
||||||
|
|
||||||
void afterOptimizations(Program program, MethodReader method, ListableClassReaderSource classSource);
|
void afterOptimizations(Program program, MethodReader method, ListableClassReaderSource classSource);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.teavm.vm.TeaVM;
|
||||||
*/
|
*/
|
||||||
public interface MetadataGeneratorContext extends ServiceRepository {
|
public interface MetadataGeneratorContext extends ServiceRepository {
|
||||||
/**
|
/**
|
||||||
* Gets the collection of all classes that were achieved by the dependency checker.
|
* Gets the collection of all classes that were reached by the dependency analyzer.
|
||||||
*
|
*
|
||||||
* @return class source.
|
* @return class source.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -94,30 +94,30 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodReached(DependencyAgent checker, MethodDependency method, CallLocation location) {
|
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
MethodReference asyncRef = getAsyncReference(ref);
|
MethodReference asyncRef = getAsyncReference(ref);
|
||||||
MethodDependency asyncMethod = checker.linkMethod(asyncRef, location);
|
MethodDependency asyncMethod = agent.linkMethod(asyncRef, location);
|
||||||
int paramCount = ref.parameterCount();
|
int paramCount = ref.parameterCount();
|
||||||
for (int i = 0; i <= paramCount; ++i) {
|
for (int i = 0; i <= paramCount; ++i) {
|
||||||
method.getVariable(i).connect(asyncMethod.getVariable(i));
|
method.getVariable(i).connect(asyncMethod.getVariable(i));
|
||||||
}
|
}
|
||||||
asyncMethod.getVariable(paramCount + 1).propagate(checker.getType(AsyncCallbackWrapper.class.getName()));
|
asyncMethod.getVariable(paramCount + 1).propagate(agent.getType(AsyncCallbackWrapper.class.getName()));
|
||||||
|
|
||||||
MethodDependency completeMethod = checker.linkMethod(
|
MethodDependency completeMethod = agent.linkMethod(
|
||||||
new MethodReference(AsyncCallbackWrapper.class, "complete", Object.class, void.class), null);
|
new MethodReference(AsyncCallbackWrapper.class, "complete", Object.class, void.class), null);
|
||||||
if (method.getResult() != null) {
|
if (method.getResult() != null) {
|
||||||
completeMethod.getVariable(1).connect(method.getResult(), type -> checker.getClassSource()
|
completeMethod.getVariable(1).connect(method.getResult(), type -> agent.getClassSource()
|
||||||
.isSuperType(ref.getReturnType(), ValueType.object(type.getName())).orElse(false));
|
.isSuperType(ref.getReturnType(), ValueType.object(type.getName())).orElse(false));
|
||||||
}
|
}
|
||||||
completeMethod.use();
|
completeMethod.use();
|
||||||
|
|
||||||
MethodDependency errorMethod = checker.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "error",
|
MethodDependency errorMethod = agent.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "error",
|
||||||
Throwable.class, void.class), null);
|
Throwable.class, void.class), null);
|
||||||
errorMethod.getVariable(1).connect(method.getThrown());
|
errorMethod.getVariable(1).connect(method.getThrown());
|
||||||
errorMethod.use();
|
errorMethod.use();
|
||||||
|
|
||||||
checker.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "create",
|
agent.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "create",
|
||||||
AsyncCallback.class, AsyncCallbackWrapper.class), null).use();
|
AsyncCallback.class, AsyncCallbackWrapper.class), null).use();
|
||||||
|
|
||||||
asyncMethod.use();
|
asyncMethod.use();
|
||||||
|
|
|
@ -53,10 +53,10 @@ public class NewInstanceDependencySupport extends AbstractDependencyListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachConstructor(DependencyAgent checker, String type, CallLocation location) {
|
private void attachConstructor(DependencyAgent agent, String type, CallLocation location) {
|
||||||
MethodReference ref = new MethodReference(type, "<init>", ValueType.VOID);
|
MethodReference ref = new MethodReference(type, "<init>", ValueType.VOID);
|
||||||
MethodDependency methodDep = checker.linkMethod(ref, location);
|
MethodDependency methodDep = agent.linkMethod(ref, location);
|
||||||
methodDep.getVariable(0).propagate(checker.getType(type));
|
methodDep.getVariable(0).propagate(agent.getType(type));
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class DependencyTest {
|
||||||
vm.setProgressListener(new TeaVMProgressListener() {
|
vm.setProgressListener(new TeaVMProgressListener() {
|
||||||
@Override
|
@Override
|
||||||
public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) {
|
public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) {
|
||||||
return phase == TeaVMPhase.DEPENDENCY_CHECKING
|
return phase == TeaVMPhase.DEPENDENCY_ANALYSIS
|
||||||
? TeaVMProgressFeedback.CONTINUE
|
? TeaVMProgressFeedback.CONTINUE
|
||||||
: TeaVMProgressFeedback.CANCEL;
|
: TeaVMProgressFeedback.CANCEL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -552,14 +552,14 @@ public final class TeaVMRunner {
|
||||||
}
|
}
|
||||||
phaseStartTime = System.currentTimeMillis();
|
phaseStartTime = System.currentTimeMillis();
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case DEPENDENCY_CHECKING:
|
case DEPENDENCY_ANALYSIS:
|
||||||
System.out.print("Finding methods to decompile...");
|
System.out.print("Analyzing classes...");
|
||||||
break;
|
break;
|
||||||
case LINKING:
|
case LINKING:
|
||||||
System.out.print("Linking methods...");
|
System.out.print("Linking methods...");
|
||||||
break;
|
break;
|
||||||
case OPTIMIZATION:
|
case OPTIMIZATION:
|
||||||
System.out.print("Applying devirtualization...");
|
System.out.print("Optimizing code...");
|
||||||
break;
|
break;
|
||||||
case DECOMPILATION:
|
case DECOMPILATION:
|
||||||
System.out.print("Decompiling...");
|
System.out.print("Decompiling...");
|
||||||
|
|
|
@ -43,7 +43,7 @@ class TeaVMEclipseProgressListener implements TeaVMProgressListener {
|
||||||
case DECOMPILATION:
|
case DECOMPILATION:
|
||||||
taskName = "Decompiling";
|
taskName = "Decompiling";
|
||||||
break;
|
break;
|
||||||
case DEPENDENCY_CHECKING:
|
case DEPENDENCY_ANALYSIS:
|
||||||
taskName = "Dependency checking";
|
taskName = "Dependency checking";
|
||||||
break;
|
break;
|
||||||
case OPTIMIZATION:
|
case OPTIMIZATION:
|
||||||
|
|
|
@ -171,7 +171,7 @@ class TeaVMBuild {
|
||||||
|
|
||||||
private static String phaseName(TeaVMPhase phase) {
|
private static String phaseName(TeaVMPhase phase) {
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case DEPENDENCY_CHECKING:
|
case DEPENDENCY_ANALYSIS:
|
||||||
return "Discovering classes to compile";
|
return "Discovering classes to compile";
|
||||||
case LINKING:
|
case LINKING:
|
||||||
return "Resolving method invocations";
|
return "Resolving method invocations";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user