public MethodDescriptor getDescriptor() { if (descriptor == null) { descriptor = new MethodDescriptor(name, signature); } return descriptor; }
public MethodHolder(String name, ValueType... signature) { this(new MethodDescriptor(name, signature)); }
private MethodDescriptor getDescriptor(Method method) { ValueType[] signature = Stream.concat(Arrays.stream(method.getParameterTypes()).map(ValueType::parse), Stream.of(ValueType.parse(method.getReturnType()))) .toArray(ValueType[]::new); return new MethodDescriptor(method.getName(), signature); }
public static MethodDescriptor parseIfPossible(String text) { int parenIndex = text.indexOf('('); if (parenIndex < 1) { return null; } return new MethodDescriptor(text.substring(0, parenIndex), parseSignature(text.substring(parenIndex))); }
public SourceWriter appendMethodBody(String className, String name, ValueType... params) throws IOException { return appendMethodBody(new MethodReference(className, new MethodDescriptor(name, params))); }
public boolean hasClinit(String className) { if (isStructure(className) || className.equals(Address.class.getName())) { return false; } ClassReader cls = classSource.get(className); if (cls == null) { return false; } return cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null; }
private void installThreadMethods(ClassHolder cls) { cls.addMethod(createMethodThrowingSecurityException(new MethodDescriptor("setName", String.class, void.class))); cls.addMethod(createMethodThrowingSecurityException(new MethodDescriptor("setDaemon", boolean.class, void.class))); }
private boolean clinitNeeded(String className) { ClassReader cls = unprocessedClassSource.get(className); if (cls == null) { return true; } return cls.getMethod(new MethodDescriptor("<clinit>", void.class)) != null; }
public SourceWriter appendMethod(String name, Class<?>... params) throws IOException { return append(naming.getNameFor(new MethodDescriptor(name, params))); }
public static MethodDescriptor get(MethodHolder method) { return new MethodDescriptor(method.getName(), method.getSignature()); }
private boolean isSplittingClassInitializer(String className) { ClassReader cls = classSource.get(className); if (cls == null) { return false; } MethodReader method = cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)); return method != null && asyncMethods.contains(method.getReference()); }
@Override public void visit(InvokeDynamicInstruction insn) { ValueType[] signature = insn.getMethod().getSignature(); for (int i = 0; i < signature.length; ++i) { signature[i] = rename(signature[i]); } insn.setMethod(new MethodDescriptor(insn.getMethod().getName(), signature)); for (int i = 0; i < insn.getBootstrapArguments().size(); ++i) { insn.getBootstrapArguments().set(i, rename(insn.getBootstrapArguments().get(i))); } }
private boolean hasAsyncMethods() { boolean result = false; loop: for (String clsName : classSource.getClassNames()) { ClassReader cls = classSource.get(clsName); for (MethodReader method : cls.getMethods()) { if (!asyncMethods.contains(method.getReference()) || method.getProgram() == null) { continue; } if (hasMonitor(method)) { result = true; break loop; } } } ClassReader cls = classSource.get("java.lang.Thread"); MethodReader method = cls != null ? cls.getMethod(new MethodDescriptor("start", void.class)) : null; return result && method != null; }
@Override public void visit(InvokeInstruction insn) { String className = classNameMapper.map(insn.getMethod().getClassName()); ValueType[] signature = insn.getMethod().getSignature(); boolean changed = true; for (int i = 0; i < signature.length; ++i) { ValueType type = signature[i]; ValueType newType = rename(type); if (newType != null) { changed = true; } signature[i] = newType; } if (changed) { insn.setMethod(referenceCache.getCached(new MethodReference(className, new MethodDescriptor(insn.getMethod().getName(), signature)))); } }
@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 boolean needsInitializer(ClassReader cls) { return !context.getCharacteristics().isStaticInit(cls.getName()) && !context.getCharacteristics().isStructure(cls.getName()) && cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null; }
private static Value<MethodReference> methodToReference(ReflectMethod method) { int signatureSize = method.getParameterCount() + 1; Value<ValueType[]> signature = emit(() -> new ValueType[signatureSize]); for (int i = 0; i < method.getParameterCount(); ++i) { Value<ValueType> paramType = classToValueType(method.getParameterType(i)); int index = i; emit(() -> signature.get()[index] = paramType.get()); } Value<ValueType> returnType = classToValueType(method.getReturnType()); emit(() -> signature.get()[signatureSize - 1] = returnType.get()); String className = method.getDeclaringClass().getName(); String name = method.getName(); return emit(() -> new MethodReference(className, new MethodDescriptor(name, signature.get()))); }
private void transformCompareMethod(ClassHolder cls, ValueType type, NumericOperandType insnType) { MethodHolder method = cls.getMethod(new MethodDescriptor("compare", type, type, ValueType.INTEGER)); Program program = new Program(); program.createVariable(); Variable firstArg = program.createVariable(); Variable secondArg = program.createVariable(); Variable result = program.createVariable(); BasicBlock block = program.createBasicBlock(); BinaryInstruction insn = new BinaryInstruction(BinaryOperation.COMPARE, insnType); insn.setFirstOperand(firstArg); insn.setSecondOperand(secondArg); insn.setReceiver(result); block.add(insn); ExitInstruction exit = new ExitInstruction(); exit.setValueToReturn(result); block.add(exit); method.setProgram(program); method.getModifiers().remove(ElementModifier.NATIVE); } }
private void generateStaticInitializerCalls(GenerationContext context, CodeWriter writer, ListableClassReaderSource classes) { MethodDescriptor clinitDescriptor = new MethodDescriptor("<clinit>", ValueType.VOID); for (String className : classes.getClassNames()) { ClassReader cls = classes.get(className); if (!context.getCharacteristics().isStaticInit(cls.getName()) && !context.getCharacteristics().isStructure(cls.getName())) { continue; } if (cls.getMethod(clinitDescriptor) == null) { continue; } String clinitName = context.getNames().forMethod(new MethodReference(className, clinitDescriptor)); writer.println(clinitName + "();"); } }
private void generatePrepareNewInstance(GeneratorContext context, SourceWriter writer) throws IOException { writer.append("var c").ws().append("=").ws().append("'$$constructor$$';").softNewLine(); for (String clsName : context.getClassSource().getClassNames()) { ClassReader cls = context.getClassSource().get(clsName); MethodReader method = cls.getMethod(new MethodDescriptor("<init>", void.class)); if (method != null) { writer.appendClass(clsName).append("[c]").ws().append("=").ws() .appendMethodBody(method.getReference()).append(";").softNewLine(); } } }