attempts at fixing multithread functionstack/garbage collector issues
This commit is contained in:
parent
57ed698463
commit
a161775ea6
1 changed files with 641 additions and 642 deletions
|
@ -3,6 +3,7 @@ import java.lang.reflect.*;
|
|||
import java.net.BindException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -35,7 +36,7 @@ public class ISBPL {
|
|||
ArrayList<String> included = new ArrayList<>();
|
||||
HashMap<String, ISBPLCallable> natives = new HashMap<>();
|
||||
|
||||
private Object syncMakeThread = new Object();
|
||||
private final Object syncMakeThread = new Object();
|
||||
private ISBPLKeyword getKeyword(String word) {
|
||||
switch (word) {
|
||||
case "native":
|
||||
|
@ -51,7 +52,7 @@ public class ISBPL {
|
|||
idx++;
|
||||
Object var = new Object();
|
||||
ISBPLCallable c;
|
||||
vars.put(var, new ISBPLObject(getType("null"), 0));
|
||||
vars.put(var, getNullObject());
|
||||
addFunction(words[idx], c = ((stack1) -> stack1.push(vars.get(var))));
|
||||
addFunction("=" + words[idx], (stack1) -> vars.put(var, stack1.pop()));
|
||||
varLinks.put(c, var);
|
||||
|
@ -165,20 +166,16 @@ public class ISBPL {
|
|||
synchronized(syncMakeThread) {
|
||||
idx++;
|
||||
AtomicInteger i = new AtomicInteger(idx);
|
||||
Stack<ISBPLObject> s = new Stack<>();
|
||||
Stack<ISBPLObject> s = new ISBPLStack<>();
|
||||
for(ISBPLObject obj : stack) {
|
||||
s.push(obj);
|
||||
}
|
||||
ISBPLCallable block = readBlock(i, words, file, false);
|
||||
// This cant be a non-function, unless we clone vars aswell to avoid garbage collecting them accidentally.
|
||||
ISBPLCallable block = readBlock(i, words, file, true);
|
||||
long tid = Thread.currentThread().getId();
|
||||
Stack<HashMap<String, ISBPLCallable>> fs = new Stack<>();
|
||||
for(HashMap<String, ISBPLCallable> map : functionStack.get()) {
|
||||
fs.push(map);
|
||||
}
|
||||
new Thread(() -> {
|
||||
debuggerIPC.run.put(Thread.currentThread().getId(), debuggerIPC.run.getOrDefault(tid, -1) == -1 ? -1 : 0);
|
||||
debuggerIPC.stack.put(Thread.currentThread().getId(), s);
|
||||
functionStack.set(fs);
|
||||
try {
|
||||
block.call(s);
|
||||
} catch (ISBPLStop stop) {
|
||||
|
@ -231,7 +228,7 @@ public class ISBPL {
|
|||
i.checkType(getType("int"));
|
||||
ISBPLObject[] arr = new ISBPLObject[((int) i.object)];
|
||||
for (int j = 0 ; j < arr.length ; j++) {
|
||||
arr[j] = new ISBPLObject(getType("null"), 0);
|
||||
arr[j] = getNullObject();
|
||||
}
|
||||
stack.push(new ISBPLObject(getType("array"), arr));
|
||||
};
|
||||
|
@ -395,8 +392,7 @@ public class ISBPL {
|
|||
end.checkType(getType("int"));
|
||||
begin.checkType(getType("int"));
|
||||
fileToRead.checkType(getType("file"));
|
||||
try {
|
||||
FileInputStream f = new FileInputStream((File) fileToRead.object);
|
||||
try(FileInputStream f = new FileInputStream((File) fileToRead.object)) {
|
||||
int b = ((int) begin.object);
|
||||
int e = ((int) end.object);
|
||||
byte[] bytes = new byte[e - b];
|
||||
|
@ -972,7 +968,7 @@ public class ISBPL {
|
|||
return nullObj;
|
||||
}
|
||||
|
||||
private Object syncJIOClass = new Object();
|
||||
private final Object syncJIOClass = new Object();
|
||||
public ISBPLObject toISBPL(Class<?> clazz) {
|
||||
synchronized(syncJIOClass) {
|
||||
ISBPLType type = getType(clazz.getName());
|
||||
|
@ -1123,27 +1119,6 @@ public class ISBPL {
|
|||
return params[mid.get()];
|
||||
}
|
||||
|
||||
private Object syncFromISBPL = new Object();
|
||||
private Object fromISBPL(ISBPLObject o) {
|
||||
synchronized(syncFromISBPL) {
|
||||
ISBPLType type = o.type;
|
||||
if (type.equals(getType("null"))) {
|
||||
return null;
|
||||
}
|
||||
if (type.equals(getType("string")))
|
||||
return toJavaString(o);
|
||||
if (type.equals(getType("array"))) {
|
||||
ISBPLObject[] isbplArray = ((ISBPLObject[]) o.object);
|
||||
Object[] array = new Object[isbplArray.length];
|
||||
for (int i = 0 ; i < array.length ; i++) {
|
||||
array[i] = fromISBPL(isbplArray[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
return o.object;
|
||||
}
|
||||
}
|
||||
|
||||
public Object primitiveDefault(Class<?> expectedType) {
|
||||
if(expectedType == long.class)
|
||||
return 0L;
|
||||
|
@ -1165,7 +1140,6 @@ public class ISBPL {
|
|||
}
|
||||
|
||||
public Object fromISBPL(ISBPLObject o, Class<?> expectedType) {
|
||||
synchronized(syncFromISBPL) {
|
||||
ISBPLType type = o.type;
|
||||
if (type.equals(getType("null"))) {
|
||||
return null;
|
||||
|
@ -1211,13 +1185,10 @@ public class ISBPL {
|
|||
typeError(o.type.name, expectedType.getName());
|
||||
return o.object;
|
||||
}
|
||||
}
|
||||
|
||||
private Object syncToISBPL = new Object();
|
||||
public ISBPLObject toISBPL(Object object) {
|
||||
synchronized (syncToISBPL) {
|
||||
if(object == null) {
|
||||
return new ISBPLObject(getType("null"), 0);
|
||||
return getNullObject();
|
||||
}
|
||||
ISBPLObject o = toISBPL(object.getClass());
|
||||
if (object instanceof String) {
|
||||
|
@ -1246,7 +1217,6 @@ public class ISBPL {
|
|||
o.object = object;
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
public void addFunction(ISBPLType type, String name, ISBPLCallable callable) {
|
||||
type.methods.put(name, callable);
|
||||
|
@ -1407,6 +1377,14 @@ public class ISBPL {
|
|||
}
|
||||
if(stack.size() > 0) {
|
||||
// Doing this nonrecursively because it's much better despite the slight readability disadvantage.
|
||||
if(stack.peek() == null) {
|
||||
// We need to dump things immediately.
|
||||
System.err.println("!!! ISBPL WORD PARSER ERROR !!!");
|
||||
System.err.println("This is most likely due to a garbage collector malfunction.");
|
||||
System.err.println("Stack: " + stack);
|
||||
System.err.println("LastWords: " + lastWords);
|
||||
System.err.println("FileStack: " + fileStack);
|
||||
}
|
||||
ISBPLType type = stack.peek().type;
|
||||
Queue<ISBPLType> types = new LinkedList<>();
|
||||
types.add(type);
|
||||
|
@ -1462,9 +1440,12 @@ public class ISBPL {
|
|||
finally {
|
||||
if(isFunction) {
|
||||
HashMap<String, ISBPLCallable> fstack = functionStack.get().pop();
|
||||
for(ISBPLCallable c : fstack.values()) {
|
||||
if(varLinks.containsKey(c)) {
|
||||
vars.remove(varLinks.remove(c));
|
||||
for(Map.Entry<String, ISBPLCallable> c : fstack.entrySet()) {
|
||||
if(varLinks.containsKey(c.getValue())) {
|
||||
vars.remove(varLinks.remove(c.getValue()));
|
||||
if(printCalls) {
|
||||
System.err.println("Garbage collector: removed " + c.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1533,7 +1514,7 @@ public class ISBPL {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Stack<ISBPLObject> stack = new Stack<>();
|
||||
Stack<ISBPLObject> stack = new ISBPLStack<>();
|
||||
ISBPL isbpl = new ISBPL();
|
||||
isbpl.debuggerIPC.stack.put(Thread.currentThread().getId(), stack);
|
||||
debug = !System.getenv().getOrDefault("DEBUG", "").equals("");
|
||||
|
@ -1566,6 +1547,7 @@ public class ISBPL {
|
|||
}
|
||||
|
||||
private static String readFile(File f) throws IOException {
|
||||
//noinspection resource
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
byte[] currentBytes = new byte[4096];
|
||||
|
@ -1637,7 +1619,7 @@ class ISBPLObject {
|
|||
}
|
||||
|
||||
public boolean isTruthy() {
|
||||
return object != null && object != Integer.valueOf(0) && !object.equals(Boolean.valueOf(false));
|
||||
return object != null && object != Integer.valueOf(0) && !object.equals(Boolean.FALSE);
|
||||
}
|
||||
|
||||
// This has heavy optimizations, please do not change unless necessary
|
||||
|
@ -1802,6 +1784,7 @@ class ISBPLDebugger extends Thread {
|
|||
try {
|
||||
ServerSocket socket = null;
|
||||
try {
|
||||
//noinspection resource
|
||||
socket = new ServerSocket(Integer.parseInt(System.getenv().getOrDefault("DEBUG", "9736")));
|
||||
port = socket.getLocalPort();
|
||||
System.err.println("Debugger listening on :" + socket.getLocalPort());
|
||||
|
@ -1809,6 +1792,7 @@ class ISBPLDebugger extends Thread {
|
|||
catch (BindException e) {
|
||||
while (socket == null) {
|
||||
try {
|
||||
//noinspection resource
|
||||
socket = new ServerSocket((int) (Math.random() * 5000 + 5000));
|
||||
port = socket.getLocalPort();
|
||||
System.err.println("Debugger listening on :" + socket.getLocalPort());
|
||||
|
@ -2033,7 +2017,7 @@ class ISBPLStreamer {
|
|||
s = stack.pop();
|
||||
s.checkType(isbpl.getType("string"));
|
||||
f = new File(isbpl.toJavaString(s));
|
||||
stream = new ISBPLStream(new FileInputStream(f), new OutputStream() {
|
||||
stream = new ISBPLStream(Files.newInputStream(f.toPath()), new OutputStream() {
|
||||
@Override
|
||||
public void write(int b) {
|
||||
throw new ISBPLError("IllegalArgument", "Can't write to a FILE_IN stream!");
|
||||
|
@ -2051,7 +2035,7 @@ class ISBPLStreamer {
|
|||
public int read() {
|
||||
throw new ISBPLError("IllegalArgument", "Can't read a FILE_OUT stream!");
|
||||
}
|
||||
}, new FileOutputStream(f));
|
||||
}, Files.newOutputStream(f.toPath()));
|
||||
streams.add(stream);
|
||||
stack.push(new ISBPLObject(isbpl.getType("int"), stream.id));
|
||||
break;
|
||||
|
@ -2143,4 +2127,19 @@ class ISBPLThreadLocal<T> {
|
|||
public synchronized void set(T t) {
|
||||
map.put(Thread.currentThread().getId(), t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return get().toString();
|
||||
}
|
||||
}
|
||||
|
||||
class ISBPLStack<T> extends Stack<T> {
|
||||
|
||||
@Override
|
||||
public T push(T t) {
|
||||
//if(t == null)
|
||||
//throw new IllegalArgumentException("item is null");
|
||||
return super.push(t);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue