Runtime.avt

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

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

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

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

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

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

package avt.lang;

import avt.security.*;
import platform.dependent.*;
import platform.independent.filesystem.*;

public abstract class Runtime(Object)
{
    private static Runtime instance;

    public static Runtime getInstance() { return instance; }

    protected static void construct(Runtime instance) {
        if(Runtime.instance != null)
        {
            throw new SecurityException(package.getResourceString("security.runtime.caller"));
        }
        instance.defaultConstructor();
        instance.afterConstruction();
    }

    protected static void destruct(CallerSecurityContext context) {
        if(context == null)
        {
            checkCaller(Thread.callerTypeTrace());
        } else
        {
            checkCaller(context);
        }
        instance.beforeDestruction();
    }

    protected static void constructInstance(Object instance, CallerSecurityContext context) {
        if(Runtime.instance != null)
        {
            if(context == null)
            {
                checkCaller(Thread.callerTypeTrace());
            } else
            {
                checkCaller(context);
            }
        }
        if(!instance.getClass().isArray())
        {
            instance.defaultConstructor();
            instance.afterConstruction();
        }
    }

    protected static void destructInstance(Object instance, CallerSecurityContext context) {
        if(Runtime.instance != null)
        {
            if(context == null)
            {
                checkCaller(Thread.callerTypeTrace());
            } else
            {
                checkCaller(context);
            }
        }
        if(!instance.getClass().isArray())
        {
            instance.beforeDestruction();
        }
    }

    protected static void invokeBeforeDestruction(long instancePointer, CallerSecurityContext context) {
        if(context == null)
        {
            checkCaller(Thread.callerTypeTrace());
        } else
        {
            checkCaller(context);
        }
        Object instance = toInstance(instancePointer);
        if(!instance.getClass().isArray())
        {
            try
            {
                instance.beforeDestruction();
            }
            catch(Throwable exception) {  }
        }
    }

    protected static native void addOtherRefInInstance(Object instance, CallerSecurityContext context);

    protected static native void releaseRefsInInstance(long instancePointer, CallerSecurityContext context);

    protected static boolean isIntersectRegions(long2 region1Pointers, long2 region2Pointers) {
        return Long2.max(region1Pointers, region2Pointers)[0] < Long2.min(region1Pointers, region2Pointers)[1];
    }

    protected static native long toPointer(Object instance);

    protected static native long refsFromInstance(long instancePointer, long targetPointer, CallerSecurityContext context);

    protected static native long2 refsToInstance(long instancePointer, CallerSecurityContext context);

    protected static native long2 toMemoryRegionPointers(long pointer, long size);

    protected static native long2 toMemoryRegionPointers(Object instance, long size);

    protected static native Object initializeInstance(long instancePointer, Class type, long size, int length, CallerSecurityContext context);

    private static void checkCaller(CallerSecurityContext context) { context.checkSameType(instance.getClass()); }

    private static void checkCaller(Class callerType) {
        if(callerType != instance.getClass())
        {
            throw new SecurityException(package.getResourceString("security.caller"));
        }
    }

    private static native int readProcessorBrandString(byte[] dst);

    private static native long2 getProgrammeCodeRegionPointers();

    private static native long2 getProgrammeDataRegionPointers();

    private static native Object toInstance(long instancePointer);

    private boolean fldMultiThreaded;
    private long fldCollectedBytes;
    private GarbageCollectorThread fldGarbageCollectorThread;
    private final Mutex fldSystemOperation;
    private final String fldProcessorBrandString;
    private final Object fldGarbageCollectorMonitor;

    protected () {
        if(instance != null)
        {
            throw new SecurityException(package.getResourceString("security.runtime.construct"));
        }
        instance = this;
        String.initialize();
        byte[] processorBrandStringBytes = new byte[48];
        int processorBrandStringLength = readProcessorBrandString(processorBrandStringBytes);
        char[] processorBrandStringChars = new char[processorBrandStringLength];
        for(int index = processorBrandStringLength; index-- > 0; ) processorBrandStringChars[index] = (char) (processorBrandStringBytes[index] & 0xff);
        fldSystemOperation = newMutex();
        fldProcessorBrandString = new String(processorBrandStringChars, 0, processorBrandStringLength);
        fldGarbageCollectorMonitor = new Object();
    }

    public abstract long freeMemory();

    public abstract long totalMemory();

    public void exit(int exitCode) {
        throw new SecurityException(package.getResourceString("security.runtime.exit"));
    }

    public final void gc() {
        synchronized with(fldGarbageCollectorMonitor)
        {
            notify();
        }
    }

    public final long collectedBytes() { return fldCollectedBytes; }

    protected abstract void collectGarbage();

    protected abstract void throwOutOfMemoryError();

    protected abstract void startThreadId(long threadId);

    protected abstract void setThreadIdPriority(long threadId, int priority);

    protected abstract boolean isAliveThreadId(long threadId);

    protected abstract int getThreadIdPriority(long threadId);

    protected abstract int activeThreadsCount();

    protected abstract long newThreadId(Thread reference);

    protected abstract long currentThreadId();

    protected abstract long[] activeThreadsIds();

    protected abstract Event newEvent(long threadId);

    protected abstract Mutex newMutex();

    protected abstract Monitor newMonitor();

    protected abstract Object allocateInstance(Class type, long size, int length, boolean executable);

    protected void yieldThread() {  }

    protected void nowMultiThreaded() {  }

    protected boolean isCanonicalPointer(long pointer) {
        return pointer >= 0xffff800000000000L && pointer <= 0x00007fffffffffffL;
    }

    protected boolean isProtectedMemory(long2 regionPointers) {
        return isIntersectRegions(getProgrammeCodeRegionPointers(), regionPointers) || isIntersectRegions(getProgrammeDataRegionPointers(), regionPointers);
    }

    protected final void afterConstruction() {
        Thread.initialize();
        with((Thread) (fldGarbageCollectorThread = new GarbageCollectorThread(fldGarbageCollectorMonitor)))
        {
            priority = MIN_PRIORITY;
            start();
        }
    }

    protected final void beforeDestruction() {
        GarbageCollectorThread garbageCollectorThread = fldGarbageCollectorThread;
        if(garbageCollectorThread != null) garbageCollectorThread.terminate();
    }

    protected final void modCollectedBytes(long deltaCollectedBytes) {
        fldCollectedBytes += deltaCollectedBytes;
    }

    protected final boolean isTerminated() {
        GarbageCollectorThread garbageCollectorThread = fldGarbageCollectorThread;
        return garbageCollectorThread != null && garbageCollectorThread.fldTerminated;
    }

    protected abstract int processorNumberOfCores { read }

    protected abstract TimeBase timeBase { read }

    protected abstract FileSystem localFileSystem { read }

    protected abstract String operatingSystemName { read }

    protected abstract String operatingSystemVersion { read }

    protected abstract String entryPointTypeCanonicalName { read }

    protected abstract ProcessEnvironment currentProcessEnvironment { read }

    protected String lineSeparator { read = "\n" }

    protected final boolean multiThreaded { read = fldMultiThreaded }

    protected final int processorCodeBits { read = 64 }

    protected final String processorBrandString { read = fldProcessorBrandString }

    package final void setMultiThreaded() {
        if(!fldMultiThreaded)
        {
            fldMultiThreaded = true;
            nowMultiThreaded();
        }
    }

    package final Mutex systemOperation { read = fldSystemOperation }
}

class GarbageCollectorThread(Thread)
{
    boolean fldTerminated;
    private boolean fldLaunched;
    private final Object fldGarbageCollectorMonitor;

    public (Object garbageCollectorMonitor) {
        fldGarbageCollectorMonitor = garbageCollectorMonitor;
    }

    public void run() {
        if(!fldLaunched)
        {
            fldLaunched = true;
            try
            {
                Runtime runtime = Runtime.getInstance();
                do
                {
                    Thread.clean();
                    String.clean();
                    runtime.collectGarbage();
                    pause();
                } while(!fldTerminated);
            }
            catch(Exception exception)
            {
                exception.printStackTrace();
            }
        }
    }

    public void interruptio() {
        throw new SecurityException(package.getResourceString("security.thread.interruptio.gc"));
    }

    public void terminate() {
        synchronized with(fldGarbageCollectorMonitor)
        {
            fldTerminated = true;
            notify();
        }
        if(Thread.current() != this)
        {
            try
            {
                join();
            }
            catch(Exception exception) {  }
        }
    }

    private void pause() throws InterruptedException {
        synchronized with(fldGarbageCollectorMonitor)
        {
            wait(6000L);
        }
    }
}