use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeCodeGenerator method createGetFactories.
private static ExecutableElement createGetFactories(ProcessorContext context, NodeData node) {
List<NodeData> factoryList = node.getNodesWithFactories();
if (node.needsFactory() && node.isGenerateFactory()) {
factoryList.add(node);
}
if (factoryList.isEmpty()) {
return null;
}
List<TypeMirror> nodeTypesList = new ArrayList<>();
TypeMirror prev = null;
boolean allSame = true;
for (NodeData child : factoryList) {
nodeTypesList.add(child.getNodeType());
if (prev != null && !ElementUtils.typeEquals(child.getNodeType(), prev)) {
allSame = false;
}
prev = child.getNodeType();
}
TypeMirror commonNodeSuperType = ElementUtils.getCommonSuperType(context, nodeTypesList);
Types types = context.getEnvironment().getTypeUtils();
TypeMirror factoryType = context.getType(NodeFactory.class);
TypeMirror baseType;
if (allSame) {
baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), commonNodeSuperType);
} else {
baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null));
}
TypeMirror listType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getType(List.class)), baseType);
CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories");
CodeTreeBuilder builder = method.createBuilder();
builder.startReturn();
if (factoryList.size() > 1) {
builder.startStaticCall(context.getType(Arrays.class), "asList");
} else {
builder.startStaticCall(context.getType(Collections.class), "singletonList");
}
for (NodeData child : factoryList) {
builder.startGroup();
NodeData childNode = child;
List<NodeData> factories = new ArrayList<>();
while (childNode.getDeclaringNode() != null) {
factories.add(childNode);
childNode = childNode.getDeclaringNode();
}
Collections.reverse(factories);
for (NodeData nodeData : factories) {
builder.string(getAccessorClassName(nodeData)).string(".");
}
builder.string("getInstance()");
builder.end();
}
builder.end();
builder.end();
return method;
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method initializeFallbackReachability.
private static void initializeFallbackReachability(NodeData node) {
List<SpecializationData> specializations = node.getSpecializations();
SpecializationData fallback = null;
for (int i = specializations.size() - 1; i >= 0; i--) {
SpecializationData specialization = specializations.get(i);
if (specialization.isFallback() && specialization.getMethod() != null) {
fallback = specialization;
break;
}
}
if (fallback == null) {
// no need to compute reachability
return;
}
for (int index = 0; index < specializations.size(); index++) {
SpecializationData specialization = specializations.get(index);
SpecializationData lastReachable = specialization;
for (int searchIndex = index + 1; searchIndex < specializations.size(); searchIndex++) {
SpecializationData search = specializations.get(searchIndex);
if (search == fallback) {
// reached the end of the specialization
break;
}
assert lastReachable != search;
if (!lastReachable.isReachableAfter(search)) {
lastReachable = search;
} else if (search.getReplaces().contains(specialization)) {
lastReachable = search;
}
}
specialization.setReachesFallback(lastReachable == specialization);
List<SpecializationData> failedSpecializations = null;
if (specialization.isReachesFallback() && !specialization.getCaches().isEmpty() && !specialization.getGuards().isEmpty()) {
boolean guardBoundByCache = false;
for (GuardExpression guard : specialization.getGuards()) {
if (specialization.isGuardBoundWithCache(guard)) {
guardBoundByCache = true;
break;
}
}
if (guardBoundByCache && specialization.getMaximumNumberOfInstances() > 1) {
if (failedSpecializations == null) {
failedSpecializations = new ArrayList<>();
}
failedSpecializations.add(specialization);
}
}
if (failedSpecializations != null) {
List<String> specializationIds = failedSpecializations.stream().map((e) -> e.getId()).collect(Collectors.toList());
fallback.addError("Some guards for the following specializations could not be negated for the @%s specialization: %s. " + "Guards cannot be negated for the @%s when they bind @%s parameters and the specialization may consist of multiple instances. " + "To fix this limit the number of instances to '1' or " + "introduce a more generic specialization declared between this specialization and the fallback. " + "Alternatively the use of @%s can be avoided by declaring a @%s with manually specified negated guards.", Fallback.class.getSimpleName(), specializationIds, Fallback.class.getSimpleName(), Cached.class.getSimpleName(), Fallback.class.getSimpleName(), Specialization.class.getSimpleName());
}
}
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method parse.
@Override
protected NodeData parse(Element element, AnnotationMirror mirror) {
NodeData node = parseRootType((TypeElement) element);
if (Log.isDebug() && node != null) {
String dump = node.dump();
log.message(Kind.ERROR, null, null, null, dump);
}
return node;
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method parseNodeData.
private NodeData parseNodeData(TypeElement templateType, List<TypeElement> typeHierarchy) {
AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);
TypeSystemData typeSystem = null;
if (typeSystemMirror != null) {
TypeMirror typeSystemType = ElementUtils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
typeSystem = (TypeSystemData) context.getTemplate(typeSystemType, true);
if (typeSystem == null) {
NodeData nodeData = new NodeData(context, templateType);
nodeData.addError("The used type system '%s' is invalid. Fix errors in the type system first.", ElementUtils.getQualifiedName(typeSystemType));
return nodeData;
}
} else {
// default dummy type system
typeSystem = new TypeSystemData(context, templateType, null, true);
}
boolean useNodeFactory = findFirstAnnotation(typeHierarchy, GenerateNodeFactory.class) != null;
return new NodeData(context, templateType, typeSystem, useNodeFactory);
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class AbstractParser method parse.
public final M parse(Element element) {
M model = null;
try {
AnnotationMirror mirror = null;
if (getAnnotationType() != null) {
mirror = ElementUtils.findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), getAnnotationType());
}
if (!context.getTruffleTypes().verify(context, element, mirror)) {
return null;
}
model = parse(element, mirror);
if (model == null) {
return null;
}
redirectMessages(new HashSet<MessageContainer>(), model, model);
model.emitMessages(context, log);
if (model instanceof NodeData) {
return model;
} else {
return filterErrorElements(model);
}
} catch (CompileErrorException e) {
log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage());
return null;
}
}
Aggregations