FieldsMap.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Компилятор языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package ru.malik.elaborarer.avtoo.lang;

public final class FieldsMap(Object, Cloneable)
{
    public static final int MIN_FIELD_WIDTH = 0x01;
    public static final int MAX_FIELD_WIDTH = 0x40;

    private boolean fldFinalized;
    private long[] fldBitMap;

    public () { fldBitMap = new long[0x10]; }

    private (long[] bitMap) {
        if(bitMap == null)
        {
            fldBitMap = new long[0x10];
            return;
        }
        int length = bitMap.length;
        Array.copy(bitMap, 0, fldBitMap = new long[length], 0, length);
    }

    public FieldsMap clone() { return new FieldsMap(fldBitMap); }

    public void finalize() { fldFinalized = true; }

    public int allocateDwordAlignedField(int fieldWidthInBytes) { return allocateAlignedField(fieldWidthInBytes, 0x04); }

    public int allocateQwordAlignedField(int fieldWidthInBytes) { return allocateAlignedField(fieldWidthInBytes, 0x08); }

    public int allocateXwordAlignedField(int fieldWidthInBytes) { return allocateAlignedField(fieldWidthInBytes, 0x10); }

    public int allocateYwordAlignedField(int fieldWidthInBytes) { return allocateAlignedField(fieldWidthInBytes, 0x20); }

    public int allocateZwordAlignedField(int fieldWidthInBytes) { return allocateAlignedField(fieldWidthInBytes, 0x40); }

    public boolean finalized { read = fldFinalized }

    private int allocateAlignedField(int fieldWidthInBytes, int align) {
        if(fldFinalized)
        {
            throw new IllegalFieldsMapStateException(package.getResourceString("fields-map.finalized"));
        }
        if(fieldWidthInBytes < MIN_FIELD_WIDTH || fieldWidthInBytes > MAX_FIELD_WIDTH)
        {
            throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "fieldWidthInBytes" }));
        }
        int fieldWidthInDwords = (fieldWidthInBytes + (-fieldWidthInBytes & (align - 1))) >> 2;
        long mask = (1 << fieldWidthInDwords) - 1;
        long[] bitMap = fldBitMap;
        int length = bitMap.length;
        int index = Array.indexOfNon(-1, bitMap, 0, length);
        if(index >= 0) for(long subMap = bitMap[index], int limit = 0x41 - fieldWidthInDwords, int step = align >> 2, int shift = 0; shift < limit; shift += step) if((subMap & mask << shift) == 0)
        {
            bitMap[index] = subMap | mask << shift;
            return index << 8 | shift << 2;
        }
        if(length >= 0x00800000)
        {
            throw new IllegalFieldsMapStateException(package.getResourceString("fields-map.full"));
        }
        Array.copy(bitMap, 0, fldBitMap = bitMap = new long[length << 1], 0, length);
        bitMap[length] = mask;
        return length << 8;
    }
}