All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.qbicc.plugin.layout.ObjectAccessLoweringBuilder Maven / Gradle / Ivy

package org.qbicc.plugin.layout;

import org.qbicc.context.CompilationContext;
import org.qbicc.graph.BasicBlockBuilder;
import org.qbicc.graph.DelegatingBasicBlockBuilder;
import org.qbicc.graph.Value;
import org.qbicc.graph.ValueHandle;
import org.qbicc.graph.ValueHandleVisitor;
import org.qbicc.plugin.coreclasses.CoreClasses;
import org.qbicc.type.ArrayObjectType;
import org.qbicc.type.CompoundType;
import org.qbicc.type.ObjectType;
import org.qbicc.type.PhysicalObjectType;
import org.qbicc.type.PointerType;
import org.qbicc.type.ReferenceArrayObjectType;
import org.qbicc.type.ReferenceType;
import org.qbicc.type.UnsignedIntegerType;
import org.qbicc.type.ValueType;
import org.qbicc.type.WordType;
import org.qbicc.type.definition.element.FieldElement;

/**
 *
 */
public class ObjectAccessLoweringBuilder extends DelegatingBasicBlockBuilder implements ValueHandleVisitor {
    private final CompilationContext ctxt;

    public ObjectAccessLoweringBuilder(final CompilationContext ctxt, final BasicBlockBuilder delegate) {
        super(delegate);
        this.ctxt = ctxt;
    }

    @Override
    public ValueHandle pointerHandle(Value pointer, Value offsetValue) {
        BasicBlockBuilder fb = getFirstBuilder();
        PointerType pointerType = (PointerType) pointer.getType();
        if (pointerType.getPointeeType() instanceof PhysicalObjectType pot) {
            Layout layout = Layout.get(ctxt);
            LayoutInfo info = layout.getInstanceLayoutInfo(pot.getDefinition());
            return fb.pointerHandle(fb.valueConvert(pointer, info.getCompoundType().getPointer().asCollected()));
        }
        return getDelegate().pointerHandle(pointer, offsetValue);
    }

    @Override
    public Value valueConvert(Value value, WordType toType) {
        if (toType instanceof PointerType pt) {
            if (pt.getPointeeType() instanceof PhysicalObjectType pot) {
                BasicBlockBuilder fb = getFirstBuilder();
                Layout layout = Layout.get(ctxt);
                LayoutInfo info = layout.getInstanceLayoutInfo(pot.getDefinition());
                PointerType newType = info.getCompoundType().getPointer().asCollected();
                if (value.getType() instanceof PointerType) {
                    return fb.bitCast(value, newType);
                } else {
                    return fb.valueConvert(value, newType);
                }
            }
        }
        return getDelegate().valueConvert(value, toType);
    }

    @Override
    public Value stackAllocate(ValueType type, Value count, Value align) {
        if (type instanceof PhysicalObjectType pot) {
            BasicBlockBuilder fb = getFirstBuilder();
            Layout layout = Layout.get(ctxt);
            LayoutInfo info = layout.getInstanceLayoutInfo(pot.getDefinition());
            PointerType newType = info.getCompoundType().getPointer().asCollected();
            return fb.stackAllocate(newType, count, align);
        }
        return super.stackAllocate(type, count, align);
    }

    public ValueHandle elementOf(ValueHandle array, Value index) {
        if (array.getValueType() instanceof CompoundType ct && ct.getMemberCount() > 0) {
            // ElementOf a CompoundType -> ElementOf the last Member
            CompoundType.Member lastMember = ct.getMember(ct.getMemberCount() - 1);
            BasicBlockBuilder fb = getFirstBuilder();
            return fb.elementOf(fb.memberOf(array, lastMember), index);
        }
        return getDelegate().elementOf(array, index);
    }

    @Override
    public ValueHandle referenceHandle(Value reference) {
        BasicBlockBuilder fb = getFirstBuilder();
        // convert reference to pointer
        Layout layout = Layout.get(ctxt);
        ReferenceType referenceType = (ReferenceType) reference.getType();
        ObjectType upperBound = referenceType.getUpperBound();
        LayoutInfo info;
        if (upperBound instanceof ReferenceArrayObjectType raot) {
            info = layout.getArrayLayoutInfo(CoreClasses.get(ctxt).getArrayContentField(upperBound).getEnclosingType(), raot.getElementObjectType());
        } else if (upperBound instanceof ArrayObjectType) {
            info = layout.getInstanceLayoutInfo(CoreClasses.get(ctxt).getArrayContentField(upperBound).getEnclosingType());
        } else {
            info = layout.getInstanceLayoutInfo(upperBound.getDefinition());
        }
        return fb.pointerHandle(fb.valueConvert(reference, info.getCompoundType().getPointer().asCollected()));
    }

    @Override
    public ValueHandle instanceFieldOf(ValueHandle instance, FieldElement field) {
        BasicBlockBuilder fb = getFirstBuilder();
        Layout layout = Layout.get(ctxt);
        LayoutInfo layoutInfo = layout.getInstanceLayoutInfo(field.getEnclosingType());
        return fb.memberOf(instance, layoutInfo.getMember(field));
    }

    @Override
    public ValueHandle unsafeHandle(ValueHandle base, Value offset, ValueType outputType) {
        BasicBlockBuilder fb = getFirstBuilder();
        UnsignedIntegerType u8 = ctxt.getTypeSystem().getUnsignedInteger8Type();
        ValueHandle valueHandle = fb.pointerHandle(fb.bitCast(fb.addressOf(base), u8.getPointer()), offset);
        return fb.pointerHandle(fb.bitCast(fb.addressOf(valueHandle), outputType.getPointer()));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy