use of com.oracle.svm.hosted.c.info.EnumInfo in project graal by oracle.
the class SizeAndSignednessVerifier method visitEnumValueInfo.
@Override
protected void visitEnumValueInfo(EnumValueInfo valueInfo) {
ResolvedJavaMethod method = (ResolvedJavaMethod) valueInfo.getAnnotatedElement();
ResolvedJavaType returnType = (ResolvedJavaType) method.getSignature().getReturnType(method.getDeclaringClass());
EnumInfo enumInfo = (EnumInfo) valueInfo.getParent();
for (ElementInfo info : enumInfo.getChildren()) {
if (info instanceof EnumConstantInfo) {
EnumConstantInfo constantInfo = (EnumConstantInfo) info;
checkSizeAndSignedness(constantInfo, returnType, method, true);
}
}
}
use of com.oracle.svm.hosted.c.info.EnumInfo in project graal by oracle.
the class CEntryPointCallStubMethod method buildGraph.
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess();
NativeLibraries nativeLibraries = CEntryPointCallStubSupport.singleton().getNativeLibraries();
HostedGraphKit kit = new HostedGraphKit(debug, providers, method);
StructuredGraph graph = kit.getGraph();
JavaType[] parameterTypes = method.toParameterTypes();
JavaType[] parameterLoadTypes = Arrays.copyOf(parameterTypes, parameterTypes.length);
EnumInfo[] parameterEnumInfos;
parameterEnumInfos = adaptParameterTypes(providers, nativeLibraries, kit, parameterTypes, parameterLoadTypes, purpose);
ValueNode[] args = kit.loadArguments(parameterLoadTypes).toArray(new ValueNode[0]);
InvokeNode prologueInvoke = generatePrologue(providers, kit, parameterLoadTypes, args);
adaptArgumentValues(providers, kit, parameterTypes, parameterEnumInfos, args);
ResolvedJavaMethod unwrappedTargetMethod = targetMethod;
while (unwrappedTargetMethod instanceof WrappedJavaMethod) {
unwrappedTargetMethod = ((WrappedJavaMethod) unwrappedTargetMethod).getWrapped();
}
ResolvedJavaMethod universeTargetMethod = lookupMethodInUniverse(metaAccess, unwrappedTargetMethod);
int invokeBci = kit.bci();
int exceptionEdgeBci = kit.bci();
// Also support non-static test methods (they are not allowed to use the receiver)
InvokeKind invokeKind = universeTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special;
ValueNode[] invokeArgs = args;
if (invokeKind != InvokeKind.Static) {
invokeArgs = new ValueNode[args.length + 1];
invokeArgs[0] = kit.createObject(null);
System.arraycopy(args, 0, invokeArgs, 1, args.length);
}
InvokeWithExceptionNode invoke = kit.startInvokeWithException(universeTargetMethod, invokeKind, kit.getFrameState(), invokeBci, exceptionEdgeBci, invokeArgs);
kit.exceptionPart();
ExceptionObjectNode exception = kit.exceptionObject();
generateExceptionHandler(providers, kit, exception, invoke.getStackKind());
kit.endInvokeWithException();
ValueNode returnValue = adaptReturnValue(method, providers, purpose, metaAccess, nativeLibraries, kit, invoke);
InvokeNode epilogueInvoke = generateEpilogue(providers, kit);
kit.createReturn(returnValue, returnValue.getStackKind());
inlinePrologueAndEpilogue(kit, prologueInvoke, epilogueInvoke, invoke.getStackKind());
assert graph.verify();
return graph;
}
use of com.oracle.svm.hosted.c.info.EnumInfo in project graal by oracle.
the class CEntryPointCallStubMethod method adaptParameterTypes.
private EnumInfo[] adaptParameterTypes(HostedProviders providers, NativeLibraries nativeLibraries, HostedGraphKit kit, JavaType[] parameterTypes, JavaType[] parameterLoadTypes, Purpose purpose) {
EnumInfo[] parameterEnumInfos = null;
for (int i = 0; i < parameterTypes.length; i++) {
if (!parameterTypes[i].getJavaKind().isPrimitive() && !providers.getWordTypes().isWord(parameterTypes[i])) {
ElementInfo typeInfo = nativeLibraries.findElementInfo(parameterTypes[i]);
if (typeInfo instanceof EnumInfo) {
UserError.guarantee(typeInfo.getChildren().stream().anyMatch(EnumLookupInfo.class::isInstance), "Enum class " + parameterTypes[i].toJavaName() + " needs a method that is annotated with @" + CEnumLookup.class + " because it is used as a parameter of an entry point method: " + targetMethod.format("%H.%n(%p)"));
if (parameterEnumInfos == null) {
parameterEnumInfos = new EnumInfo[parameterTypes.length];
}
parameterEnumInfos[i] = (EnumInfo) typeInfo;
parameterLoadTypes[i] = providers.getMetaAccess().lookupJavaType(cEnumParameterKind.toJavaClass());
final int parameterIndex = i;
FrameState initialState = kit.getGraph().start().stateAfter();
Iterator<ValueNode> matchingNodes = initialState.values().filter(node -> ((ParameterNode) node).index() == parameterIndex).iterator();
ValueNode parameterNode = matchingNodes.next();
assert !matchingNodes.hasNext() && parameterNode.usages().filter(n -> n != initialState).isEmpty();
parameterNode.setStamp(StampFactory.forKind(cEnumParameterKind));
} else if (purpose != Purpose.ANALYSIS) {
// for analysis test cases: abort only during compilation
throw UserError.abort("Entry point method parameter types are restricted to primitive types, word types and enumerations (@" + CEnum.class.getSimpleName() + "): " + targetMethod.format("%H.%n(%p)"));
}
}
}
return parameterEnumInfos;
}
use of com.oracle.svm.hosted.c.info.EnumInfo in project graal by oracle.
the class CEntryPointCallStubMethod method adaptReturnValue.
private ValueNode adaptReturnValue(ResolvedJavaMethod method, HostedProviders providers, Purpose purpose, UniverseMetaAccess metaAccess, NativeLibraries nativeLibraries, HostedGraphKit kit, ValueNode invokeValue) {
ValueNode returnValue = invokeValue;
if (returnValue.getStackKind().isPrimitive()) {
return returnValue;
}
JavaType returnType = method.getSignature().getReturnType(null);
ElementInfo typeInfo = nativeLibraries.findElementInfo(returnType);
if (typeInfo instanceof EnumInfo) {
UserError.guarantee(typeInfo.getChildren().stream().anyMatch(EnumValueInfo.class::isInstance), "Enum class " + returnType.toJavaName() + " needs a method that is annotated with @" + CEnumValue.class + " because it is used as the return type of an entry point method: " + targetMethod.format("%H.%n(%p)"));
IsNullNode isNull = kit.unique(new IsNullNode(returnValue));
kit.startIf(isNull, BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY);
kit.thenPart();
ResolvedJavaType enumExceptionType = metaAccess.lookupJavaType(RuntimeException.class);
NewInstanceNode enumException = kit.append(new NewInstanceNode(enumExceptionType, true));
Iterator<ResolvedJavaMethod> enumExceptionCtor = Arrays.stream(enumExceptionType.getDeclaredConstructors()).filter(c -> c.getSignature().getParameterCount(false) == 1 && c.getSignature().getParameterType(0, null).equals(metaAccess.lookupJavaType(String.class))).iterator();
ConstantNode enumExceptionMessage = kit.createConstant(kit.getConstantReflection().forString("null return value cannot be converted to a C enum value"), JavaKind.Object);
kit.createJavaCallWithExceptionAndUnwind(InvokeKind.Special, enumExceptionCtor.next(), enumException, enumExceptionMessage);
assert !enumExceptionCtor.hasNext();
kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, enumException));
kit.append(new DeadEndNode());
kit.endIf();
// Always return enum values as a signed word because it should never be a problem if
// the caller expects a narrower integer type and the various checks already handle
// replacements with word types
CInterfaceEnumTool tool = new CInterfaceEnumTool(providers.getMetaAccess(), providers.getSnippetReflection());
JavaKind cEnumReturnType = providers.getWordTypes().getWordKind();
assert !cEnumReturnType.isUnsigned() : "requires correct representation of signed values";
returnValue = tool.createEnumValueInvoke(kit, (EnumInfo) typeInfo, cEnumReturnType, returnValue);
} else if (purpose != Purpose.ANALYSIS) {
// for analysis test cases: abort only during compilation
throw UserError.abort("Entry point method return types are restricted to primitive types, word types and enumerations (@" + CEnum.class.getSimpleName() + "): " + targetMethod.format("%H.%n(%p)"));
}
return returnValue;
}
use of com.oracle.svm.hosted.c.info.EnumInfo in project graal by oracle.
the class CFunctionCallStubMethod method adaptReturnValue.
private static ValueNode adaptReturnValue(ResolvedJavaMethod method, HostedProviders providers, NativeLibraries nativeLibraries, HostedGraphKit kit, ValueNode invokeValue) {
ValueNode returnValue = invokeValue;
JavaType declaredReturnType = method.getSignature().getReturnType(null);
if (isPrimitiveOrWord(providers, declaredReturnType)) {
return returnValue;
}
ElementInfo typeInfo = nativeLibraries.findElementInfo(declaredReturnType);
if (typeInfo instanceof EnumInfo) {
UserError.guarantee(typeInfo.getChildren().stream().anyMatch(EnumValueInfo.class::isInstance), "Enum class " + declaredReturnType.toJavaName() + " needs a method that is annotated with @" + CEnumLookup.class + " because it is used as the return type of a method annotated with @" + CFunction.class.getSimpleName() + ": " + method.format("%H.%n(%p)"));
// We take a word return type because checks expect word type replacements, but it is
// narrowed to cEnumKind here.
CInterfaceEnumTool tool = new CInterfaceEnumTool(providers.getMetaAccess(), providers.getSnippetReflection());
returnValue = tool.createEnumLookupInvoke(kit, (ResolvedJavaType) declaredReturnType, (EnumInfo) typeInfo, cEnumKind, returnValue);
} else {
throw UserError.abort("Return types of methods annotated with @" + CFunction.class.getSimpleName() + " are restricted to primitive types, word types and enumerations (@" + CEnum.class.getSimpleName() + "): " + method.format("%H.%n(%p)"));
}
return returnValue;
}
Aggregations