public ClassDependency linkClass(String className) { return analyzer.linkClass(className); }
public void preserveType(String className) { dependencyAnalyzer.defer(() -> { dependencyAnalyzer.linkClass(className).initClass(null); }); preservedClasses.add(className); }
@Override public void isInstance(VariableReader receiver, VariableReader value, ValueType type) { String className = extractClassName(type); if (className != null) { getAnalyzer().linkClass(className); } }
@Override public void initClass(String className) { getAnalyzer().linkClass(className).initClass(getCallLocation()); }
@Override public void create(VariableReader receiver, String type) { getAnalyzer().linkClass(type); DependencyNode node = getNode(receiver); if (node != null) { node.propagate(getAnalyzer().getType(type)); } }
public ClassDependency linkClass(String className) { if (completing && getClass(className) == null) { throw new IllegalStateException("Can't link class during completion phase"); } ClassDependency dep = classCache.map(className); if (!dep.activated) { dep.activated = true; if (!dep.isMissing()) { deferredTasks.add(() -> { for (DependencyListener listener : listeners) { listener.classReached(agent, className); } }); ClassReader cls = dep.getClassReader(); if (cls.getParent() != null && !classCache.caches(cls.getParent())) { linkClass(cls.getParent()); } for (String iface : cls.getInterfaces()) { if (!classCache.caches(iface)) { linkClass(iface); } } } } return dep; }
@Override public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) { DependencyNode node = getNode(receiver); if (node != null) { node.propagate(getAnalyzer().getType("[" + itemType)); } String className = extractClassName(itemType); if (className != null) { getAnalyzer().linkClass(className); } }
@Override public void classConstant(VariableReader receiver, ValueType cst) { DependencyNode node = getNode(receiver); if (node != null) { node.propagate(getAnalyzer().getType("java.lang.Class")); if (!(cst instanceof ValueType.Primitive)) { StringBuilder sb = new StringBuilder(); if (cst instanceof ValueType.Object) { sb.append(((ValueType.Object) cst).getClassName()); } else { sb.append(cst.toString()); } node.getClassValueNode().propagate(getAnalyzer().getType(sb.toString())); } else { node.getClassValueNode().propagate(getAnalyzer().getType("~" + cst.toString())); } } while (cst instanceof ValueType.Array) { cst = ((ValueType.Array) cst).getItemType(); } if (cst instanceof ValueType.Object) { String className = ((ValueType.Object) cst).getClassName(); getAnalyzer().linkClass(className); } }
@Override public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) { dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "allocate", RuntimeClass.class, Address.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "allocateArray", RuntimeClass.class, int.class, Address.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "allocateMultiArray", RuntimeClass.class, Address.class, int.class, RuntimeArray.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(ExceptionHandling.class, "throwException", Throwable.class, void.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(ExceptionHandling.class, "throwClassCastException", void.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(ExceptionHandling.class, "throwNullPointerException", void.class)).use(); dependencyAnalyzer.linkMethod(new MethodReference(ExceptionHandling.class, "catchException", Throwable.class)).use(); dependencyAnalyzer.linkClass("java.lang.String"); dependencyAnalyzer.linkClass("java.lang.Class"); dependencyAnalyzer.linkField(new FieldReference("java.lang.String", "hashCode")); ClassDependency runtimeClassDep = dependencyAnalyzer.linkClass(RuntimeClass.class.getName()); ClassDependency runtimeObjectDep = dependencyAnalyzer.linkClass(RuntimeObject.class.getName()); ClassDependency runtimeArrayDep = dependencyAnalyzer.linkClass(RuntimeArray.class.getName()); for (ClassDependency classDep : Arrays.asList(runtimeClassDep, runtimeObjectDep, runtimeArrayDep)) { for (FieldReader field : classDep.getClassReader().getFields()) { dependencyAnalyzer.linkField(field.getReference()); } } }
@Override public void createArray(VariableReader receiver, ValueType itemType, List<? extends VariableReader> dimensions) { DependencyNode node = getNode(receiver); for (int i = 0; i < dimensions.size(); ++i) { if (node == null) { break; } String itemTypeStr; if (itemType instanceof ValueType.Object) { itemTypeStr = ((ValueType.Object) itemType).getClassName(); } else { itemTypeStr = itemType.toString(); } node.propagate(getAnalyzer().getType(itemTypeStr)); node = node.getArrayItem(); itemType = ((ValueType.Array) itemType).getItemType(); } String className = extractClassName(itemType); if (className != null) { getAnalyzer().linkClass(className); } }
public void entryPoint(String className, String name) { if (entryPoints.containsKey(name)) { throw new IllegalArgumentException("Entry point with public name `" + name + "' already defined " + "for class " + className); } ClassReader cls = dependencyAnalyzer.getClassSource().get(className); if (cls == null) { diagnostics.error(null, "There's no main class: '{{c0}}'", className); return; } if (cls.getMethod(MAIN_METHOD_DESC) == null) { diagnostics.error(null, "Specified main class '{{c0}}' does not have method '" + MAIN_METHOD_DESC + "'", cls.getName()); return; } MethodDependency mainMethod = dependencyAnalyzer.linkMethod(new MethodReference(className, "main", ValueType.parse(String[].class), ValueType.VOID)); TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, mainMethod); dependencyAnalyzer.defer(() -> { dependencyAnalyzer.linkClass(className).initClass(null); mainMethod.getVariable(1).propagate(dependencyAnalyzer.getType("[Ljava/lang/String;")); mainMethod.getVariable(1).getArrayItem().propagate(dependencyAnalyzer.getType("java.lang.String")); mainMethod.use(); }); entryPoints.put(name, entryPoint); }
private MethodDependency createMethodDep(MethodReference methodRef, MethodHolder method) { ValueType[] arguments = methodRef.getParameterTypes(); int paramCount = arguments.length + 1; DependencyNode[] parameterNodes = new DependencyNode[arguments.length + 1]; parameterNodes[0] = createParameterNode(methodRef, ValueType.object(methodRef.getClassName()), 0); for (int i = 0; i < arguments.length; ++i) { parameterNodes[i + 1] = createParameterNode(methodRef, arguments[i], i + 1); } DependencyNode resultNode; if (methodRef.getDescriptor().getResultType() == ValueType.VOID) { resultNode = null; } else { resultNode = createResultNode(methodRef); } DependencyNode thrown = createThrownNode(methodRef); MethodDependency dep = new MethodDependency(this, parameterNodes, paramCount, resultNode, thrown, method, methodRef); if (method != null) { deferredTasks.add(() -> linkClass(dep.getMethod().getOwnerName()) .initClass(new CallLocation(dep.getMethod().getReference()))); } return dep; }
dependencyAnalyzer.linkClass(tryCatch.getExceptionType());
ClassDependency runtimeClassDep = dependencyAnalyzer.linkClass(RuntimeClass.class.getName()); ClassDependency runtimeObjectDep = dependencyAnalyzer.linkClass(RuntimeObject.class.getName()); ClassDependency runtimeArrayDep = dependencyAnalyzer.linkClass(RuntimeArray.class.getName()); for (ClassDependency classDep : Arrays.asList(runtimeClassDep, runtimeObjectDep, runtimeArrayDep)) { for (FieldReader field : classDep.getClassReader().getFields()) {