package com.oracle.svm.hosted.code;
import java.util.Arrays;
import java.util.List;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.nativeimage.c.function.CFunction;
import com.oracle.graal.pointsto.meta.HostedProviders;
import com.oracle.svm.core.graal.code.CGlobalDataInfo;
import com.oracle.svm.core.graal.nodes.CGlobalDataLoadAddressNode;
import com.oracle.svm.core.thread.VMThreads.StatusSupport;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.c.NativeLibraries;
import com.oracle.svm.hosted.phases.HostedGraphKit;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Signature;
public final class CFunctionCallStubMethod extends CCallStubMethod {
private final CGlobalDataInfo linkage;
CFunctionCallStubMethod(ResolvedJavaMethod original, CGlobalDataInfo linkage, int newThreadStatus) {
super(original, newThreadStatus);
this.linkage = linkage;
}
@Override
protected String getCorrespondingAnnotationName() {
return getAnnotationClass().getSimpleName();
}
private Class<?> getAnnotationClass() {
if (original.getAnnotation(CFunction.class) != null) {
return CFunction.class;
} else {
throw VMError.shouldNotReachHere("Method is not annotated with @" + CFunction.class.getSimpleName());
}
}
@Override
public boolean allowRuntimeCompilation() {
boolean needsTransition = StatusSupport.isValidStatus(newThreadStatus);
return !needsTransition;
}
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
assert purpose != Purpose.PREPARE_RUNTIME_COMPILATION || allowRuntimeCompilation();
return super.buildGraph(debug, method, providers, purpose);
}
@Override
protected ValueNode createTargetAddressNode(HostedGraphKit kit, HostedProviders providers, List<ValueNode> arguments) {
return kit.unique(new CGlobalDataLoadAddressNode(linkage));
}
@Override
protected JavaType[] getParameterTypesForLoad(ResolvedJavaMethod method) {
return method.toParameterTypes();
}
@Override
protected Signature adaptSignatureAndConvertArguments(HostedProviders providers, NativeLibraries nativeLibraries,
HostedGraphKit kit, ResolvedJavaMethod method, JavaType returnType, JavaType[] paramTypes, List<ValueNode> arguments) {
JavaType[] adaptedParamTypes = paramTypes;
if (method.hasReceiver()) {
arguments.remove(0);
adaptedParamTypes = Arrays.copyOfRange(adaptedParamTypes, 1, adaptedParamTypes.length);
}
return super.adaptSignatureAndConvertArguments(providers, nativeLibraries, kit, method, returnType, adaptedParamTypes, arguments);
}
}