public MethodDescriptor getDescriptor() { if (descriptor == null) { descriptor = new MethodDescriptor(name, signature); } return descriptor; }
private int indexOfMethod(ClassReader cls, MethodReader method) { int index = 0; for (MethodReader m : cls.getMethods()) { if (m.getDescriptor().equals(method.getDescriptor())) { return index; } ++index; } return -1; }
private boolean isProperSetIndexer(MethodDescriptor desc) { return desc.parameterCount() == 2 && typeHelper.isSupportedType(desc.parameterType(0)) && typeHelper.isSupportedType(desc.parameterType(0)) && desc.getResultType() == ValueType.VOID; }
public MethodReference(String className, MethodDescriptor descriptor) { this.className = className; this.descriptor = descriptor; this.name = descriptor.getName(); this.signature = descriptor.getSignature(); }
private static boolean sameParams(MethodDescriptor a, MethodDescriptor b) { if (a.parameterCount() != b.parameterCount()) { return false; } for (int i = 0; i < a.parameterCount(); ++i) { if (!a.parameterType(i).equals(b.parameterType(i))) { return false; } } return true; } }
private boolean isApplicableToMethod(MethodDescriptor method) { return method.getName().equals("getClass") && method.parameterCount() == 1; }
CallLocation callLocation = new CallLocation(methodRef); ValueType[] exportedMethodSignature = Arrays.stream(method.getSignature()) .map(type -> ValueType.object(JSObject.class.getName())) .toArray(ValueType[]::new); MethodDescriptor exportedMethodDesc = new MethodDescriptor(method.getName() + "$exported$" + index++, exportedMethodSignature); MethodHolder exportedMethod = new MethodHolder(exportedMethodDesc); program, marshallInstructions); Variable[] variablesToPass = new Variable[method.parameterCount()]; for (int i = 0; i < method.parameterCount(); ++i) { variablesToPass[i] = program.createVariable(); for (int i = 0; i < method.parameterCount(); ++i) { variablesToPass[i] = marshaller.unwrapReturnValue(callLocation, variablesToPass[i], method.parameterType(i)); if (method.getResultType() != ValueType.VOID) { invocation.setReceiver(program.createVariable()); exit.setValueToReturn(marshaller.wrapArgument(callLocation, invocation.getReceiver(), method.getResultType(), false)); basicBlock.addAll(marshallInstructions); marshallInstructions.clear();
public MethodDescriptor getCached(MethodDescriptor descriptor) { MethodDescriptor result = descriptorCache.get(descriptor); if (result == null) { result = descriptor; ValueType[] signature = descriptor.getSignature(); boolean signatureChanged = false; for (int i = 0; i < signature.length; ++i) { ValueType type = signature[i]; if (type == null) { continue; } ValueType cachedType = getCached(type); if (type != cachedType) { signatureChanged = true; signature[i] = cachedType; } } if (signatureChanged) { result = new MethodDescriptor(descriptor.getName(), signature); } descriptorCache.put(result, result); } return result; }
@Override public ValueEmitter substitute(DynamicCallSite callSite, ProgramEmitter callerPe) { ValueType[] invokedType = callSite.getCalledMethod().getSignature(); ValueType[] samMethodType = callSite.getBootstrapArguments().get(0).getMethodType(); MethodHandle implMethod = callSite.getBootstrapArguments().get(1).getMethodHandle(); ValueType[] instantiatedMethodType = callSite.getBootstrapArguments().get(2).getMethodType(); String samName = ((ValueType.Object) callSite.getCalledMethod().getResultType()).getClassName(); ClassHierarchy hierarchy = callSite.getAgent().getClassHierarchy(); ClassReader samClass = hierarchy.getClassSource().get(samName); int id = 0; for (MethodReader callerMethod : callerClass.getMethods()) { if (callerMethod.getDescriptor().equals(callSite.getCaller().getDescriptor())) { break; int capturedVarCount = callSite.getCalledMethod().parameterCount(); MethodHolder ctor = createConstructor(hierarchy, implementor, Arrays.copyOfRange(invokedType, 0, capturedVarCount), callerPe.getCurrentLocation()); createBridge(hierarchy, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType, samMethodType, callerPe.getCurrentLocation()); MethodHolder worker = new MethodHolder(callSite.getCalledMethod().getName(), instantiatedMethodType); worker.setLevel(AccessLevel.PUBLIC); ProgramEmitter pe = ProgramEmitter.create(worker, callSite.getAgent().getClassHierarchy()); for (int i = 0; i < bridgeCount; ++i) { ValueType[] bridgeType = callSite.getBootstrapArguments().get(bootstrapArgIndex++).getMethodType(); createBridge(hierarchy, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType, bridgeType, callerPe.getCurrentLocation());
@Override public Object invoke(Object proxy, Method method, Object[] args) { if (method.getName().equals("annotationType")) { return annotationType; } else { ClassReader cls = hierarchy.getClassSource().get(reader.getType()); return cache.computeIfAbsent(method.getName(), name -> { MethodDescriptor desc = new MethodDescriptor(name, ValueType.parse(method.getReturnType())); MethodReader methodReader = cls.getMethod(desc); AnnotationValue value = reader.getValue(name); if (value == null) { value = methodReader.getAnnotationDefault(); } try { return convertValue(value, desc.getResultType()); } catch (Exception e) { throw new RuntimeException(e); } }); } }
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))); }
@Override public ValueType parameterType(int index) { return descriptor.parameterType(index); }
@Override protected CharSequence callMethod(String ident, String fqn, String method, String params) { MethodDescriptor desc = MethodDescriptor.parse(method + params + "V"); MethodReader reader = JavaScriptBodyDependency.findMethod(classSource, fqn, desc); if (reader == null) { sb.append("$this"); for (int i = 0; i < desc.parameterCount(); ++i) { if (ident != null || i > 0) { sb.append(", "); for (int i = 0; i < desc.parameterCount(); ++i) { if (i > 0) { sb.append(", "); ValueType paramType = simplifyParamType(desc.parameterType(i)); sb.append(naming.getFullNameFor(JavaScriptConvGenerator.fromJsMethod)).append("(p").append(i) .append(", ")
@Override public ValueType getResultType() { return descriptor.getResultType(); }
private void writeFunctor(ClassReader cls, FieldReference functorField) throws IOException { AnnotationReader implAnnot = cls.getAnnotations().get(FunctorImpl.class.getName()); MethodDescriptor functorMethod = MethodDescriptor.parse(implAnnot.getValue("value").getString()); String alias = cls.getMethod(functorMethod).getAnnotations() .get(JSMethodToExpose.class.getName()).getValue("name").getString(); if (alias == null) { return; } writer.append("c.jso$functor$").append(alias).ws().append("=").ws().append("function()").ws().append("{") .indent().softNewLine(); writer.append("if").ws().append("(!this.").appendField(functorField).append(")").ws().append("{") .indent().softNewLine(); writer.append("var self").ws().append('=').ws().append("this;").softNewLine(); writer.append("this.").appendField(functorField).ws().append('=').ws().append("function("); appendArguments(functorMethod.parameterCount()); writer.append(")").ws().append('{').indent().softNewLine(); writer.append("return self.").appendMethod(functorMethod).append('('); appendArguments(functorMethod.parameterCount()); writer.append(");").softNewLine(); writer.outdent().append("};").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("return this.").appendField(functorField).append(';').softNewLine(); writer.outdent().append("};").softNewLine(); }
public MethodDescriptor parseDescriptorCached(String value) { MethodDescriptor result = descriptorParseCache.get(value); if (result == null) { result = getCached(MethodDescriptor.parse(value)); descriptorParseCache.put(value, result); } return result; }
@Override public int parameterCount() { return descriptor.parameterCount(); }
private boolean isApplicableToMethod(MethodDescriptor methodDescriptor) { switch (methodDescriptor.getName()) { case "getPlatformObject": case "asJavaClass": case "createQueue": return true; default: return false; } }
ValueType[] types = new ValueType[method.getDescriptor().parameterCount() + 2]; types[0] = ValueType.object("java.lang.Object"); System.arraycopy(method.getDescriptor().getSignature(), 0, types, 1, method.getDescriptor().parameterCount() + 1); accessInsn.setMethod(new MethodReference(ResourceAccessor.class.getName(), method.getName(), types)); Variable[] accessArgs = new Variable[insn.getArguments().size() + 1];
@Override public ValueType[] getSignature() { return descriptor.getSignature(); }