Search in sources :

Example 6 with ExecutableTypeData

use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.

the class NodeParser method parseExecutableTypeData.

private List<ExecutableTypeData> parseExecutableTypeData(NodeData node, List<? extends Element> elements, int signatureSize, List<TypeMirror> frameTypes, boolean includeFinals) {
    List<ExecutableTypeData> typeData = new ArrayList<>();
    for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
        Set<Modifier> modifiers = method.getModifiers();
        if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.STATIC)) {
            continue;
        }
        if (!includeFinals && modifiers.contains(Modifier.FINAL)) {
            continue;
        }
        if (!method.getSimpleName().toString().startsWith("execute")) {
            continue;
        }
        if (ElementUtils.findAnnotationMirror(context.getEnvironment(), method, Specialization.class) != null) {
            continue;
        }
        ExecutableTypeData executableType = new ExecutableTypeData(node, method, signatureSize, context.getFrameTypes());
        if (executableType.getFrameParameter() != null) {
            boolean supportedType = false;
            for (TypeMirror type : frameTypes) {
                if (ElementUtils.isAssignable(type, executableType.getFrameParameter())) {
                    supportedType = true;
                    break;
                }
            }
            if (!supportedType) {
                continue;
            }
        }
        typeData.add(executableType);
    }
    namesUnique(typeData);
    return typeData;
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) Specialization(com.oracle.truffle.api.dsl.Specialization) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) Modifier(javax.lang.model.element.Modifier)

Example 7 with ExecutableTypeData

use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.

the class NodeParser method buildExecutableHierarchy.

private static void buildExecutableHierarchy(NodeData node, ExecutableTypeData parent, ListIterator<ExecutableTypeData> executesIterator) {
    while (executesIterator.hasNext()) {
        ExecutableTypeData other = executesIterator.next();
        if (other.canDelegateTo(parent)) {
            parent.addDelegatedFrom(other);
            executesIterator.remove();
        }
    }
    for (int i = 1; i < parent.getDelegatedFrom().size(); i++) {
        buildExecutableHierarchy(node, parent.getDelegatedFrom().get(i - 1), parent.getDelegatedFrom().listIterator(i));
    }
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData)

Example 8 with ExecutableTypeData

use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.

the class NodeParser method initializeChildren.

@SuppressWarnings("unchecked")
private void initializeChildren(NodeData node) {
    for (NodeChildData child : node.getChildren()) {
        AnnotationValue executeWithValue1 = child.getExecuteWithValue();
        List<AnnotationValue> executeWithValues = ElementUtils.resolveAnnotationValue(List.class, executeWithValue1);
        List<NodeExecutionData> executeWith = new ArrayList<>();
        for (AnnotationValue executeWithValue : executeWithValues) {
            String executeWithString = ElementUtils.resolveAnnotationValue(String.class, executeWithValue);
            if (child.getName().equals(executeWithString)) {
                child.addError(executeWithValue1, "The child node '%s' cannot be executed with itself.", executeWithString);
                continue;
            }
            NodeExecutionData found = null;
            boolean before = true;
            for (NodeExecutionData resolveChild : node.getChildExecutions()) {
                if (resolveChild.getChild() == child) {
                    before = false;
                    continue;
                }
                if (resolveChild.getIndexedName().equals(executeWithString)) {
                    found = resolveChild;
                    break;
                }
            }
            if (found == null) {
                child.addError(executeWithValue1, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
                continue;
            } else if (!before) {
                child.addError(executeWithValue1, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, executeWithString);
                continue;
            }
            executeWith.add(found);
        }
        child.setExecuteWith(executeWith);
    }
    for (NodeChildData child : node.getChildren()) {
        TypeMirror nodeType = child.getNodeType();
        NodeData fieldNodeData = parseChildNodeData(node, child, ElementUtils.fromTypeMirror(nodeType));
        child.setNode(fieldNodeData);
        if (fieldNodeData == null || fieldNodeData.hasErrors()) {
            child.addError("Node type '%s' is invalid or not a subclass of Node.", ElementUtils.getQualifiedName(nodeType));
        } else {
            List<ExecutableTypeData> types = child.findGenericExecutableTypes(context);
            if (types.isEmpty()) {
                AnnotationValue executeWithValue = child.getExecuteWithValue();
                child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s and frame types %s.", child.getExecuteWith().size(), ElementUtils.getSimpleName(nodeType), ElementUtils.getUniqueIdentifiers(createAllowedChildFrameTypes(node)));
            }
        }
    }
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ArrayList(java.util.ArrayList) AnnotationValue(javax.lang.model.element.AnnotationValue) NodeData(com.oracle.truffle.dsl.processor.model.NodeData)

Example 9 with ExecutableTypeData

use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.

the class NodeParser method buildExecutableHierarchy.

private static List<ExecutableTypeData> buildExecutableHierarchy(NodeData node) {
    List<ExecutableTypeData> executes = node.getExecutableTypes();
    if (executes.isEmpty()) {
        return Collections.emptyList();
    }
    List<ExecutableTypeData> hierarchyExecutes = new ArrayList<>(executes);
    Collections.sort(hierarchyExecutes);
    ExecutableTypeData parent = hierarchyExecutes.get(0);
    ListIterator<ExecutableTypeData> executesIterator = hierarchyExecutes.listIterator(1);
    buildExecutableHierarchy(node, parent, executesIterator);
    return hierarchyExecutes;
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) ArrayList(java.util.ArrayList)

Example 10 with ExecutableTypeData

use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.

the class NodeParser method initializeExecutableTypes.

private void initializeExecutableTypes(NodeData node) {
    List<ExecutableTypeData> allExecutes = node.getExecutableTypes();
    Set<String> inconsistentFrameTypes = new HashSet<>();
    TypeMirror frameType = null;
    for (ExecutableTypeData execute : allExecutes) {
        TypeMirror frame = execute.getFrameParameter();
        TypeMirror resolvedFrameType;
        if (frame != null) {
            resolvedFrameType = frame;
            if (frameType == null) {
                frameType = resolvedFrameType;
            } else if (!ElementUtils.typeEquals(frameType, resolvedFrameType)) {
                // found inconsistent frame types
                inconsistentFrameTypes.add(ElementUtils.getSimpleName(frameType));
                inconsistentFrameTypes.add(ElementUtils.getSimpleName(resolvedFrameType));
            }
        }
    }
    if (!inconsistentFrameTypes.isEmpty()) {
        // ensure they are sorted somehow
        List<String> inconsistentFrameTypesList = new ArrayList<>(inconsistentFrameTypes);
        Collections.sort(inconsistentFrameTypesList);
        node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList);
    }
    if (frameType == null) {
        frameType = context.getType(void.class);
    }
    node.setFrameType(frameType);
    boolean genericFound = false;
    for (ExecutableTypeData type : node.getExecutableTypes()) {
        if (!type.hasUnexpectedValue(context)) {
            genericFound = true;
            break;
        }
    }
    // no generic executes
    if (!genericFound) {
        node.addError("No accessible and overridable generic execute method found. Generic execute methods usually have the " + "signature 'public abstract {Type} execute(VirtualFrame)' and must not throw any checked exceptions.");
    }
    int nodeChildDeclarations = 0;
    int nodeChildDeclarationsRequired = 0;
    List<NodeExecutionData> executions = node.getChildExecutions();
    for (NodeExecutionData execution : executions) {
        if (execution.getChild() == null) {
            nodeChildDeclarationsRequired = execution.getIndex() + 1;
        } else {
            nodeChildDeclarations++;
        }
    }
    List<String> requireNodeChildDeclarations = new ArrayList<>();
    for (ExecutableTypeData type : allExecutes) {
        if (type.getEvaluatedCount() < nodeChildDeclarationsRequired) {
            requireNodeChildDeclarations.add(ElementUtils.createReferenceName(type.getMethod()));
        }
    }
    if (!requireNodeChildDeclarations.isEmpty()) {
        node.addError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " + "The following execute methods do not provide all evaluated values for the expected signature size %s: %s.", executions.size(), requireNodeChildDeclarations);
    }
    if (nodeChildDeclarations > 0 && executions.size() == node.getMinimalEvaluatedParameters()) {
        for (NodeChildData child : node.getChildren()) {
            child.addError("Unnecessary @NodeChild declaration. All evaluated child values are provided as parameters in execute methods.");
        }
    }
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) ArrayList(java.util.ArrayList) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) HashSet(java.util.HashSet)

Aggregations

ExecutableTypeData (com.oracle.truffle.dsl.processor.model.ExecutableTypeData)16 ArrayList (java.util.ArrayList)11 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)10 TypeMirror (javax.lang.model.type.TypeMirror)10 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)6 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)6 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)6 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)5 NodeChildData (com.oracle.truffle.dsl.processor.model.NodeChildData)4 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)4 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)3 HashSet (java.util.HashSet)3 UnexpectedResultException (com.oracle.truffle.api.nodes.UnexpectedResultException)2 CodeTree (com.oracle.truffle.dsl.processor.java.model.CodeTree)2 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)2 LinkedHashSet (java.util.LinkedHashSet)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 Specialization (com.oracle.truffle.api.dsl.Specialization)1 Child (com.oracle.truffle.api.nodes.Node.Child)1 NodeInfo (com.oracle.truffle.api.nodes.NodeInfo)1