use of org.graalvm.compiler.nodes.InvokeNode in project graal by oracle.
the class CInterfaceEnumTool method replaceEnumValueInvoke.
boolean replaceEnumValueInvoke(BytecodeParser p, EnumInfo enumInfo, ResolvedJavaMethod method, ValueNode[] args) {
ResolvedJavaMethod valueMethod = getValueMethodForKind(method.getSignature().getReturnKind());
JavaType originalReturnType = method.getSignature().getReturnType(null);
assert args.length == 1;
InvokeNode invoke = invokeEnumValue(p, CallTargetFactory.from(p), p.getFrameStateBuilder(), p.bci(), enumInfo, valueMethod, args[0]);
ValueNode adapted = CInterfaceInvocationPlugin.adaptPrimitiveType(p.getGraph(), invoke, invoke.stamp(NodeView.DEFAULT).getStackKind(), originalReturnType.getJavaKind(), false);
Stamp originalStamp = p.getInvokeReturnStamp(null).getTrustedStamp();
adapted = CInterfaceInvocationPlugin.adaptPrimitiveType(p.getGraph(), adapted, originalReturnType.getJavaKind(), originalStamp.getStackKind(), false);
p.push(CInterfaceInvocationPlugin.pushKind(method), adapted);
return true;
}
use of org.graalvm.compiler.nodes.InvokeNode in project graal by oracle.
the class CInterfaceEnumTool method invokeEnumLookup.
private InvokeNode invokeEnumLookup(GraphBuilderTool b, CallTargetFactory callTargetFactory, FrameStateBuilder frameState, int bci, EnumInfo enumInfo, JavaKind parameterKind, ValueNode arg) {
ValueNode[] args = new ValueNode[2];
args[0] = ConstantNode.forConstant(snippetReflection.forObject(enumInfo.getRuntimeData()), b.getMetaAccess(), b.getGraph());
assert !Modifier.isStatic(convertCToJavaMethod.getModifiers()) && convertCToJavaMethod.getSignature().getParameterCount(false) == 1;
JavaKind expectedKind = convertCToJavaMethod.getSignature().getParameterType(0, null).getJavaKind();
args[1] = CInterfaceInvocationPlugin.adaptPrimitiveType(b.getGraph(), arg, parameterKind, expectedKind, false);
ResolvedJavaType convertReturnType = (ResolvedJavaType) convertCToJavaMethod.getSignature().getReturnType(null);
StampPair returnStamp = StampFactory.forDeclaredType(null, convertReturnType, false);
MethodCallTargetNode callTargetNode = b.append(callTargetFactory.createMethodCallTarget(InvokeKind.Virtual, convertCToJavaMethod, args, returnStamp, bci));
Stamp invokeStamp = StampFactory.object(TypeReference.createWithoutAssumptions(convertReturnType));
InvokeNode invoke = b.append(new InvokeNode(callTargetNode, bci, invokeStamp));
frameState.push(convertReturnType.getJavaKind(), invoke);
FrameState stateWithInvoke = frameState.create(bci, invoke);
frameState.pop(convertReturnType.getJavaKind());
invoke.setStateAfter(stateWithInvoke);
return invoke;
}
use of org.graalvm.compiler.nodes.InvokeNode in project graal by oracle.
the class CInterfaceEnumTool method replaceEnumLookupInvoke.
boolean replaceEnumLookupInvoke(BytecodeParser p, EnumInfo enumInfo, ResolvedJavaMethod method, ValueNode[] args) {
assert Modifier.isStatic(method.getModifiers()) && method.getSignature().getParameterCount(false) == 1;
assert args.length == 1;
JavaKind methodParameterKind = method.getSignature().getParameterType(0, null).getJavaKind();
InvokeNode invokeNode = invokeEnumLookup(p, CallTargetFactory.from(p), p.getFrameStateBuilder(), p.bci(), enumInfo, methodParameterKind, args[0]);
Stamp returnStamp = p.getInvokeReturnStamp(null).getTrustedStamp();
assert returnStamp.getStackKind() == JavaKind.Object && invokeNode.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object;
assert StampTool.typeOrNull(invokeNode.stamp(NodeView.DEFAULT)).isAssignableFrom(StampTool.typeOrNull(returnStamp));
ValueNode adapted = p.getGraph().unique(new PiNode(invokeNode, returnStamp));
p.push(CInterfaceInvocationPlugin.pushKind(method), adapted);
return true;
}
use of org.graalvm.compiler.nodes.InvokeNode 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.InvokeNode in project graal by oracle.
the class GraphKit method createInvoke.
/**
* Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
* arguments.
*/
@SuppressWarnings("try")
public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), method))) {
assert method.isStatic() == (invokeKind == InvokeKind.Static);
Signature signature = method.getSignature();
JavaType returnType = signature.getReturnType(null);
assert checkArgs(method, args);
StampPair returnStamp = graphBuilderPlugins.getOverridingStamp(this, returnType, false);
if (returnStamp == null) {
returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
}
MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, bci));
InvokeNode invoke = append(new InvokeNode(callTarget, bci));
if (frameStateBuilder != null) {
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.push(invoke.getStackKind(), invoke);
}
invoke.setStateAfter(frameStateBuilder.create(bci, invoke));
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.pop(invoke.getStackKind());
}
}
return invoke;
}
}
Aggregations