MemoryRegion.avt

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

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

    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 }); }
}