Search in sources :

Example 6 with Parameter

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

the class MethodSpecParser method parseImpl.

public TemplateMethod parseImpl(MethodSpec methodSpecification, int naturalOrder, String id, ExecutableElement method, AnnotationMirror annotation, TypeMirror returnType, List<? extends VariableElement> parameterTypes) {
    ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
    Parameter returnTypeMirror = matchParameter(returnTypeSpec, new CodeVariableElement(returnType, "returnType"), -1, -1);
    if (returnTypeMirror == null) {
        if (isEmitErrors() && method != null) {
            TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<Parameter>emptyList());
            String expectedReturnType = returnTypeSpec.toSignatureString(true);
            String actualReturnType = ElementUtils.getSimpleName(returnType);
            String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, methodSpecification.toSignatureString(method.getSimpleName().toString()));
            invalidMethod.addError(message);
            return invalidMethod;
        } else {
            return null;
        }
    }
    List<Parameter> parameters = parseParameters(methodSpecification, parameterTypes, isUseVarArgs() && method != null ? method.isVarArgs() : false);
    if (parameters == null) {
        if (isEmitErrors() && method != null) {
            TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<Parameter>emptyList());
            String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(method), methodSpecification.toSignatureString(method.getSimpleName().toString()));
            invalidMethod.addError(message);
            return invalidMethod;
        } else {
            return null;
        }
    }
    return new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, parameters);
}
Also used : TemplateMethod(com.oracle.truffle.dsl.processor.model.TemplateMethod) ParameterSpec(com.oracle.truffle.dsl.processor.model.ParameterSpec) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)

Example 7 with Parameter

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

the class NodeParser method initializeCaches.

private void initializeCaches(SpecializationData specialization, DSLExpressionResolver resolver) {
    TypeMirror cacheMirror = context.getType(Cached.class);
    List<CacheExpression> expressions = new ArrayList<>();
    for (Parameter parameter : specialization.getParameters()) {
        AnnotationMirror annotationMirror = ElementUtils.findAnnotationMirror(parameter.getVariableElement().getAnnotationMirrors(), cacheMirror);
        if (annotationMirror != null) {
            String initializer = ElementUtils.getAnnotationValue(String.class, annotationMirror, "value");
            TypeMirror parameterType = parameter.getType();
            DSLExpressionResolver localResolver = resolver;
            if (parameterType.getKind() == TypeKind.DECLARED) {
                localResolver = localResolver.copy(importPublicStaticMembers(ElementUtils.fromTypeMirror(parameterType), true));
            }
            CacheExpression cacheExpression;
            DSLExpression expression = null;
            try {
                expression = DSLExpression.parse(initializer);
                expression.accept(localResolver);
                cacheExpression = new CacheExpression(parameter, annotationMirror, expression);
                if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) {
                    cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(parameter.getType()));
                }
            } catch (InvalidExpressionException e) {
                cacheExpression = new CacheExpression(parameter, annotationMirror, null);
                cacheExpression.addError("Error parsing expression '%s': %s", initializer, e.getMessage());
            }
            if (!cacheExpression.hasErrors()) {
                Cached cached = cacheExpression.getParameter().getVariableElement().getAnnotation(Cached.class);
                cacheExpression.setDimensions(cached.dimensions());
                if (parameterType.getKind() == TypeKind.ARRAY && !ElementUtils.isSubtype(((ArrayType) parameterType).getComponentType(), context.getType(NodeInterface.class))) {
                    if (cacheExpression.getDimensions() == -1) {
                        cacheExpression.addWarning("The cached dimensions attribute must be specified for array types.");
                    }
                } else {
                    if (cacheExpression.getDimensions() != -1) {
                        cacheExpression.addError("The dimensions attribute has no affect for the type %s.", ElementUtils.getSimpleName(parameterType));
                    }
                }
            }
            expressions.add(cacheExpression);
        }
    }
    specialization.setCaches(expressions);
    if (specialization.hasErrors()) {
        return;
    }
    // verify that cache expressions are bound in the correct order.
    for (int i = 0; i < expressions.size(); i++) {
        CacheExpression currentExpression = expressions.get(i);
        Set<VariableElement> boundVariables = currentExpression.getExpression().findBoundVariableElements();
        for (int j = i + 1; j < expressions.size(); j++) {
            CacheExpression boundExpression = expressions.get(j);
            if (boundVariables.contains(boundExpression.getParameter().getVariableElement())) {
                currentExpression.addError("The initializer expression of parameter '%s' binds unitialized parameter '%s. Reorder the parameters to resolve the problem.", currentExpression.getParameter().getLocalName(), boundExpression.getParameter().getLocalName());
                break;
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) DSLExpression(com.oracle.truffle.dsl.processor.expression.DSLExpression) CacheExpression(com.oracle.truffle.dsl.processor.model.CacheExpression) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) InvalidExpressionException(com.oracle.truffle.dsl.processor.expression.InvalidExpressionException) Cached(com.oracle.truffle.api.dsl.Cached) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) DSLExpressionResolver(com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver) NodeInterface(com.oracle.truffle.api.nodes.NodeInterface)

Example 8 with Parameter

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

the class NodeParser method initializePolymorphism.

private void initializePolymorphism(NodeData node) {
    if (!node.needsRewrites(context)) {
        return;
    }
    SpecializationData generic = node.getGenericSpecialization();
    List<VariableElement> types = new ArrayList<>();
    Collection<TypeMirror> frameTypes = new HashSet<>();
    for (SpecializationData specialization : node.getSpecializations()) {
        if (specialization.getFrame() != null) {
            frameTypes.add(specialization.getFrame().getType());
        }
    }
    if (node.supportsFrame()) {
        frameTypes.add(node.getFrameType());
    }
    if (!frameTypes.isEmpty()) {
        frameTypes = ElementUtils.uniqueSortedTypes(frameTypes, false);
        TypeMirror frameType;
        if (frameTypes.size() == 1) {
            frameType = frameTypes.iterator().next();
        } else {
            frameType = context.getType(Frame.class);
        }
        types.add(new CodeVariableElement(frameType, TemplateMethod.FRAME_NAME));
    }
    TypeMirror returnType = null;
    int index = 0;
    for (Parameter genericParameter : generic.getReturnTypeAndParameters()) {
        TypeMirror polymorphicType;
        if (genericParameter.getLocalName().equals(TemplateMethod.FRAME_NAME)) {
            continue;
        }
        boolean isReturnParameter = genericParameter == generic.getReturnType();
        if (!genericParameter.getSpecification().isSignature()) {
            polymorphicType = genericParameter.getType();
        } else {
            NodeExecutionData execution = genericParameter.getSpecification().getExecution();
            Collection<TypeMirror> usedTypes = new HashSet<>();
            for (SpecializationData specialization : node.getSpecializations()) {
                if (specialization.isUninitialized()) {
                    continue;
                }
                Parameter parameter = specialization.findParameter(genericParameter.getLocalName());
                if (parameter == specialization.getReturnType() && specialization.isFallback() && specialization.getMethod() == null) {
                    continue;
                }
                if (parameter == null) {
                    throw new AssertionError("Parameter existed in generic specialization but not in specialized. param = " + genericParameter.getLocalName());
                }
                if (isReturnParameter && specialization.hasUnexpectedResultRewrite()) {
                    if (!ElementUtils.isSubtypeBoxed(context, context.getType(Object.class), node.getGenericType(execution))) {
                        specialization.addError("Implicit 'Object' return type from UnexpectedResultException not compatible with generic type '%s'.", node.getGenericType(execution));
                    } else {
                        // if any specialization throws UnexpectedResultException, Object could
                        // be returned
                        usedTypes.add(context.getType(Object.class));
                    }
                }
                usedTypes.add(parameter.getType());
            }
            usedTypes = ElementUtils.uniqueSortedTypes(usedTypes, false);
            if (usedTypes.size() == 1) {
                polymorphicType = usedTypes.iterator().next();
            } else {
                polymorphicType = ElementUtils.getCommonSuperType(context, usedTypes);
            }
            if (execution != null && !ElementUtils.isSubtypeBoxed(context, polymorphicType, node.getGenericType(execution))) {
                throw new AssertionError(String.format("Polymorphic types %s not compatible to generic type %s.", polymorphicType, node.getGenericType(execution)));
            }
        }
        if (isReturnParameter) {
            returnType = polymorphicType;
        } else {
            types.add(new CodeVariableElement(polymorphicType, "param" + index));
        }
        index++;
    }
    SpecializationMethodParser parser = new SpecializationMethodParser(context, node);
    SpecializationData polymorphic = parser.create("Polymorphic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, types);
    if (polymorphic == null) {
        throw new AssertionError("Failed to parse polymorphic signature. " + parser.createDefaultMethodSpec(null, null, false, null) + " Types: " + returnType + " - " + types);
    }
    polymorphic.setKind(SpecializationKind.POLYMORPHIC);
    node.getSpecializations().add(polymorphic);
}
Also used : Frame(com.oracle.truffle.api.frame.Frame) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) ArrayList(java.util.ArrayList) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) HashSet(java.util.HashSet)

Example 9 with Parameter

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

the class NodeParser method initializeExpressions.

private void initializeExpressions(List<? extends Element> elements, NodeData node) {
    List<Element> members = filterNotAccessibleElements(node.getTemplateType(), elements);
    List<VariableElement> fields = new ArrayList<>();
    for (NodeFieldData field : node.getFields()) {
        fields.add(field.getVariable());
    }
    for (SpecializationData specialization : node.getSpecializations()) {
        if (specialization.getMethod() == null) {
            continue;
        }
        List<Element> specializationMembers = new ArrayList<>(members.size() + specialization.getParameters().size() + fields.size());
        for (Parameter p : specialization.getParameters()) {
            specializationMembers.add(p.getVariableElement());
        }
        specializationMembers.addAll(fields);
        specializationMembers.addAll(members);
        DSLExpressionResolver resolver = new DSLExpressionResolver(context, specializationMembers);
        initializeCaches(specialization, resolver);
        initializeGuards(specialization, resolver);
        if (specialization.hasErrors()) {
            continue;
        }
        initializeLimit(specialization, resolver);
        initializeAssumptions(specialization, resolver);
    }
}
Also used : NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) TypeElement(javax.lang.model.element.TypeElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) DSLExpressionResolver(com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver)

Example 10 with Parameter

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

the class ImplicitCastParser method create.

@Override
public ImplicitCastData create(TemplateMethod method, boolean invalid) {
    if (invalid) {
        return new ImplicitCastData(method, null, null);
    }
    Parameter target = method.findParameter("targetValue");
    Parameter source = method.findParameter("sourceValue");
    TypeMirror targetType = target.getType();
    TypeMirror sourceType = source.getType();
    if (ElementUtils.typeEquals(targetType, sourceType)) {
        method.addError("Target type and source type of an @%s must not be the same type.", ImplicitCast.class.getSimpleName());
    }
    if (!method.getMethod().getModifiers().contains(Modifier.STATIC)) {
        method.addError("@%s annotated method %s must be static.", ImplicitCast.class.getSimpleName(), method.getMethodName());
    }
    return new ImplicitCastData(method, sourceType, targetType);
}
Also used : ImplicitCastData(com.oracle.truffle.dsl.processor.model.ImplicitCastData) TypeMirror(javax.lang.model.type.TypeMirror) ImplicitCast(com.oracle.truffle.api.dsl.ImplicitCast) Parameter(com.oracle.truffle.dsl.processor.model.Parameter)

Aggregations

Parameter (com.oracle.truffle.dsl.processor.model.Parameter)16 ArrayList (java.util.ArrayList)10 TypeMirror (javax.lang.model.type.TypeMirror)9 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)8 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)8 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)7 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)6 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)6 CodeTree (com.oracle.truffle.dsl.processor.java.model.CodeTree)4 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)4 VariableElement (javax.lang.model.element.VariableElement)4 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)3 TypeGuard (com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard)3 Cached (com.oracle.truffle.api.dsl.Cached)2 Node (com.oracle.truffle.api.nodes.Node)2 NodeInterface (com.oracle.truffle.api.nodes.NodeInterface)2 DSLExpression (com.oracle.truffle.dsl.processor.expression.DSLExpression)2 Variable (com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable)2 DSLExpressionResolver (com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver)2 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)2