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