use of org.graalvm.compiler.nodes.IndirectCallTargetNode in project graal by oracle.
the class SubstrateGraphKit method createIndirectCall.
public InvokeNode createIndirectCall(ValueNode targetAddress, ResolvedJavaMethod targetMethod, List<ValueNode> arguments, Signature signature, CallingConvention.Type callType) {
assert arguments.size() == signature.getParameterCount(false);
frameState.clearStack();
Stamp stamp = returnStamp(signature);
int bci = bci();
CallTargetNode callTarget = getGraph().add(new IndirectCallTargetNode(targetAddress, arguments.toArray(new ValueNode[arguments.size()]), StampPair.createSingle(stamp), signature.toParameterTypes(null), targetMethod, callType, InvokeKind.Static));
InvokeNode invoke = append(new InvokeNode(callTarget, bci));
// Insert framestate.
frameState.pushReturn(signature.getReturnKind(), invoke);
FrameState stateAfter = frameState.create(bci, invoke);
invoke.setStateAfter(stateAfter);
return invoke;
}
use of org.graalvm.compiler.nodes.IndirectCallTargetNode in project graal by oracle.
the class CInterfaceInvocationPlugin method replaceFunctionPointerInvoke.
private boolean replaceFunctionPointerInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, CallingConvention.Type callType) {
if (!functionPointerType.isAssignableFrom(method.getDeclaringClass())) {
throw UserError.abort(new CInterfaceError("function pointer invocation method " + method.format("%H.%n(%p)") + " must be in a type that extends " + CFunctionPointer.class.getSimpleName(), method).getMessage());
}
assert b.getInvokeKind() == InvokeKind.Interface;
JavaType[] parameterTypes = method.getSignature().toParameterTypes(null);
if (callType == SubstrateCallingConventionType.NativeCall) {
Predicate<JavaType> isValid = t -> t.getJavaKind().isPrimitive() || wordTypes.isWord(t);
UserError.guarantee(Stream.of(parameterTypes).allMatch(isValid) && isValid.test(method.getSignature().getReturnType(null)), "C function pointer invocation method must have only primitive types or word types for its parameters and return value: " + method.format("%H.%n(%p)"));
/*
* We currently do not support automatic conversions for @CEnum because it entails
* introducing additional invokes without real BCIs in a BytecodeParser context, which
* does not work too well.
*/
}
// We "discard" the receiver from the signature by pretending we are a static method
assert args.length >= 1;
ValueNode methodAddress = args[0];
ValueNode[] argsWithoutReceiver = Arrays.copyOfRange(args, 1, args.length);
assert argsWithoutReceiver.length == parameterTypes.length;
Stamp returnStamp;
if (wordTypes.isWord(b.getInvokeReturnType())) {
returnStamp = wordTypes.getWordStamp((ResolvedJavaType) b.getInvokeReturnType());
} else {
returnStamp = b.getInvokeReturnStamp(null).getTrustedStamp();
}
CallTargetNode indirectCallTargetNode = b.add(new IndirectCallTargetNode(methodAddress, argsWithoutReceiver, StampPair.createSingle(returnStamp), parameterTypes, method, callType, InvokeKind.Static));
if (callType == SubstrateCallingConventionType.JavaCall) {
b.handleReplacedInvoke(indirectCallTargetNode, b.getInvokeReturnType().getJavaKind());
} else if (callType == SubstrateCallingConventionType.NativeCall) {
// Native code cannot throw exceptions, omit exception edge
InvokeNode invokeNode = new InvokeNode(indirectCallTargetNode, b.bci());
if (pushKind(method) != JavaKind.Void) {
b.addPush(pushKind(method), invokeNode);
} else {
b.add(invokeNode);
}
} else {
throw shouldNotReachHere("Unsupported type of call: " + callType);
}
return true;
}
use of org.graalvm.compiler.nodes.IndirectCallTargetNode in project graal by oracle.
the class NodeLIRBuilder method emitInvoke.
@Override
public void emitInvoke(Invoke x) {
LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess()), callTarget.signature(), gen);
frameMapBuilder.callsMethod(invokeCc);
Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
LabelRef exceptionEdge = null;
if (x instanceof InvokeWithExceptionNode) {
exceptionEdge = getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge());
}
LIRFrameState callState = stateWithExceptionEdge(x, exceptionEdge);
Value result = invokeCc.getReturn();
if (callTarget instanceof DirectCallTargetNode) {
emitDirectCall((DirectCallTargetNode) callTarget, result, parameters, AllocatableValue.NONE, callState);
} else if (callTarget instanceof IndirectCallTargetNode) {
emitIndirectCall((IndirectCallTargetNode) callTarget, result, parameters, AllocatableValue.NONE, callState);
} else {
throw GraalError.shouldNotReachHere();
}
if (isLegal(result)) {
setResult(x.asNode(), gen.emitMove(result));
}
if (x instanceof InvokeWithExceptionNode) {
gen.emitJump(getLIRBlock(((InvokeWithExceptionNode) x).next()));
}
}
Aggregations