Search in sources :

Example 6 with CodeVariableElement

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

the class TypeSystemCodeGenerator method createExpectMethod.

static CodeExecutableElement createExpectMethod(Modifier visibility, TypeSystemData typeSystem, TypeMirror sourceTypeOriginal, TypeMirror expectedTypeOriginal) {
    TypeMirror expectedType = ElementUtils.fillInGenericWildcards(expectedTypeOriginal);
    TypeMirror sourceType = ElementUtils.fillInGenericWildcards(sourceTypeOriginal);
    if (ElementUtils.isObject(expectedType) || ElementUtils.isVoid(expectedType)) {
        return null;
    }
    CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), expectedType, TypeSystemCodeGenerator.expectTypeMethodName(typeSystem, expectedType));
    method.setVisibility(visibility);
    method.addParameter(new CodeVariableElement(sourceType, LOCAL_VALUE));
    method.addThrownType(typeSystem.getContext().getTruffleTypes().getUnexpectedValueException());
    CodeTreeBuilder body = method.createBuilder();
    body.startIf().tree(check(typeSystem, expectedType, LOCAL_VALUE)).end().startBlock();
    body.startReturn().tree(cast(typeSystem, expectedType, LOCAL_VALUE)).end();
    body.end();
    body.startThrow().startNew(typeSystem.getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
    return method;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 7 with CodeVariableElement

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

the class AbstractCodeWriter method visitVariable.

@Override
public Void visitVariable(VariableElement f, Void p) {
    Element parent = f.getEnclosingElement();
    for (AnnotationMirror annotation : f.getAnnotationMirrors()) {
        visitAnnotation(f, annotation);
        write(" ");
    }
    CodeTree init = null;
    if (f instanceof CodeVariableElement) {
        init = ((CodeVariableElement) f).getInit();
    }
    if (parent != null && parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) {
        write(f.getSimpleName());
        if (init != null) {
            write("(");
            visitTree(init, p, f);
            write(")");
        }
    } else {
        writeModifiers(f.getModifiers(), true);
        boolean varArgs = false;
        if (parent != null && parent.getKind() == ElementKind.METHOD) {
            ExecutableElement method = (ExecutableElement) parent;
            if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) {
                varArgs = true;
            }
        }
        TypeMirror varType = f.asType();
        if (varArgs) {
            if (varType.getKind() == TypeKind.ARRAY) {
                varType = ((ArrayType) varType).getComponentType();
            }
            write(useImport(f, varType));
            write("...");
        } else {
            write(useImport(f, varType));
        }
        write(" ");
        write(f.getSimpleName());
        if (init != null) {
            write(" = ");
            visitTree(init, p, f);
        }
    }
    return null;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) CodeTree(com.oracle.truffle.dsl.processor.java.model.CodeTree) TypeMirror(javax.lang.model.type.TypeMirror) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeParameterElement(javax.lang.model.element.TypeParameterElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)

Example 8 with CodeVariableElement

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

the class NodeParser method createGenericSpecialization.

private SpecializationData createGenericSpecialization(final NodeData node) {
    FallbackParser parser = new FallbackParser(context, node);
    MethodSpec specification = parser.createDefaultMethodSpec(node.getSpecializations().iterator().next().getMethod(), null, true, null);
    List<VariableElement> parameterTypes = new ArrayList<>();
    int signatureIndex = 1;
    for (ParameterSpec spec : specification.getRequired()) {
        parameterTypes.add(new CodeVariableElement(createGenericType(node, spec), "arg" + signatureIndex));
        if (spec.isSignature()) {
            signatureIndex++;
        }
    }
    TypeMirror returnType = createGenericType(node, specification.getReturnType());
    SpecializationData generic = parser.create("Generic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, parameterTypes);
    if (generic == null) {
        throw new RuntimeException("Unable to create generic signature for node " + node.getNodeId() + " with " + parameterTypes + ". Specification " + specification + ".");
    }
    return generic;
}
Also used : MethodSpec(com.oracle.truffle.dsl.processor.model.MethodSpec) ParameterSpec(com.oracle.truffle.dsl.processor.model.ParameterSpec) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement)

Example 9 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement 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 10 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement 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)

Aggregations

CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)22 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)14 TypeMirror (javax.lang.model.type.TypeMirror)12 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)8 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)8 VariableElement (javax.lang.model.element.VariableElement)8 ArrayList (java.util.ArrayList)7 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)6 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)5 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)5 ExecutableElement (javax.lang.model.element.ExecutableElement)5 CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)4 TypeElement (javax.lang.model.element.TypeElement)4 Child (com.oracle.truffle.api.nodes.Node.Child)3 CodeAnnotationMirror (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror)3 CodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror)3 NodeChildData (com.oracle.truffle.dsl.processor.model.NodeChildData)3 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)3 Parameter (com.oracle.truffle.dsl.processor.model.Parameter)3 Assumption (com.oracle.truffle.api.Assumption)2