@Override public boolean isApplicable(MethodReference methodReference) { if (!methodReference.getClassName().equals("java.lang.Object")) { return false; } switch (methodReference.getName()) { case "wrap": return true; default: return false; } }
private MethodReference getAsyncReference(MethodReference methodRef) { ValueType[] signature = new ValueType[methodRef.parameterCount() + 2]; for (int i = 0; i < methodRef.parameterCount(); ++i) { signature[i] = methodRef.getDescriptor().parameterType(i); } signature[methodRef.parameterCount()] = ValueType.parse(AsyncCallback.class); signature[methodRef.parameterCount() + 1] = ValueType.VOID; return new MethodReference(methodRef.getClassName(), methodRef.getName(), signature); }
private Method getJavaMethod(ClassLoader classLoader, MethodReference ref) throws ReflectiveOperationException { Class<?> cls = Class.forName(ref.getClassName(), true, classLoader); Class<?>[] parameterTypes = new Class<?>[ref.parameterCount()]; for (int i = 0; i < parameterTypes.length; ++i) { parameterTypes[i] = getJavaType(classLoader, ref.parameterType(i)); } return cls.getDeclaredMethod(ref.getName(), parameterTypes); }
@Override public boolean isApplicable(MethodReference methodReference) { return methodReference.getClassName().equals("java.lang.Class") && isApplicableToMethod(methodReference.getDescriptor()); }
private MethodReference buildMethodReference(String suffix) { if (model.getClassParameterIndex() < 0) { return new MethodReference(model.getMethod().getClassName() + "$PROXY$" + suffix, model.getMethod().getDescriptor()); } int i; ValueType[] signature = new ValueType[model.getMetaParameterCount() + 1]; for (i = 0; i < signature.length - 1; ++i) { signature[i] = model.getMetaParameterType(i); } signature[i] = model.getMethod().getReturnType(); return new MethodReference(model.getMethod().getClassName() + "$PROXY$" + suffix, model.getMethod().getName(), signature); }
public MethodReference getCached(String className, MethodDescriptor descriptor) { return referenceCache .computeIfAbsent(className, key -> new HashMap<>()) .computeIfAbsent(descriptor, key -> new MethodReference(className, descriptor)); }
@Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { switch (methodRef.getName()) { case "createMetadata": generateCreateMetadata(context, writer); break; } }
private Method asJvmMethod(MethodReference method) { Class<?> cls; try { cls = Class.forName(method.getClassName(), false, classLoader); } catch (ClassNotFoundException e) { throw new RuntimeException("Can't find class " + method.getClassName()); } Class<?>[] jvmParameters = new Class[method.parameterCount()]; for (int i = 0; i < method.parameterCount(); ++i) { jvmParameters[i] = asJvmClass(method.parameterType(i)); } Class<?> jvmReturnType = asJvmClass(method.getReturnType()); for (Method jvmMethod : cls.getDeclaredMethods()) { if (Arrays.equals(jvmMethod.getParameterTypes(), jvmParameters) && jvmReturnType.equals(jvmMethod.getReturnType())) { return jvmMethod; } } throw new RuntimeException("Method not found: " + method); }
private void renderInitializer(String className, MethodNode method) throws IOException { MethodReference ref = method.getReference(); debugEmitter.emitMethod(ref.getDescriptor()); renderFunctionDeclaration(className, naming.getNameForInit(ref)); writer.append("("); for (int i = 0; i < ref.parameterCount(); ++i) { if (i > 0) { writer.append(",").ws(); } writer.append(variableNameForInitializer(i)); } writer.append(")").ws().append("{").softNewLine().indent(); String instanceName = variableNameForInitializer(ref.parameterCount()); writer.append("var " + instanceName).ws().append("=").ws().append("new ").appendClass( ref.getClassName()).append("();").softNewLine(); writer.appendMethodBody(ref).append("(" + instanceName); for (int i = 0; i < ref.parameterCount(); ++i) { writer.append(",").ws(); writer.append(variableNameForInitializer(i)); } writer.append(");").softNewLine(); writer.append("return " + instanceName + ";").softNewLine(); writer.outdent().append("}"); if (classScoped) { writer.append(";"); } writer.newLine(); debugEmitter.emitMethod(null); }
@Override public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments, InvocationType type) { if (instance == null) { invokeSpecial(receiver, null, method, arguments); } else { switch (type) { case SPECIAL: invokeSpecial(receiver, instance, method, arguments); break; case VIRTUAL: invokeVirtual(receiver, instance, method, arguments); break; } if (method.getName().equals("getClass") && method.parameterCount() == 0 && method.getReturnType().isObject(Class.class) && receiver != null) { getNode(instance).connect(getNode(receiver).getClassValueNode()); } } }
@Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { function(context, writer, "Math." + methodRef.getName(), methodRef.parameterCount()); }
@Override public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) { InvocationExpr expr = new InvocationExpr(); MethodReference method = new MethodReference(WasmRuntime.class.getName(), invocation.getMethod().getDescriptor()); expr.setMethod(method); expr.setType(InvocationType.SPECIAL); expr.getArguments().addAll(invocation.getArguments()); return manager.generate(expr); } }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodReference ref = method.getReference(); MethodReference asyncRef = getAsyncReference(ref); MethodDependency asyncMethod = agent.linkMethod(asyncRef); method.addLocationListener(asyncMethod::addLocation); int paramCount = ref.parameterCount(); for (int i = 0; i <= paramCount; ++i) { method.getVariable(i).connect(asyncMethod.getVariable(i)); } asyncMethod.getVariable(paramCount + 1).propagate(agent.getType(AsyncCallbackWrapper.class.getName())); MethodDependency completeMethod = agent.linkMethod( new MethodReference(AsyncCallbackWrapper.class, "complete", Object.class, void.class)); if (method.getResult() != null) { completeMethod.getVariable(1).connect(method.getResult(), type -> agent.getClassHierarchy() .isSuperType(ref.getReturnType(), ValueType.object(type.getName()), false)); } completeMethod.use(); MethodDependency errorMethod = agent.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "error", Throwable.class, void.class)); errorMethod.getVariable(1).connect(method.getThrown()); errorMethod.use(); agent.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "create", AsyncCallback.class, AsyncCallbackWrapper.class)).use(); asyncMethod.use(); }
private void emitVirtualDeclaration(MethodReference ref) throws IOException { String methodName = naming.getNameFor(ref.getDescriptor()); writer.append("\"").append(methodName).append("\""); writer.append(",").ws().append("function("); List<String> args = new ArrayList<>(); for (int i = 1; i <= ref.parameterCount(); ++i) { args.add(variableNameForInitializer(i)); } for (int i = 0; i < args.size(); ++i) { if (i > 0) { writer.append(",").ws(); } writer.append(args.get(i)); } writer.append(")").ws().append("{").ws(); if (ref.getDescriptor().getResultType() != ValueType.VOID) { writer.append("return "); } writer.appendMethodBody(ref).append("("); writer.append("this"); for (String arg : args) { writer.append(",").ws().append(arg); } writer.append(");").ws().append("}"); }
public void generateMethodSignature(CodeWriter writer, MethodReference methodRef, boolean isStatic, boolean withNames) { writer.print("static "); writer.printType(methodRef.getReturnType()).print(" ").print(names.forMethod(methodRef)).print("("); generateMethodParameters(writer, methodRef.getDescriptor(), isStatic, withNames); writer.print(")"); }
@Override @JsonValue public String toString() { if (reprCache == null) { reprCache = className + "." + getDescriptor().toString(); } return reprCache; }
public ValueType getMetaParameterType(int index) { if (!isStatic) { if (index == 0) { return ValueType.object(method.getClassName()); } else { --index; } } return method.parameterType(index); }
private static ValueType[] getStaticSignature(MethodReference method) { ValueType[] signature = method.getSignature(); ValueType[] staticSignature = new ValueType[signature.length + 1]; for (int i = 0; i < signature.length; ++i) { staticSignature[i + 1] = signature[i]; } staticSignature[0] = ValueType.object(method.getClassName()); return staticSignature; }
private void applyParametersToWriteStats(ReadWriteStatsBuilder stats, MethodReference method) { for (int i = 0; i <= method.parameterCount(); ++i) { stats.writes[i]++; } }