public void preserveType(String className) { dependencyAnalyzer.defer(() -> { dependencyAnalyzer.linkClass(className).initClass(null); }); preservedClasses.add(className); }
private void linkClassIfNecessary(DependencyAgent agent, MemberReader member, CallLocation location) { if (member.hasModifier(ElementModifier.STATIC)) { agent.linkClass(member.getOwnerName()).initClass(location); } }
@Override public void initClass(String className) { getAnalyzer().linkClass(className).initClass(getCallLocation()); }
@Override protected void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments) { CallLocation callLocation = impreciseLocation; if (instance == null) { dependencyAnalyzer.linkClass(method.getClassName()).initClass(callLocation); } MethodDependency methodDep = dependencyAnalyzer.linkMethod(method); methodDep.addLocation(callLocation); methodDep.use(); }
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); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { switch (method.getMethod().getName()) { case "initialize": method.getVariable(0).getClassValueNode().addConsumer(type -> { ClassDependency classDep = agent.linkClass(type.getName()); if (classDep != null) { classDep.initClass(new CallLocation(method.getReference())); } }); break; case "getSimpleNameCacheLowLevel": method.getResult().propagate(agent.getType("java.lang.String")); break; } } }
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; }
CallLocation callLocation = getCallLocation(); if (instance == null) { dependencyAnalyzer.linkClass(method.getClassName()).initClass(callLocation); } else { dependencyAnalyzer.linkClass(method.getClassName());
public void exportType(String name, String className) { if (exportedClasses.containsKey(name)) { throw new IllegalArgumentException("Class with public name `" + name + "' already defined for class " + className); } dependencyChecker.linkClass(className, null).initClass(null); exportedClasses.put(name, className); }
@Override public void initClass(final String className) { CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation); dependencyChecker.linkClass(className, callLocation).initClass(callLocation); }
/** * <p>Adds an entry point. TeaVM guarantees, that all methods that are required by the entry point * will be available at run-time in browser. Also you need to specify for each parameter of entry point * which actual types will be passed here by calling {@link TeaVMEntryPoint#withValue(int, String)}. * It is highly recommended to read explanation on {@link TeaVMEntryPoint} class documentation.</p> * * <p>You should call this method after installing all plugins and interceptors, but before * doing the actual build.</p> * * @param name the name under which this entry point will be available for JavaScript code. * @param ref a full reference to the method which is an entry point. * @return an entry point that you can additionally adjust. */ public TeaVMEntryPoint entryPoint(String name, MethodReference ref) { if (name != null) { if (entryPoints.containsKey(name)) { throw new IllegalArgumentException("Entry point with public name `" + name + "' already defined " + "for method " + ref); } } TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, ref, dependencyChecker.linkMethod(ref, null)); dependencyChecker.linkClass(ref.getClassName(), null).initClass(null); if (name != null) { entryPoints.put(name, entryPoint); } return entryPoint; }
public TeaVMEntryPoint linkMethod(MethodReference ref) { TeaVMEntryPoint entryPoint = new TeaVMEntryPoint("", ref, dependencyChecker.linkMethod(ref, null)); dependencyChecker.linkClass(ref.getClassName(), null).initClass(null); return entryPoint; }
private FieldDependency createFieldNode(FieldReference fieldRef, FieldReader field) { DependencyNode node = createNode(); if (shouldLog) { node.setTag(fieldRef.getClassName() + "#" + fieldRef.getFieldName()); } FieldDependency dep = new FieldDependency(node, field, fieldRef); if (!dep.isMissing()) { tasks.add(() -> linkClass(fieldRef.getClassName(), null).initClass(null)); } return dep; }
public FieldDependency linkField(FieldReference fieldRef, CallLocation location) { if (completing) { throw new IllegalStateException("Can't submit class during completion phase"); } boolean added; if (location != null) { added = callGraph.getNode(location.getMethod()).addFieldAccess(fieldRef, location.getSourceLocation()); } else { added = fieldsAddedByRoot.add(fieldRef); } FieldDependency dep = fieldCache.map(fieldRef); if (!dep.isMissing()) { tasks.add(() -> linkClass(fieldRef.getClassName(), location).initClass(location)); } if (!dep.isMissing() && added) { for (DependencyListener listener : listeners) { listener.fieldReached(agent, dep, location); } } return dep; }
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments) { CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation); dependencyChecker.linkClass(method.getClassName(), callLocation).initClass(callLocation); MethodDependency methodDep = dependencyChecker.linkMethod(method, callLocation); if (methodDep.isMissing()) { return; } methodDep.use(); DependencyNode[] targetParams = methodDep.getVariables(); for (int i = 0; i < arguments.size(); ++i) { DependencyNode value = nodes[arguments.get(i).getIndex()]; DependencyNode param = targetParams[i + 1]; if (value != null && param != null) { value.connect(param); } } if (instance != null) { nodes[instance.getIndex()].connect(targetParams[0]); } if (methodDep.getResult() != null && receiver != null) { DependencyNode receiverNode = nodes[receiver.getIndex()]; if (methodDep.getResult() != null && receiverNode != null) { methodDep.getResult().connect(receiverNode); } } methodDep.getThrown().addConsumer(currentExceptionConsumer); initClass(method.getClassName()); }
tasks.add(() -> { CallLocation caller = new CallLocation(dep.getMethod().getReference()); linkClass(dep.getMethod().getOwnerName(), caller).initClass(caller); });