Search in sources :

Example 26 with CodeExecutableElement

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

the class NodeFactoryFactory method createCreateNodeMethod.

private CodeExecutableElement createCreateNodeMethod() {
    CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode");
    CodeVariableElement arguments = new CodeVariableElement(context.getType(Object.class), "arguments");
    method.setVarArgs(true);
    method.addParameter(arguments);
    CodeTreeBuilder builder = method.createBuilder();
    List<ExecutableElement> signatures = GeneratorUtils.findUserConstructors(createdFactoryElement.asType());
    boolean ifStarted = false;
    for (ExecutableElement element : signatures) {
        ifStarted = builder.startIf(ifStarted);
        builder.string("arguments.length == " + element.getParameters().size());
        int index = 0;
        for (VariableElement param : element.getParameters()) {
            if (ElementUtils.isObject(param.asType())) {
                index++;
                continue;
            }
            builder.string(" && ");
            if (!param.asType().getKind().isPrimitive()) {
                builder.string("(arguments[" + index + "] == null || ");
            }
            builder.string("arguments[" + index + "] instanceof ");
            builder.type(ElementUtils.eraseGenericTypes(ElementUtils.boxType(context, param.asType())));
            if (!param.asType().getKind().isPrimitive()) {
                builder.string(")");
            }
            index++;
        }
        builder.end();
        builder.startBlock();
        builder.startReturn().startCall("create");
        index = 0;
        for (VariableElement param : element.getParameters()) {
            builder.startGroup();
            if (!ElementUtils.isObject(param.asType())) {
                builder.string("(").type(param.asType()).string(") ");
            }
            builder.string("arguments[").string(String.valueOf(index)).string("]");
            builder.end();
            index++;
        }
        builder.end().end();
        // block
        builder.end();
    }
    builder.startElseBlock();
    builder.startThrow().startNew(context.getType(IllegalArgumentException.class));
    builder.doubleQuote("Invalid create signature.");
    builder.end().end();
    // else block
    builder.end();
    return method;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 27 with CodeExecutableElement

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

the class NodeFactoryFactory method createCreateGetExecutionSignature.

private CodeExecutableElement createCreateGetExecutionSignature() {
    TypeMirror returnValue = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getType(List.class)));
    CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnValue, "getExecutionSignature");
    CodeTreeBuilder builder = method.createBuilder();
    builder.startReturn();
    builder.startStaticCall(context.getType(Arrays.class), "asList");
    for (NodeExecutionData execution : node.getChildExecutions()) {
        builder.typeLiteral(execution.getNodeType());
    }
    builder.end();
    builder.end();
    return method;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) TypeMirror(javax.lang.model.type.TypeMirror) Arrays(java.util.Arrays) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 28 with CodeExecutableElement

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

the class NodeFactoryFactory method createCreateMethod.

private CodeExecutableElement createCreateMethod(ExecutableElement constructor) {
    CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), constructor);
    method.setSimpleName(CodeNames.of("create"));
    method.getModifiers().clear();
    method.getModifiers().add(Modifier.PUBLIC);
    method.getModifiers().add(Modifier.STATIC);
    method.setReturnType(node.getNodeType());
    CodeTreeBuilder body = method.createBuilder();
    body.startReturn();
    if (node.getSpecializations().isEmpty()) {
        body.nullLiteral();
    } else {
        body.startNew(NodeCodeGenerator.nodeType(node));
        for (VariableElement var : method.getParameters()) {
            body.string(var.getSimpleName().toString());
        }
        body.end();
    }
    body.end();
    return method;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) VariableElement(javax.lang.model.element.VariableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 29 with CodeExecutableElement

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

the class OptionProcessor method generateDescriptors.

private CodeTypeElement generateDescriptors(ProcessorContext context, Element element, OptionsInfo model) {
    String optionsClassName = ElementUtils.getSimpleName(element.asType()) + OptionDescriptors.class.getSimpleName();
    TypeElement sourceType = (TypeElement) model.type;
    PackageElement pack = context.getEnvironment().getElementUtils().getPackageOf(sourceType);
    Set<Modifier> typeModifiers = ElementUtils.modifiers(Modifier.FINAL);
    CodeTypeElement descriptors = new CodeTypeElement(typeModifiers, ElementKind.CLASS, pack, optionsClassName);
    DeclaredType optionDescriptorsType = context.getDeclaredType(OptionDescriptors.class);
    descriptors.getImplements().add(optionDescriptorsType);
    ExecutableElement get = ElementUtils.findExecutableElement(optionDescriptorsType, "get");
    CodeExecutableElement getMethod = CodeExecutableElement.clone(processingEnv, get);
    getMethod.getModifiers().remove(ABSTRACT);
    CodeTreeBuilder builder = getMethod.createBuilder();
    String nameVariableName = getMethod.getParameters().get(0).getSimpleName().toString();
    builder.startSwitch().string(nameVariableName).end().startBlock();
    for (OptionInfo info : model.options) {
        builder.startCase().doubleQuote(info.name).end().startCaseBlock();
        builder.startReturn().tree(createBuildOptionDescriptor(context, info)).end();
        // case
        builder.end();
    }
    // block
    builder.end();
    builder.returnNull();
    descriptors.add(getMethod);
    CodeExecutableElement iteratorMethod = CodeExecutableElement.clone(processingEnv, ElementUtils.findExecutableElement(optionDescriptorsType, "iterator"));
    iteratorMethod.getModifiers().remove(ABSTRACT);
    builder = iteratorMethod.createBuilder();
    builder.startReturn();
    if (model.options.isEmpty()) {
        builder.startStaticCall(context.getType(Collections.class), "<OptionDescriptor> emptyList().iterator").end();
    } else {
        builder.startStaticCall(context.getType(Arrays.class), "asList");
        for (OptionInfo info : model.options) {
            builder.startGroup();
            builder.startIndention();
            builder.newLine();
            builder.tree(createBuildOptionDescriptor(context, info));
            builder.end();
            builder.end();
        }
        // / asList call
        builder.end();
        builder.newLine();
        builder.startCall("", "iterator").end();
    }
    // return
    builder.end();
    descriptors.add(iteratorMethod);
    return descriptors;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) TypeElement(javax.lang.model.element.TypeElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) OptionDescriptors(org.graalvm.options.OptionDescriptors) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) PackageElement(javax.lang.model.element.PackageElement) Arrays(java.util.Arrays) Modifier(javax.lang.model.element.Modifier) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) DeclaredType(javax.lang.model.type.DeclaredType)

Example 30 with CodeExecutableElement

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

the class InstrumentableProcessor method generateWrapper.

@SuppressWarnings("deprecation")
private CodeTypeElement generateWrapper(ProcessorContext context, Element e, boolean topLevelClass) {
    if (!e.getKind().isClass()) {
        return null;
    }
    if (e.getModifiers().contains(Modifier.PRIVATE)) {
        emitError(e, "Class must not be private to generate a wrapper.");
        return null;
    }
    if (e.getModifiers().contains(Modifier.FINAL)) {
        emitError(e, "Class must not be final to generate a wrapper.");
        return null;
    }
    if (e.getEnclosingElement().getKind() != ElementKind.PACKAGE && !e.getModifiers().contains(Modifier.STATIC)) {
        emitError(e, "Inner class must be static to generate a wrapper.");
        return null;
    }
    TypeElement sourceType = (TypeElement) e;
    ExecutableElement constructor = null;
    List<ExecutableElement> constructors = ElementFilter.constructorsIn(e.getEnclosedElements());
    if (constructors.isEmpty()) {
        // add default constructor
        constructors.add(new CodeExecutableElement(ElementUtils.modifiers(Modifier.PUBLIC), null, e.getSimpleName().toString()));
    }
    // try visible default constructor
    for (ListIterator<ExecutableElement> iterator = constructors.listIterator(); iterator.hasNext(); ) {
        ExecutableElement c = iterator.next();
        Modifier modifier = ElementUtils.getVisibility(c.getModifiers());
        if (modifier == Modifier.PRIVATE) {
            iterator.remove();
            continue;
        }
        if (c.getParameters().isEmpty()) {
            constructor = c;
            break;
        }
    }
    // try copy constructor
    if (constructor == null) {
        for (ExecutableElement c : constructors) {
            VariableElement firstParameter = c.getParameters().iterator().next();
            if (ElementUtils.typeEquals(firstParameter.asType(), sourceType.asType())) {
                constructor = c;
                break;
            }
        }
    }
    // try source section constructor
    if (constructor == null) {
        for (ExecutableElement c : constructors) {
            VariableElement firstParameter = c.getParameters().iterator().next();
            if (ElementUtils.typeEquals(firstParameter.asType(), context.getType(SourceSection.class))) {
                constructor = c;
                break;
            }
        }
    }
    if (constructor == null) {
        emitError(sourceType, "No suiteable constructor found for wrapper factory generation. At least one default or copy constructor must be visible.");
        return null;
    }
    PackageElement pack = context.getEnvironment().getElementUtils().getPackageOf(sourceType);
    Set<Modifier> typeModifiers;
    String wrapperClassName = createWrapperClassName(sourceType);
    if (topLevelClass) {
        typeModifiers = ElementUtils.modifiers(Modifier.FINAL);
    } else {
        typeModifiers = ElementUtils.modifiers(Modifier.PRIVATE, Modifier.FINAL);
        // add some suffix to avoid name clashes
        wrapperClassName += "0";
    }
    CodeTypeElement wrapperType = new CodeTypeElement(typeModifiers, ElementKind.CLASS, pack, wrapperClassName);
    TypeMirror resolvedSuperType = sourceType.asType();
    wrapperType.setSuperClass(resolvedSuperType);
    if (topLevelClass) {
        wrapperType.getImplements().add(context.getType(InstrumentableNode.WrapperNode.class));
    } else {
        wrapperType.getImplements().add(context.getType(com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode.class));
    }
    addGeneratedBy(context, wrapperType, sourceType);
    wrapperType.add(createNodeChild(context, sourceType.asType(), FIELD_DELEGATE));
    wrapperType.add(createNodeChild(context, context.getType(ProbeNode.class), FIELD_PROBE));
    Set<Modifier> constructorModifiers;
    if (topLevelClass) {
        // package protected
        constructorModifiers = ElementUtils.modifiers();
    } else {
        constructorModifiers = ElementUtils.modifiers(Modifier.PRIVATE);
    }
    CodeExecutableElement wrappedConstructor = GeneratorUtils.createConstructorUsingFields(constructorModifiers, wrapperType, constructor);
    wrapperType.add(wrappedConstructor);
    // generate getters
    for (VariableElement field : wrapperType.getFields()) {
        CodeExecutableElement getter = new CodeExecutableElement(ElementUtils.modifiers(Modifier.PUBLIC), field.asType(), "get" + ElementUtils.firstLetterUpperCase(field.getSimpleName().toString()));
        getter.createBuilder().startReturn().string(field.getSimpleName().toString()).end();
        wrapperType.add(getter);
    }
    if (isOverrideableOrUndeclared(sourceType, METHOD_GET_NODE_COST)) {
        TypeMirror returnType = context.getType(NodeCost.class);
        CodeExecutableElement getInstrumentationTags = new CodeExecutableElement(ElementUtils.modifiers(Modifier.PUBLIC), returnType, METHOD_GET_NODE_COST);
        getInstrumentationTags.createBuilder().startReturn().staticReference(returnType, "NONE").end();
        wrapperType.add(getInstrumentationTags);
    }
    List<ExecutableElement> wrappedMethods = new ArrayList<>();
    List<ExecutableElement> wrappedExecuteMethods = new ArrayList<>();
    List<? extends Element> elementList = context.getEnvironment().getElementUtils().getAllMembers(sourceType);
    for (ExecutableElement method : ElementFilter.methodsIn(elementList)) {
        Set<Modifier> modifiers = method.getModifiers();
        if (modifiers.contains(Modifier.FINAL)) {
            continue;
        }
        Modifier visibility = ElementUtils.getVisibility(modifiers);
        if (visibility == Modifier.PRIVATE) {
            continue;
        }
        String methodName = method.getSimpleName().toString();
        if (methodName.startsWith(EXECUTE_METHOD_PREFIX)) {
            VariableElement firstParam = method.getParameters().isEmpty() ? null : method.getParameters().get(0);
            if (topLevelClass && (firstParam == null || !ElementUtils.isAssignable(firstParam.asType(), context.getType(VirtualFrame.class)))) {
                emitError(e, String.format("Wrapped execute method %s must have VirtualFrame as first parameter.", method.getSimpleName().toString()));
                return null;
            }
            wrappedExecuteMethods.add(method);
        } else {
            if (// 
            modifiers.contains(Modifier.ABSTRACT) && !methodName.equals("getSourceSection") && !methodName.equals(METHOD_GET_NODE_COST)) {
                wrappedMethods.add(method);
            }
        }
    }
    if (wrappedExecuteMethods.isEmpty()) {
        emitError(sourceType, String.format("No methods starting with name execute found to wrap."));
        return null;
    }
    Collections.sort(wrappedExecuteMethods, new Comparator<ExecutableElement>() {

        public int compare(ExecutableElement o1, ExecutableElement o2) {
            return ElementUtils.compareMethod(o1, o2);
        }
    });
    for (ExecutableElement executeMethod : wrappedExecuteMethods) {
        CodeExecutableElement wrappedExecute = CodeExecutableElement.clone(processingEnv, executeMethod);
        wrappedExecute.getModifiers().remove(Modifier.ABSTRACT);
        wrappedExecute.getAnnotationMirrors().clear();
        String frameParameterName = "null";
        for (VariableElement parameter : wrappedExecute.getParameters()) {
            if (ElementUtils.typeEquals(context.getType(VirtualFrame.class), parameter.asType())) {
                frameParameterName = parameter.getSimpleName().toString();
                break;
            }
        }
        CodeTreeBuilder builder = wrappedExecute.createBuilder();
        TypeMirror returnTypeMirror = executeMethod.getReturnType();
        boolean returnVoid = ElementUtils.isVoid(returnTypeMirror);
        String returnName;
        if (!returnVoid) {
            returnName = "returnValue";
            builder.declaration(returnTypeMirror, returnName, (CodeTree) null);
        } else {
            returnName = "null";
        }
        builder.startFor().startGroup().string(";;").end().end().startBlock();
        builder.declaration("boolean", VAR_RETURN_CALLED, "false");
        builder.startTryBlock();
        builder.startStatement().startCall(FIELD_PROBE, METHOD_ON_ENTER).string(frameParameterName).end().end();
        CodeTreeBuilder callDelegate = builder.create();
        callDelegate.startCall(FIELD_DELEGATE, executeMethod.getSimpleName().toString());
        for (VariableElement parameter : wrappedExecute.getParameters()) {
            callDelegate.string(parameter.getSimpleName().toString());
        }
        callDelegate.end();
        if (returnVoid) {
            builder.statement(callDelegate.build());
        } else {
            builder.startStatement().string(returnName).string(" = ").tree(callDelegate.build()).end();
        }
        builder.startStatement().string(VAR_RETURN_CALLED).string(" = true").end();
        builder.startStatement().startCall(FIELD_PROBE, METHOD_ON_RETURN_VALUE).string(frameParameterName).string(returnName).end().end();
        builder.statement("break");
        if (wrappedExecute.getThrownTypes().contains(context.getType(UnexpectedResultException.class))) {
            builder.end().startCatchBlock(context.getType(UnexpectedResultException.class), "e");
            builder.startStatement().string(VAR_RETURN_CALLED).string(" = true").end();
            builder.startStatement().startCall(FIELD_PROBE, METHOD_ON_RETURN_VALUE).string(frameParameterName).string("e.getResult()").end().end();
            builder.startThrow().string("e").end();
        }
        builder.end().startCatchBlock(context.getType(Throwable.class), "t");
        CodeTreeBuilder callExOrUnwind = builder.create();
        callExOrUnwind.startCall(FIELD_PROBE, METHOD_ON_RETURN_EXCEPTIONAL_OR_UNWIND).string(frameParameterName).string("t").string(VAR_RETURN_CALLED).end();
        builder.declaration("Object", "result", callExOrUnwind.build());
        builder.startIf().string("result == ").string(CONSTANT_REENTER).end();
        builder.startBlock();
        builder.statement("continue");
        builder.end().startElseIf();
        if (returnVoid) {
            builder.string("result != null").end();
            builder.startBlock();
            builder.statement("break");
        } else {
            boolean objectReturnType = "java.lang.Object".equals(ElementUtils.getQualifiedName(returnTypeMirror)) && returnTypeMirror.getKind() != TypeKind.ARRAY;
            boolean throwsUnexpectedResult = wrappedExecute.getThrownTypes().contains(context.getType(UnexpectedResultException.class));
            if (objectReturnType || !throwsUnexpectedResult) {
                builder.string("result != null").end();
                builder.startBlock();
                builder.startStatement().string(returnName).string(" = ");
                if (!objectReturnType) {
                    builder.string("(").string(ElementUtils.getSimpleName(returnTypeMirror)).string(") ");
                }
                builder.string("result").end();
                builder.statement("break");
            } else {
                // can throw UnexpectedResultException
                builder.string("result").instanceOf(boxed(returnTypeMirror, context.getEnvironment().getTypeUtils())).end();
                builder.startBlock();
                builder.startStatement().string(returnName).string(" = ");
                builder.string("(").string(ElementUtils.getSimpleName(returnTypeMirror)).string(") ");
                builder.string("result").end();
                builder.statement("break");
                builder.end();
                builder.startElseIf().string("result != null").end();
                builder.startBlock();
                builder.startThrow().string("new UnexpectedResultException(result)").end();
            }
        }
        builder.end();
        builder.startThrow().string("t").end();
        builder.end(2);
        if (!returnVoid) {
            builder.startReturn().string(returnName).end();
        }
        wrapperType.add(wrappedExecute);
    }
    for (ExecutableElement delegateMethod : wrappedMethods) {
        CodeExecutableElement generatedMethod = CodeExecutableElement.clone(processingEnv, delegateMethod);
        generatedMethod.getModifiers().remove(Modifier.ABSTRACT);
        CodeTreeBuilder callDelegate = generatedMethod.createBuilder();
        if (ElementUtils.isVoid(delegateMethod.getReturnType())) {
            callDelegate.startStatement();
        } else {
            callDelegate.startReturn();
        }
        callDelegate.startCall("this." + FIELD_DELEGATE, generatedMethod.getSimpleName().toString());
        for (VariableElement parameter : generatedMethod.getParameters()) {
            callDelegate.string(parameter.getSimpleName().toString());
        }
        callDelegate.end().end();
        wrapperType.add(generatedMethod);
    }
    return wrapperType;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) UnexpectedResultException(com.oracle.truffle.api.nodes.UnexpectedResultException) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) CodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) SourceSection(com.oracle.truffle.api.source.SourceSection) Modifier(javax.lang.model.element.Modifier) TypeElement(javax.lang.model.element.TypeElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) VirtualFrame(com.oracle.truffle.api.frame.VirtualFrame) PackageElement(javax.lang.model.element.PackageElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Aggregations

CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)31 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)23 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)18 TypeMirror (javax.lang.model.type.TypeMirror)18 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)11 ArrayList (java.util.ArrayList)11 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)10 ExecutableElement (javax.lang.model.element.ExecutableElement)10 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)9 CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)8 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)8 VariableElement (javax.lang.model.element.VariableElement)8 TypeElement (javax.lang.model.element.TypeElement)6 Arrays (java.util.Arrays)5 CodeTree (com.oracle.truffle.dsl.processor.java.model.CodeTree)4 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)4 Modifier (javax.lang.model.element.Modifier)4 CodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror)3 NodeChildData (com.oracle.truffle.dsl.processor.model.NodeChildData)3 SpecializationGroup (com.oracle.truffle.dsl.processor.parser.SpecializationGroup)3