@Override public void raise(VariableReader exception) { nodes[exception.getIndex()].addConsumer(currentExceptionConsumer); }
FastVirtualCallConsumer getVirtualCallConsumer(MethodReference method) { return virtualCallConsumers.computeIfAbsent(method, key -> { FastVirtualCallConsumer consumer = new FastVirtualCallConsumer(instancesNode, key.getDescriptor(), this); defer(() -> { getSubtypeNode(method.getClassName()).addConsumer(consumer); }); return consumer; }); }
private void reachGetLength(DependencyAgent agent, MethodDependency method) { method.getVariable(1).addConsumer(type -> { if (!type.getName().startsWith("[")) { MethodReference cons = new MethodReference(IllegalArgumentException.class, "<init>", void.class); agent.linkMethod(cons).use(); } }); }
private void reachSet(DependencyAgent agent, MethodDependency method) { method.getVariable(3).connect(method.getVariable(1).getArrayItem()); method.getVariable(1).addConsumer(type -> { if (type.getName().startsWith("[")) { String typeName = type.getName().substring(1); for (int i = 0; i < primitiveTypes.length; ++i) { if (primitiveTypes[i].toString().equals(typeName)) { String wrapper = "java.lang." + primitiveWrappers[i]; MethodReference methodRef = new MethodReference(wrapper, primitives[i].toLowerCase() + "Value", primitiveTypes[i]); agent.linkMethod(methodRef).use(); } } } }); } }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodReader reader = method.getMethod(); if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstanceImpl")) { allClassesNode.connect(method.getResult()); MethodReference methodRef = reader.getReference(); method.getResult().addConsumer(type -> attachConstructor(agent, type.getName(), new CallLocation(methodRef))); } }
private void reachGetComponentType(DependencyAgent agent, MethodDependency method) { method.getVariable(0).getClassValueNode().addConsumer(t -> { if (!t.getName().startsWith("[")) { return; } String typeName = t.getName().substring(1); if (typeName.charAt(0) == 'L') { typeName = ((ValueType.Object) ValueType.parse(typeName)).getClassName(); } method.getResult().getClassValueNode().propagate(agent.getType(typeName)); }); }
public FastDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Diagnostics diagnostics) { super(classSource, classLoader, services, diagnostics); instancesNode = new DependencyNode(this, null); classesNode = new DependencyNode(this, null); instancesNode.addConsumer(type -> { getSubtypeNode(type.getName()).propagate(type); }); }
private void reachGet(DependencyAgent agent, MethodDependency method) { method.getVariable(1).getArrayItem().connect(method.getResult()); method.getVariable(1).addConsumer(type -> { if (type.getName().startsWith("[")) { String typeName = type.getName().substring(1); for (int i = 0; i < primitiveTypes.length; ++i) { if (primitiveTypes[i].toString().equals(typeName)) { String wrapper = "java.lang." + primitiveWrappers[i]; MethodReference methodRef = new MethodReference(wrapper, "valueOf", primitiveTypes[i], ValueType.object(wrapper)); agent.linkMethod(methodRef).use(); method.getResult().propagate(agent.getType("java.lang." + primitiveWrappers[i])); } } } }); }
void installProxyEmitter() { Diagnostics diagnostics = agent.getDiagnostics(); try { proxyMethod = getJavaMethod(classLoader, model.getMetaMethod()); proxyMethod.setAccessible(true); } catch (ReflectiveOperationException e) { StringWriter stackTraceWriter = new StringWriter(); e.printStackTrace(new PrintWriter(stackTraceWriter)); diagnostics.error(location, "Error accessing proxy method {{m0}}: " + stackTraceWriter.getBuffer(), model.getMetaMethod()); return; } nameDependency = installAdditionalDependencies(); if (model.getClassParameterIndex() >= 0) { int index = 1 + model.getClassParameterIndex(); methodDep.getVariable(index).getClassValueNode().addConsumer( type -> emitPermutation(findClass(type.getName()))); } else { emitPermutation(null); } }
@Override protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments) { DependencyNode[] actualArgs = new DependencyNode[arguments.size() + 1]; for (int i = 0; i < arguments.size(); ++i) { actualArgs[i + 1] = nodes[arguments.get(i).getIndex()]; } actualArgs[0] = getNode(instance); DependencyConsumer listener = new VirtualCallConsumer(getNode(instance), method.getClassName(), method.getDescriptor(), dependencyAnalyzer, actualArgs, receiver != null ? getNode(receiver) : null, getCallLocation(), currentExceptionConsumer); getNode(instance).addConsumer(listener); dependencyAnalyzer.getClassSource().overriddenMethods(method).forEach(methodImpl -> { dependencyAnalyzer.linkMethod(methodImpl.getReference()).addLocation(getCallLocation()); }); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodReference ref = method.getReference(); if (ref.getClassName().equals(Platform.class.getName()) && ref.getName().equals("lookupClass")) { allClasses.addConsumer(type -> { ClassReader cls = agent.getClassSource().get(type.getName()); if (cls == null) { return; } MethodReader initMethod = cls.getMethod(new MethodDescriptor("<clinit>", void.class)); if (initMethod != null) { MethodDependency initDep = agent.linkMethod(initMethod.getReference()); method.addLocationListener(initDep::addLocation); initDep.use(); } }); } } }
private void reachGetSuperclass(DependencyAgent agent, MethodDependency method) { method.getVariable(0).getClassValueNode().addConsumer(type -> { String className = type.getName(); if (className.startsWith("[")) { return; } ClassReader cls = agent.getClassSource().get(className); if (cls != null && cls.getParent() != null) { method.getResult().getClassValueNode().propagate(agent.getType(cls.getParent())); } }); }
@Override public void started(DependencyAgent agent) { allClasses = agent.createNode(); allClasses.addConsumer(c -> { if (agent.getClassSource().isSuperType("java.lang.Throwable", c.getName()).orElse(false)) { MethodDependency methodDep = agent.linkMethod(new MethodReference(c.getName(), GET_MESSAGE)); methodDep.getVariable(0).propagate(c); methodDep.use(); } }); agent.linkClass("java.lang.Throwable"); }
private void reachGetInterfaces(DependencyAgent agent, MethodDependency method) { method.getVariable(0).getClassValueNode().addConsumer(type -> { String className = type.getName(); if (className.startsWith("[")) { return; } ClassReader cls = agent.getClassSource().get(className); if (cls != null) { for (String iface : cls.getInterfaces()) { method.getResult().getClassValueNode().propagate(agent.getType(iface)); } } }); }
private void reachGetAnnotations(DependencyAgent agent, DependencyNode node) { node.getClassValueNode().addConsumer(type -> { String className = type.getName(); ClassReader cls = agent.getClassSource().get(className); if (cls == null) { return; } for (AnnotationReader annotation : cls.getAnnotations().all()) { agent.linkClass(annotation.getType()); } createAnnotationClass(agent, className); }); }
@Override public void cloneArray(VariableReader receiver, VariableReader array) { DependencyNode arrayNode = getNode(array); DependencyNode receiverNode = getNode(receiver); if (arrayNode != null && receiverNode != null) { arrayNode.addConsumer(receiverNode::propagate); arrayNode.getArrayItem().connect(receiverNode.getArrayItem()); } MethodDependency cloneDep = getAnalyzer().linkMethod(CLONE_METHOD); cloneDep.addLocation(getCallLocation()); arrayNode.connect(cloneDep.getVariable(0)); cloneDep.use(); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { if (method.getReference().getClassName().equals(Platform.class.getName()) && method.getReference().getName().equals("getEnumConstants")) { allEnums.connect(method.getResult().getArrayItem()); final MethodReference ref = method.getReference(); allEnums.addConsumer(type -> { ClassReader cls = agent.getClassSource().get(type.getName()); MethodReader valuesMethod = cls.getMethod(new MethodDescriptor("values", ValueType.arrayOf(ValueType.object(cls.getName())))); if (valuesMethod != null) { MethodDependency valuesDep = agent.linkMethod(valuesMethod.getReference()); valuesDep.addLocation(new CallLocation(ref)); valuesDep.use(); } }); method.getResult().propagate(agent.getType("[Ljava/lang/Enum;")); for (String cls : agent.getReachableClasses()) { classReached(agent, cls); } } } }
@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 void handleFieldSet(DependencyAgent agent, MethodDependency method) { CallLocation location = new CallLocation(method.getReference()); DependencyNode classValueNode = agent.linkMethod(getFields) .addLocation(location) .getVariable(0).getClassValueNode(); classValueNode.addConsumer(reflectedType -> { if (reflectedType.getName().startsWith("[")) { return; } Set<String> accessibleFields = getAccessibleFields(agent, reflectedType.getName()); ClassReader cls = agent.getClassSource().get(reflectedType.getName()); for (String fieldName : accessibleFields) { FieldReader field = cls.getField(fieldName); FieldDependency fieldDep = agent.linkField(field.getReference()).addLocation(location); propagateSet(agent, field.getType(), method.getVariable(2), fieldDep.getValue(), location); linkClassIfNecessary(agent, field, location); } }); }
private void handleFieldGet(DependencyAgent agent, MethodDependency method) { CallLocation location = new CallLocation(method.getReference()); DependencyNode classValueNode = agent.linkMethod(getFields) .addLocation(location) .getVariable(0).getClassValueNode(); classValueNode.addConsumer(reflectedType -> { if (reflectedType.getName().startsWith("[")) { return; } Set<String> accessibleFields = getAccessibleFields(agent, reflectedType.getName()); ClassReader cls = agent.getClassSource().get(reflectedType.getName()); for (String fieldName : accessibleFields) { FieldReader field = cls.getField(fieldName); FieldDependency fieldDep = agent.linkField(field.getReference()) .addLocation(location); propagateGet(agent, field.getType(), fieldDep.getValue(), method.getResult(), location); linkClassIfNecessary(agent, field, location); } }); }