/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024, 2026 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package platform.independent.osservices;
import platform.dependent.*;
public final class MemoryRegion(Object, ImmutableObject, RawData)
{
public static final int NO_ACCESS = 0x00;
public static final int READABLE = 0x01;
public static final int WRITEABLE = 0x02;
public static final int EXECUTABLE = 0x04;
public static final int SHARED = 0x08;
public static final int RESERVED = 0x10;
public static final int DOWN = 0x20;
public static final long PAGE_SIZE = 0x1000;
public static void deallocate(MemoryRegion region, int flags) {
if(region == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "region" }));
}
PlatformServices.getInstance().deallocateRegion(new long2 { region.address, region.size }, flags);
}
public static MemoryRegion[] enumerate() {
long2[] regions = PlatformServices.getInstance().enumerateRegions();
int length = regions.length;
MemoryRegion[] result = new MemoryRegion[length];
for(int index = 0; index < length; index++) result[index] = new MemoryRegion(regions[index], true);
return result;
}
public static MemoryRegion allocate(long address, long size, int flags) {
long2 region = PlatformServices.getInstance().allocateRegion(new long2 { address, size }, flags);
return new MemoryRegion(region, false);
}
private boolean fldIsImmutable;
private final long fldAddress;
private final long fldSize;
private (long2 region, boolean isImmutable) {
fldIsImmutable = isImmutable;
fldAddress = region[0];
fldSize = region[1];
}
public boolean equals(Object anot) {
if(anot == this) return true;
if(!(anot instanceof MemoryRegion)) return false;
MemoryRegion aobj = (MemoryRegion) anot;
return fldAddress == aobj.fldAddress && fldSize == aobj.fldSize;
}
public long hashCodeAsLong() { return (fldAddress >> 12) ^ Long.rotateLeft(fldSize, 24); }
public long2 hashCodeAsLong2() { return new long2 { fldAddress, fldSize }; }
public String toString() {
return (new StringBuilder()).append(class.canonicalName).
append("@address=").append(Long.toHexString(fldAddress)).
append(",size=").append(Long.toHexString(fldSize)).
toString();
}
public void finalize() { fldIsImmutable = true; }
public boolean isMutable() { return !fldIsImmutable; }
public long getPointer() { return fldAddress; }
public long getLength() { return fldSize; }
public boolean isShared() { return (getProtectionBits() & SHARED) != 0; }
public boolean isReadable() { return (getProtectionBits() & READABLE) != 0; }
public boolean isWriteable() { return (getProtectionBits() & WRITEABLE) != 0; }
public boolean isExecutable() { return (getProtectionBits() & EXECUTABLE) != 0; }
public int protectionBits { read = getProtectionBits, write = setProtectionBits }
public long address { read = fldAddress }
public long size { read = fldSize }
private void setProtectionBits(int newProtectionBits) {
if(fldIsImmutable)
{
throw new ImmutableStateException(avt.lang.package.getResourceString("illegal-state.immutable"));
}
PlatformServices.getInstance().setRegionProtectionBits(new long2 { fldAddress, fldSize }, newProtectionBits);
}
private int getProtectionBits() { return PlatformServices.getInstance().getRegionProtectionBits(new long2 { fldAddress, fldSize }); }
}