/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
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;
}
}