Search in sources :

Example 1 with PropertyModel

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

the class LayoutGenerator method generateProperties.

private void generateProperties(final PrintStream stream) {
    for (PropertyModel property : layout.getInstanceProperties()) {
        if (!property.hasIdentifier()) {
            stream.printf("    protected static final HiddenKey %s_IDENTIFIER = new HiddenKey(\"%s\");%n", NameUtils.identifierToConstant(property.getName()), property.getName());
        }
        final List<String> modifiers = new ArrayList<>();
        if (!property.isNullable()) {
            modifiers.add("LocationModifier.NonNull");
        }
        if (property.isFinal()) {
            modifiers.add("LocationModifier.Final");
        }
        final String modifiersExpression;
        if (modifiers.isEmpty()) {
            modifiersExpression = "";
        } else {
            final StringBuilder modifiersExpressionBuilder = new StringBuilder();
            modifiersExpressionBuilder.append(", EnumSet.of(");
            for (String modifier : modifiers) {
                if (!modifier.equals(modifiers.get(0))) {
                    modifiersExpressionBuilder.append(", ");
                }
                modifiersExpressionBuilder.append(modifier);
            }
            modifiersExpressionBuilder.append(")");
            modifiersExpression = modifiersExpressionBuilder.toString();
        }
        final String locationType;
        if (property.isVolatile()) {
            if (property.getType().getKind() == TypeKind.INT) {
                locationType = "AtomicInteger";
            } else if (property.getType().getKind() == TypeKind.BOOLEAN) {
                locationType = "AtomicBoolean";
            } else {
                locationType = "AtomicReference";
            }
        } else {
            locationType = NameUtils.typeWithoutParameters(property.getType().toString());
        }
        stream.printf("    protected static final Property %S_PROPERTY = Property.create(%s_IDENTIFIER, %S_ALLOCATOR.locationForType(%s.class%s), 0);%n", NameUtils.identifierToConstant(property.getName()), NameUtils.identifierToConstant(property.getName()), NameUtils.identifierToConstant(layout.getName()), locationType, modifiersExpression);
        stream.println("    ");
    }
}
Also used : PropertyModel(com.oracle.truffle.object.dsl.processor.model.PropertyModel) ArrayList(java.util.ArrayList)

Example 2 with PropertyModel

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

the class LayoutGenerator method generateImports.

private void generateImports(PrintStream stream) {
    boolean needsAtomicInteger = false;
    boolean needsAtomicBoolean = false;
    boolean needsAtomicReference = false;
    boolean needsIncompatibleLocationException = false;
    boolean needsFinalLocationException = false;
    boolean needsHiddenKey = false;
    boolean needsBoundary = false;
    for (PropertyModel property : layout.getProperties()) {
        if (!property.isShapeProperty() && !property.hasIdentifier()) {
            needsHiddenKey = true;
        }
        if (property.isVolatile()) {
            if (property.getType().getKind() == TypeKind.INT) {
                needsAtomicInteger = true;
            } else if (property.getType().getKind() == TypeKind.BOOLEAN) {
                needsAtomicBoolean = true;
            } else {
                needsAtomicReference = true;
            }
        } else {
            if (property.hasSetter()) {
                if (!property.isShapeProperty()) {
                    needsIncompatibleLocationException = true;
                    needsFinalLocationException = true;
                }
            }
        }
        if (property.isShapeProperty() && (property.hasSetter() || property.hasShapeSetter())) {
            needsBoundary = true;
        }
    }
    if (layout.hasFinalInstanceProperties() || layout.hasNonNullableInstanceProperties()) {
        stream.println("import java.util.EnumSet;");
    }
    if (needsAtomicBoolean) {
        stream.println("import java.util.concurrent.atomic.AtomicBoolean;");
    }
    if (needsAtomicInteger) {
        stream.println("import java.util.concurrent.atomic.AtomicInteger;");
    }
    if (needsAtomicReference) {
        stream.println("import java.util.concurrent.atomic.AtomicReference;");
    }
    if (!layout.hasBuilder()) {
        stream.println("import com.oracle.truffle.api.CompilerAsserts;");
    }
    stream.println("import com.oracle.truffle.api.dsl.GeneratedBy;");
    if (needsBoundary) {
        stream.println("import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;");
    }
    stream.println("import com.oracle.truffle.api.object.DynamicObject;");
    stream.println("import com.oracle.truffle.api.object.DynamicObjectFactory;");
    if (needsFinalLocationException) {
        stream.println("import com.oracle.truffle.api.object.FinalLocationException;");
    }
    if (needsHiddenKey) {
        stream.println("import com.oracle.truffle.api.object.HiddenKey;");
    }
    if (needsIncompatibleLocationException) {
        stream.println("import com.oracle.truffle.api.object.IncompatibleLocationException;");
    }
    if (layout.getSuperLayout() == null) {
        stream.println("import com.oracle.truffle.api.object.Layout;");
    }
    if (layout.hasFinalInstanceProperties() || layout.hasNonNullableInstanceProperties()) {
        stream.println("import com.oracle.truffle.api.object.LocationModifier;");
    }
    stream.println("import com.oracle.truffle.api.object.ObjectType;");
    if (!layout.getInstanceProperties().isEmpty()) {
        stream.println("import com.oracle.truffle.api.object.Property;");
    }
    stream.println("import com.oracle.truffle.api.object.Shape;");
    stream.printf("import %s;%n", layout.getInterfaceFullName());
    if (layout.getSuperLayout() != null) {
        stream.printf("import %s.%sLayoutImpl;%n", layout.getSuperLayout().getPackageName(), layout.getSuperLayout().getName());
    }
}
Also used : PropertyModel(com.oracle.truffle.object.dsl.processor.model.PropertyModel)

Example 3 with PropertyModel

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

the class LayoutGenerator method generateAccessors.

private void generateAccessors(final PrintStream stream) {
    for (PropertyModel property : layout.getProperties()) {
        if (property.hasObjectTypeGetter()) {
            stream.println("    @Override");
            stream.printf("    public %s %s(ObjectType objectType) {%n", property.getType(), NameUtils.asGetter(property.getName()));
            stream.printf("        assert is%s(objectType);%n", layout.getName());
            stream.printf("        return ((%sType) objectType).%s();%n", layout.getName(), NameUtils.asGetter(property.getName()));
            stream.println("    }");
            stream.println("    ");
        }
        if (property.hasShapeGetter()) {
            stream.println("    @Override");
            stream.printf("    public %s %s(DynamicObjectFactory factory) {%n", property.getType(), NameUtils.asGetter(property.getName()));
            stream.printf("        assert creates%s(factory);%n", layout.getName());
            stream.printf("        return ((%sType) factory.getShape().getObjectType()).%s();%n", layout.getName(), NameUtils.asGetter(property.getName()));
            stream.println("    }");
            stream.println("    ");
        }
        if (property.hasGetter()) {
            addUncheckedCastWarning(stream, property);
            stream.println("    @Override");
            stream.printf("    public %s %s(DynamicObject object) {%n", property.getType(), NameUtils.asGetter(property.getName()));
            stream.printf("        assert is%s(object);%n", layout.getName());
            if (property.isShapeProperty()) {
                stream.printf("        return getObjectType(object).%s();%n", NameUtils.asGetter(property.getName()));
            } else {
                stream.printf("        assert object.getShape().hasProperty(%s_IDENTIFIER);%n", NameUtils.identifierToConstant(property.getName()));
                stream.println("        ");
                if (property.isVolatile()) {
                    if (property.getType().getKind() == TypeKind.INT) {
                        stream.printf("        return ((AtomicInteger) %s_PROPERTY.get(object, is%s(object))).get();%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
                    } else if (property.getType().getKind() == TypeKind.BOOLEAN) {
                        stream.printf("        return ((AtomicBoolean) %s_PROPERTY.get(object, is%s(object))).get();%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
                    } else {
                        stream.printf("        return ((AtomicReference<%s>) %s_PROPERTY.get(object, is%s(object))).get();%n", property.getType(), NameUtils.identifierToConstant(property.getName()), layout.getName());
                    }
                } else {
                    stream.printf("        return %s%s_PROPERTY.get(object, is%s(object));%n", cast(property.getType()), NameUtils.identifierToConstant(property.getName()), layout.getName());
                }
            }
            stream.println("    }");
            stream.println("    ");
        }
        if (property.hasShapeSetter()) {
            stream.println("    @TruffleBoundary");
            stream.println("    @Override");
            stream.printf("    public DynamicObjectFactory %s(DynamicObjectFactory factory, %s value) {%n", NameUtils.asSetter(property.getName()), property.getType());
            stream.printf("        assert creates%s(factory);%n", layout.getName());
            stream.println("        final Shape shape = factory.getShape();");
            stream.printf("        return shape.changeType(((%sType) shape.getObjectType()).%s(value)).createFactory();%n", layout.getName(), NameUtils.asSetter(property.getName()));
            stream.println("    }");
            stream.println("    ");
        }
        if (property.hasSetter() || property.hasUnsafeSetter()) {
            addUncheckedCastWarning(stream, property);
            if (property.isShapeProperty()) {
                stream.println("    @TruffleBoundary");
            }
            stream.println("    @Override");
            final String methodNameSuffix;
            if (property.hasUnsafeSetter()) {
                methodNameSuffix = "Unsafe";
            } else {
                methodNameSuffix = "";
            }
            stream.printf("    public void %s%s(DynamicObject object, %s value) {%n", NameUtils.asSetter(property.getName()), methodNameSuffix, property.getType());
            stream.printf("        assert is%s(object);%n", layout.getName());
            if (property.isShapeProperty()) {
                stream.println("        final Shape shape = object.getShape();");
                stream.printf("        object.setShapeAndGrow(shape, shape.changeType(getObjectType(object).%s(value)));%n", NameUtils.asSetter(property.getName()));
            } else {
                stream.printf("        assert object.getShape().hasProperty(%s_IDENTIFIER);%n", NameUtils.identifierToConstant(property.getName()));
                if (!property.getType().getKind().isPrimitive() && !property.isNullable()) {
                    stream.println("        assert value != null;");
                }
                stream.println("        ");
                if (property.hasUnsafeSetter()) {
                    stream.printf("        %s_PROPERTY.setInternal(object, value);%n", NameUtils.identifierToConstant(property.getName()));
                } else if (property.isVolatile()) {
                    if (property.getType().getKind() == TypeKind.INT) {
                        stream.printf("        ((AtomicInteger) %s_PROPERTY.get(object, is%s(object))).set(value);%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
                    } else if (property.getType().getKind() == TypeKind.BOOLEAN) {
                        stream.printf("        ((AtomicBoolean) %s_PROPERTY.get(object, is%s(object))).set(value);%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
                    } else {
                        stream.printf("        ((AtomicReference<%s>) %s_PROPERTY.get(object, is%s(object))).set(value);%n", property.getType(), NameUtils.identifierToConstant(property.getName()), layout.getName());
                    }
                } else {
                    stream.printf("        try {%n");
                    stream.printf("            %s_PROPERTY.set(object, value, object.getShape());%n", NameUtils.identifierToConstant(property.getName()));
                    stream.printf("        } catch (IncompatibleLocationException | FinalLocationException e) {%n");
                    stream.printf("            throw new UnsupportedOperationException(e);%n");
                    stream.printf("        }%n");
                }
            }
            stream.println("    }");
            stream.println("    ");
        }
        if (property.hasCompareAndSet()) {
            addUncheckedCastWarning(stream, property);
            stream.println("    @Override");
            stream.printf("    public boolean %s(DynamicObject object, %s expected_value, %s value) {%n", NameUtils.asCompareAndSet(property.getName()), property.getType(), property.getType());
            stream.printf("        assert is%s(object);%n", layout.getName());
            stream.printf("        assert object.getShape().hasProperty(%s_IDENTIFIER);%n", NameUtils.identifierToConstant(property.getName()));
            if (!property.getType().getKind().isPrimitive() && !property.isNullable()) {
                stream.println("        assert value != null;");
            }
            if (property.getType().getKind() == TypeKind.INT) {
                stream.printf("        return ((AtomicInteger) %s_PROPERTY.get(object, is%s(object))).compareAndSet(expected_value, value);%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
            } else if (property.getType().getKind() == TypeKind.BOOLEAN) {
                stream.printf("        return ((AtomicBoolean) %s_PROPERTY.get(object, is%s(object))).compareAndSet(expected_value, value);%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
            } else {
                stream.printf("        return ((AtomicReference<%s>) %s_PROPERTY.get(object, is%s(object))).compareAndSet(expected_value, value);%n", property.getType(), NameUtils.identifierToConstant(property.getName()), layout.getName());
            }
            stream.println("    }");
            stream.println("    ");
        }
        if (property.hasGetAndSet()) {
            addUncheckedCastWarning(stream, property);
            stream.println("    @Override");
            stream.printf("    public %s %s(DynamicObject object, %s value) {%n", property.getType(), NameUtils.asGetAndSet(property.getName()), property.getType());
            stream.printf("        assert is%s(object);%n", layout.getName());
            stream.printf("        assert object.getShape().hasProperty(%s_IDENTIFIER);%n", NameUtils.identifierToConstant(property.getName()));
            if (!property.getType().getKind().isPrimitive() && !property.isNullable()) {
                stream.println("        assert value != null;");
            }
            if (property.getType().getKind() == TypeKind.INT) {
                stream.printf("        return ((AtomicInteger) %s_PROPERTY.get(object, is%s(object))).getAndSet(value);%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
            } else if (property.getType().getKind() == TypeKind.BOOLEAN) {
                stream.printf("        return ((AtomicBoolean) %s_PROPERTY.get(object, is%s(object))).getAndSet(value);%n", NameUtils.identifierToConstant(property.getName()), layout.getName());
            } else {
                stream.printf("        return ((AtomicReference<%s>) %s_PROPERTY.get(object, is%s(object))).getAndSet(value);%n", property.getType(), NameUtils.identifierToConstant(property.getName()), layout.getName());
            }
            stream.println("    }");
            stream.println("    ");
        }
    }
    if (!layout.getShapeProperties().isEmpty()) {
        stream.print("    private");
        if (!layout.hasObjectTypeGuard()) {
            stream.print(" static");
        }
        stream.printf(" %sType getObjectType(DynamicObject object) {%n", layout.getName());
        stream.printf("        assert is%s(object);%n", layout.getName());
        stream.printf("        return (%sType) object.getShape().getObjectType();%n", layout.getName());
        stream.println("    }");
        stream.println("    ");
    }
}
Also used : PropertyModel(com.oracle.truffle.object.dsl.processor.model.PropertyModel)

Example 4 with PropertyModel

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

the class LayoutGenerator method generateObjectType.

private void generateObjectType(final PrintStream stream) {
    final String typeSuperclass;
    if (layout.getSuperLayout() == null) {
        typeSuperclass = layout.getObjectTypeSuperclass().toString();
    } else {
        typeSuperclass = layout.getSuperLayout().getName() + "LayoutImpl." + layout.getSuperLayout().getName() + "Type";
    }
    stream.printf("    public static class %sType extends %s {%n", layout.getName(), typeSuperclass);
    if (layout.hasShapeProperties()) {
        stream.println("        ");
        for (PropertyModel property : layout.getShapeProperties()) {
            stream.printf("        protected final %s %s;%n", property.getType(), property.getName());
        }
        if (!layout.getShapeProperties().isEmpty()) {
            stream.println("        ");
        }
        stream.printf("        public %sType(%n", layout.getName());
        iterateProperties(layout.getAllShapeProperties(), new PropertyIteratorAction() {

            @Override
            public void run(PropertyModel property, boolean last) {
                stream.printf("                %s %s", property.getType().toString(), property.getName());
                if (last) {
                    stream.println(") {");
                } else {
                    stream.println(",");
                }
            }
        });
        if (!layout.getInheritedShapeProperties().isEmpty()) {
            stream.println("            super(");
            iterateProperties(layout.getInheritedShapeProperties(), new PropertyIteratorAction() {

                @Override
                public void run(PropertyModel property, boolean last) {
                    stream.printf("                %s", property.getName());
                    if (last) {
                        stream.println(");");
                    } else {
                        stream.println(",");
                    }
                }
            });
        }
        iterateProperties(layout.getShapeProperties(), new PropertyIteratorAction() {

            @Override
            public void run(PropertyModel property, boolean last) {
                stream.printf("            this.%s = %s;%n", property.getName(), property.getName());
            }
        });
        stream.println("        }");
        stream.println("        ");
        for (PropertyModel property : layout.getAllShapeProperties()) {
            final boolean inherited = !layout.getShapeProperties().contains(property);
            if (!inherited) {
                stream.printf("        public %s %s() {%n", property.getType(), NameUtils.asGetter(property.getName()));
                stream.printf("            return %s;%n", property.getName());
                stream.println("        }");
                stream.println("        ");
            }
            if (inherited) {
                stream.println("        @Override");
            }
            stream.printf("        public %sType %s(%s %s) {%n", layout.getName(), NameUtils.asSetter(property.getName()), property.getType(), property.getName());
            stream.printf("            return new %sType(%n", layout.getName());
            iterateProperties(layout.getAllShapeProperties(), new PropertyIteratorAction() {

                @Override
                public void run(PropertyModel p, boolean last) {
                    stream.printf("                %s", p.getName());
                    if (last) {
                        stream.println(");");
                    } else {
                        stream.println(",");
                    }
                }
            });
            stream.println("        }");
            stream.println("        ");
        }
    } else {
        stream.println("        ");
    }
    stream.println("    }");
    stream.println("    ");
}
Also used : PropertyModel(com.oracle.truffle.object.dsl.processor.model.PropertyModel)

Example 5 with PropertyModel

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

the class LayoutParser method checkSharedParameters.

private void checkSharedParameters(Element element, List<? extends VariableElement> parameters, List<PropertyModel> sharedProperties) {
    if (parameters.size() < sharedProperties.size()) {
        processor.reportError(element, "@Layout constructor cannot have less parameters than the super layout constructor " + parameters + " " + sharedProperties);
    }
    for (int n = 0; n < sharedProperties.size(); n++) {
        final VariableElement parameter = parameters.get(n);
        final String parameterName = parameter.getSimpleName().toString();
        final PropertyModel superLayoutProperty = sharedProperties.get(n);
        if (superLayoutProperty.hasGeneratedName()) {
            // Assume the name is right if we cannot check it during incremental compilation
            superLayoutProperty.fixName(parameterName);
        }
        if (!parameterName.equals(superLayoutProperty.getName())) {
            processor.reportError(element, "@Layout constructor parameter %d needs to have the same name as the super layout constructor (is %s, should be %s)", n, parameter.getSimpleName(), superLayoutProperty.getName());
        }
        if (!isSameType(parameter.asType(), superLayoutProperty.getType())) {
            processor.reportError(element, "@Layout constructor parameter %d needs to have the same type as the super layout constructor (is %s, should be %s)", n, parameter.asType(), superLayoutProperty.getType());
        }
    }
}
Also used : PropertyModel(com.oracle.truffle.object.dsl.processor.model.PropertyModel) VariableElement(javax.lang.model.element.VariableElement)

Aggregations

PropertyModel (com.oracle.truffle.object.dsl.processor.model.PropertyModel)10 VariableElement (javax.lang.model.element.VariableElement)3 PropertyBuilder (com.oracle.truffle.object.dsl.processor.model.PropertyBuilder)2 ArrayList (java.util.ArrayList)2 Layout (com.oracle.truffle.api.object.Layout)1