(doesn't work) while trying to improve GC speed and arrays, made it extremely slow and buggy. will fix later.

This commit is contained in:
Daniella / Tove 2022-06-30 23:49:35 +02:00
parent 9cb05aa2bc
commit 5f4bfd3de7
2 changed files with 367 additions and 118 deletions

View file

@ -36,7 +36,7 @@ public class ISBPL {
public static PrintStream gErrorStream = System.err; public static PrintStream gErrorStream = System.err;
static boolean debug = false, printCalls = false; static boolean debug = false, printCalls = false;
public ISBPLDebugger.IPC debuggerIPC = new ISBPLDebugger.IPC(); public static ISBPLDebugger.IPC debuggerIPC = new ISBPLDebugger.IPC();
ArrayList<ISBPLType> types = new ArrayList<>(); ArrayList<ISBPLType> types = new ArrayList<>();
ISBPLFrame level0 = new ISBPLFrame("isbpl", this); ISBPLFrame level0 = new ISBPLFrame("isbpl", this);
final ISBPLThreadLocal<Stack<File>> fileStack = ISBPLThreadLocal.withInitial(Stack::new); final ISBPLThreadLocal<Stack<File>> fileStack = ISBPLThreadLocal.withInitial(Stack::new);
@ -132,10 +132,10 @@ public class ISBPL {
allowed = new String[] { toJavaString(array) }; allowed = new String[] { toJavaString(array) };
} }
else { else {
ISBPLObject[] arr = ((ISBPLObject[]) array.object); ISBPLArray arr = ((ISBPLArray) array.object);
allowed = new String[arr.length]; allowed = new String[arr.length];
for (int i = 0 ; i < arr.length ; i++) { for (int i = 0 ; i < arr.length ; i++) {
allowed[i] = toJavaString(arr[i]); allowed[i] = toJavaString(arr.get(i));
} }
} }
AtomicInteger i = new AtomicInteger(idx); AtomicInteger i = new AtomicInteger(idx);
@ -336,7 +336,7 @@ public class ISBPL {
func = (ISBPLStack<ISBPLObject> stack) -> { func = (ISBPLStack<ISBPLObject> stack) -> {
ISBPLObject o = stack.pop(); ISBPLObject o = stack.pop();
o.checkType(getType("array")); o.checkType(getType("array"));
stack.push(new ISBPLObject(getType("int"), ((ISBPLObject[]) o.object).length)); stack.push(new ISBPLObject(getType("int"), ((ISBPLArray) o.object).length));
}; };
break; break;
case "aget": case "aget":
@ -345,7 +345,7 @@ public class ISBPL {
ISBPLObject o = stack.pop(); ISBPLObject o = stack.pop();
i.checkType(getType("int")); i.checkType(getType("int"));
o.checkType(getType("array")); o.checkType(getType("array"));
stack.push(((ISBPLObject[]) o.object)[((int) i.object)]); stack.push(((ISBPLArray) o.object).get(((int) i.object)));
}; };
break; break;
case "aput": case "aput":
@ -355,22 +355,14 @@ public class ISBPL {
ISBPLObject o = stack.pop(); ISBPLObject o = stack.pop();
i.checkType(getType("int")); i.checkType(getType("int"));
o.checkType(getType("array")); o.checkType(getType("array"));
((ISBPLObject[]) o.object)[((int) i.object)].unusedBy(o); ((ISBPLArray) o.object).set(((int) i.object), toPut);
toPut.usedBy(o);
((ISBPLObject[]) o.object)[((int) i.object)] = toPut;
}; };
break; break;
case "anew": case "anew":
func = (ISBPLStack<ISBPLObject> stack) -> { func = (ISBPLStack<ISBPLObject> stack) -> {
ISBPLObject i = stack.pop(); ISBPLObject i = stack.pop();
i.checkType(getType("int")); i.checkType(getType("int"));
ISBPLObject[] arr = new ISBPLObject[((int) i.object)]; stack.push(new ISBPLObject(getType("array"), new ISBPLArray(((int) i.object), getNullObject())));
ISBPLObject it = new ISBPLObject(getType("array"), arr);
for (int j = 0 ; j < arr.length ; j++) {
arr[j] = getNullObject();
arr[j].usedBy(it);
}
stack.push(it);
}; };
break; break;
case "acopy": case "acopy":
@ -382,15 +374,14 @@ public class ISBPL {
ISBPLObject arr1 = stack.pop(); ISBPLObject arr1 = stack.pop();
arr1.checkType(getType("array")); arr1.checkType(getType("array"));
arr2.checkType(getType("array")); arr2.checkType(getType("array"));
ISBPLObject[] o1 = (ISBPLObject[]) arr1.object; ISBPLArray o1 = (ISBPLArray) arr1.object;
ISBPLObject[] o2 = (ISBPLObject[]) arr2.object; ISBPLArray o2 = (ISBPLArray) arr2.object;
for(int i = (int) idx1.toLong(); i < (int) idx1.toLong() + (int) len.toLong(); i++) { int idx1_ = (int) idx1.toLong();
o1[i].usedBy(arr2); int idx2_ = (int) idx2.toLong();
int len_ = (int) len.toLong();
for(int i1 = idx1_, i2 = idx2_; i1 < idx1_ + len_ && i1 < o1.length && i2 < o2.length; i1++, i2++) {
o2.set(i2, o1.get(i1));
} }
for(int i = (int) idx2.toLong(); i < (int) idx2.toLong() + (int) len.toLong(); i++) {
o2[i].unusedBy(arr2);
}
System.arraycopy(o1, (int) idx1.toLong(), o2, (int) idx2.toLong(), (int) len.toLong());
stack.push(arr2); stack.push(arr2);
}; };
break; break;
@ -399,13 +390,8 @@ public class ISBPL {
ISBPLObject a = stack.pop(); ISBPLObject a = stack.pop();
if(a.type.equals(getType("array"))) if(a.type.equals(getType("array")))
stack.push(a); stack.push(a);
else if(a.object instanceof ISBPLObject[]) { else if(a.object instanceof ISBPLArray) {
ISBPLObject[] o = (ISBPLObject[]) a.object; stack.push(new ISBPLObject(getType("array"), a.object));
ISBPLObject it = new ISBPLObject(getType("array"), a.object);
for(int i = 0; i < o.length; i++) {
o[i].usedBy(it);
}
stack.push(it);
} else } else
typeError(a.type.name, "array"); typeError(a.type.name, "array");
}; };
@ -568,9 +554,9 @@ public class ISBPL {
int e = ((int) end.object); int e = ((int) end.object);
byte[] bytes = new byte[e - b]; byte[] bytes = new byte[e - b];
f.read(bytes, b, e); f.read(bytes, b, e);
ISBPLObject[] arr = new ISBPLObject[bytes.length]; ISBPLArray arr = new ISBPLArray(bytes.length, getNullObject());
for (int i = 0 ; i < arr.length ; i++) { for (int i = 0 ; i < arr.length ; i++) {
arr[i] = new ISBPLObject(getType("byte"), bytes[i]); arr.set(i, new ISBPLObject(getType("byte"), bytes[i]));
} }
stack.push(new ISBPLObject(getType("array"), arr)); stack.push(new ISBPLObject(getType("array"), arr));
} }
@ -633,6 +619,7 @@ public class ISBPL {
ISBPLObject i = stack.pop(); ISBPLObject i = stack.pop();
ISBPLObject o = stack.pop(); ISBPLObject o = stack.pop();
i.checkType(getType("int")); i.checkType(getType("int"));
// TODO fix: o.object relocation if array
stack.push(new ISBPLObject(types.get(((int) i.object)), o.object)); stack.push(new ISBPLObject(types.get(((int) i.object)), o.object));
}; };
break; break;
@ -1029,7 +1016,7 @@ public class ISBPL {
break; break;
case "_getvars": case "_getvars":
func = (ISBPLStack<ISBPLObject> stack) -> { func = (ISBPLStack<ISBPLObject> stack) -> {
ISBPLObject[] objects = new ISBPLObject[frameStack.get().size()]; ISBPLArray objects = new ISBPLArray(frameStack.get().size(), getNullObject());
int i = 0; int i = 0;
for (ISBPLFrame map : frameStack.get()) { for (ISBPLFrame map : frameStack.get()) {
ArrayList<ISBPLObject> strings = new ArrayList<>(); ArrayList<ISBPLObject> strings = new ArrayList<>();
@ -1038,10 +1025,9 @@ public class ISBPL {
strings.add(toISBPLString(key.substring(1))); strings.add(toISBPLString(key.substring(1)));
} }
} }
objects[i++] = new ISBPLObject(getType("array"), strings.toArray(new ISBPLObject[0])); objects.set(i++, new ISBPLObject(getType("array"), new ISBPLArray(strings.toArray(new ISBPLObject[0]))));
} }
ISBPLObject array = new ISBPLObject(getType("array"), objects); stack.push(new ISBPLObject(getType("array"), objects));
stack.push(array);
}; };
break; break;
case "stacksize": case "stacksize":
@ -1198,7 +1184,7 @@ public class ISBPL {
error.checkType(getType("error")); error.checkType(getType("error"));
Throwable t = (Throwable) error.object; Throwable t = (Throwable) error.object;
Stack<ISBPLFrame> frames = stackTraces.get(t); Stack<ISBPLFrame> frames = stackTraces.get(t);
ISBPLObject[] array = new ISBPLObject[frames.size()]; ISBPLArray array = new ISBPLArray(frames.size(), getNullObject());
for(int i = 0; i < frames.size(); i++) { for(int i = 0; i < frames.size(); i++) {
ISBPLFrame frame = frames.get(i); ISBPLFrame frame = frames.get(i);
ArrayList<ISBPLObject> arr = new ArrayList<>(); ArrayList<ISBPLObject> arr = new ArrayList<>();
@ -1206,7 +1192,7 @@ public class ISBPL {
arr.add(toISBPLString(frame.name)); arr.add(toISBPLString(frame.name));
frame = frame.parent; frame = frame.parent;
} }
array[i] = new ISBPLObject(getType("array"), arr.toArray(new ISBPLObject[0])); array.set(i, new ISBPLObject(getType("array"), arr.toArray(new ISBPLObject[0])));
} }
stack.push(new ISBPLObject(getType("array"), array)); stack.push(new ISBPLObject(getType("array"), array));
}; };
@ -1437,14 +1423,14 @@ public class ISBPL {
typeError("string", expectedType.getName()); typeError("string", expectedType.getName());
} }
if (type.equals(getType("array"))) { if (type.equals(getType("array"))) {
ISBPLObject[] isbplArray = ((ISBPLObject[]) o.object); ISBPLArray isbplArray = ((ISBPLArray) o.object);
Object array = new Object[isbplArray.length]; Object array = new Object[isbplArray.length];
if(expectedType.isArray()) if(expectedType.isArray())
array = Array.newInstance(expectedType.getComponentType(), isbplArray.length); array = Array.newInstance(expectedType.getComponentType(), isbplArray.length);
else else
typeError("array", "matching-array"); typeError("array", "matching-array");
for (int i = 0 ; i < isbplArray.length ; i++) { for (int i = 0 ; i < isbplArray.length ; i++) {
Object obj = fromISBPL(isbplArray[i], expectedType.getComponentType()); Object obj = fromISBPL(isbplArray.get(i), expectedType.getComponentType());
Array.set(array, i, obj == null && expectedType.getComponentType().isPrimitive() ? primitiveDefault(expectedType.getComponentType()) : obj); Array.set(array, i, obj == null && expectedType.getComponentType().isPrimitive() ? primitiveDefault(expectedType.getComponentType()) : obj);
} }
return array; return array;
@ -1498,9 +1484,9 @@ public class ISBPL {
if (object instanceof Double) if (object instanceof Double)
return new ISBPLObject(getType("double"), object); return new ISBPLObject(getType("double"), object);
if (object.getClass().isArray()) { if (object.getClass().isArray()) {
ISBPLObject[] isbplArray = new ISBPLObject[Array.getLength(object)]; ISBPLArray isbplArray = new ISBPLArray(Array.getLength(object), getNullObject());
for (int i = 0 ; i < isbplArray.length ; i++) { for (int i = 0 ; i < isbplArray.length ; i++) {
isbplArray[i] = toISBPL(Array.get(object, i)); isbplArray.set(i, toISBPL(Array.get(object, i)));
} }
o.type = getType("array"); o.type = getType("array");
object = isbplArray; object = isbplArray;
@ -1585,20 +1571,24 @@ public class ISBPL {
public String toJavaString(ISBPLObject string) { public String toJavaString(ISBPLObject string) {
string.checkType(getType("string")); string.checkType(getType("string"));
ISBPLObject[] array = ((ISBPLObject[]) string.object); ISBPLArray array = ((ISBPLArray) string.object);
char[] chars = new char[array.length]; char[] chars = new char[array.length];
for (int i = 0 ; i < array.length ; i++) { try {
chars[i] = ((char) array[i].object); for (int i = 0 ; i < array.length ; i++) {
chars[i] = ((char) array.get(i).object);
}
} catch(NullPointerException e) {
throw new IllegalStateException(string + " has null-chars.");
} }
return new String(chars); return new String(chars);
} }
public ISBPLObject toISBPLString(String s) { public ISBPLObject toISBPLString(String s) {
char[] chars = s.toCharArray(); char[] chars = s.toCharArray();
ISBPLObject[] objects = new ISBPLObject[chars.length]; ISBPLArray objects = new ISBPLArray(chars.length, getNullObject());
ISBPLType type = getType("char"); ISBPLType type = getType("char");
for (int i = 0 ; i < chars.length ; i++) { for (int i = 0 ; i < chars.length ; i++) {
objects[i] = new ISBPLObject(type, chars[i]); objects.set(i, new ISBPLObject(type, chars[i]));
} }
return new ISBPLObject(getType("string"), objects); return new ISBPLObject(getType("string"), objects);
} }
@ -1707,7 +1697,7 @@ public class ISBPL {
ISBPL.gErrorStream.println("LastWords: " + lastWords); ISBPL.gErrorStream.println("LastWords: " + lastWords);
ISBPL.gErrorStream.println("FileStack: " + fileStack); ISBPL.gErrorStream.println("FileStack: " + fileStack);
ISBPL.gErrorStream.println("Stack: " + stack); ISBPL.gErrorStream.println("Stack: " + stack);
System.exit(1); throw new Error("ISBPL WORD PARSER");
} }
try { try {
ISBPLType type = stack.peek().type; ISBPLType type = stack.peek().type;
@ -1737,7 +1727,7 @@ public class ISBPL {
ISBPL.gErrorStream.println("LastWords: " + lastWords); ISBPL.gErrorStream.println("LastWords: " + lastWords);
ISBPL.gErrorStream.println("FileStack: " + fileStack); ISBPL.gErrorStream.println("FileStack: " + fileStack);
ISBPL.gErrorStream.println("Stack: " + stack); ISBPL.gErrorStream.println("Stack: " + stack);
System.exit(1); throw new Error("ISBPL WORD PARSER");
} }
} }
ISBPLCallable func = frameStack.get().peek().resolve(word); ISBPLCallable func = frameStack.get().peek().resolve(word);
@ -1980,9 +1970,9 @@ public class ISBPL {
} }
private static ISBPLObject argarray(ISBPL isbpl, String[] args) { private static ISBPLObject argarray(ISBPL isbpl, String[] args) {
ISBPLObject[] array = new ISBPLObject[args.length - 1]; ISBPLArray array = new ISBPLArray(args.length - 1, null);
for (int i = 1 ; i < args.length ; i++) { for (int i = 1 ; i < args.length ; i++) {
array[i - 1] = isbpl.toISBPLString(args[i]); array.set(i - 1, isbpl.toISBPLString(args[i]));
} }
return new ISBPLObject(isbpl.getType("array"), array); return new ISBPLObject(isbpl.getType("array"), array);
} }
@ -2026,9 +2016,182 @@ public class ISBPL {
} }
} }
class ISBPLFastList<T> {
private final LinkedList<T>[] items;
private final int[] lengths;
private final int cap;
private int size = 0;
public ISBPLFastList(int hashcap) {
cap = hashcap;
items = new LinkedList[hashcap];
lengths = new int[hashcap];
for(int i = 0; i < hashcap; i++) {
items[i] = new LinkedList<>();
lengths[i] = 0;
}
}
public boolean contains(T item) {
return items[Math.abs(item.hashCode() % cap)].contains(item);
}
public void add(T item) {
int i = Math.abs(item.hashCode() % cap);
items[i].add(item);
lengths[i]++;
size++;
}
public T get(int i) {
int n = 0; // end of current scope
int x = 0; // start of current scope
int l = 0; // scope
for(; l < cap; l++) {
n += lengths[l];
if(n > i) // if end of current scope is bigger than i (that means i is within current scope)
break;
x += lengths[l];
}
return items[l].get(i - x);
}
public LinkedList<T> getByHash(int hash) {
return items[Math.abs(hash % cap)];
}
public T set(int i, T item) {
int n = 0; // end of current scope
int x = 0; // start of current scope
int l = 0; // scope
for(; l < cap; l++) {
n += lengths[l];
if(n > i) // if end of current scope is bigger than i (that means i is within current scope)
break;
x += lengths[l];
}
return items[l].set(i - x, item);
}
public T[] toArray(T... in) {
T[] ts = (T[]) Array.newInstance(in.getClass().getComponentType(), size);
for(int i = 0, scope = 0, idx = 0; i < size && scope < cap; i++, idx++) {
while(idx == lengths[scope]) {
idx = 0;
scope++;
}
ts[i] = items[scope].get(idx);
}
return ts;
}
public T remove(int i) {
int n = 0; // end of current scope
int x = 0; // start of current scope
int l = 0; // scope
for(; l < cap; l++) {
n += lengths[l];
if(n > i) // if end of current scope is bigger than i (that means i is within current scope)
break;
x += lengths[l];
}
T it = items[l].remove(i - x);
lengths[l]--;
size--;
return it;
}
public boolean remove(T item) {
int i = Math.abs(item.hashCode() % cap);
if(items[i].remove(item)) {
lengths[i]--;
size--;
return true;
}
return false;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
}
class ISBPLInstanceMap<T, O> {
ISBPLFastList<Pair<T, O>> pairs = new ISBPLFastList<>(32);
private static class Pair<T, O> {
T t;
O o;
public Pair(T t, O o) {
this.t = t;
this.o = o;
}
@Override
public int hashCode() { return t.hashCode(); }
}
public O get(T t) {
LinkedList<Pair<T, O>> list = pairs.getByHash(t.hashCode());
for(int i = 0; i < list.size(); i++) {
// instance map, use strict equal!
if(list.get(i).t == t) {
return list.get(i).o;
}
}
return null;
}
public O put(T t, O o) {
LinkedList<Pair<T, O>> list = pairs.getByHash(t.hashCode());
for(int i = 0; i < list.size(); i++) {
// instance map, use strict equal!
if(list.get(i).t == t) {
O r = list.get(i).o;
list.get(i).o = o;
return r;
}
}
list.add(new Pair<>(t, o));
return null;
}
public boolean containsKey(T t) {
return get(t) != null;
}
public boolean remove(T t) {
LinkedList<Pair<T, O>> list = pairs.getByHash(t.hashCode());
for(int i = 0; i < list.size(); i++) {
// instance map, use strict equal!
if(list.get(i).t == t) {
O r = list.get(i).o;
list.remove(i);
return true;
}
}
return false;
}
public boolean removeValue(O o) {
for(int i = 0; i < pairs.size(); i++) {
// instance map, use strict equal!
if(pairs.get(i).o == o) {
T r = pairs.get(i).t;
pairs.remove(i);
return true;
}
}
return false;
}
}
interface ISBPLUsable { interface ISBPLUsable {
static HashMap<ISBPLUsable, Integer> uses = new HashMap<>(); static ISBPLInstanceMap<ISBPLUsable, Integer> uses = new ISBPLInstanceMap<>();
static HashMap<ISBPLUsable, ArrayList<ISBPLUsable>> children = new HashMap<>(); static ISBPLInstanceMap<ISBPLUsable, ISBPLFastList<ISBPLUsable>> children = new ISBPLInstanceMap<>();
default void usedBy(ISBPLUsable other) { default void usedBy(ISBPLUsable other) {
@ -2037,8 +2200,8 @@ interface ISBPLUsable {
} }
default void unusedBy(ISBPLUsable other) { default void unusedBy(ISBPLUsable other) {
if(!other.isUseless()) if(!other.isUseless())
other.removeChild(this); if(other.removeChild(this))
removeUse(); removeUse();
} }
default void addUse() { default void addUse() {
setUses(getUses() + 1); setUses(getUses() + 1);
@ -2053,11 +2216,11 @@ interface ISBPLUsable {
if(ISBPL.debug) { if(ISBPL.debug) {
ISBPL.gErrorStream.println("Garbage collecting " + this); ISBPL.gErrorStream.println("Garbage collecting " + this);
} }
ArrayList<ISBPLUsable> usables = getChildren(); ISBPLFastList<ISBPLUsable> usables = getChildren();
for(int i = 0; i < usables.size(); i++) { ISBPLUsable[] arr = usables.toArray();
usables.get(i).unusedBy(this); for(int i = 0; i < arr.length; i++) {
arr[i].unusedBy(this);
} }
ISBPL.uncollected++;
useless(); useless();
uses.remove(this); uses.remove(this);
children.remove(this); children.remove(this);
@ -2073,22 +2236,23 @@ interface ISBPLUsable {
uses.put(this, 0); uses.put(this, 0);
return uses.get(this); return uses.get(this);
} }
default ArrayList<ISBPLUsable> getChildren() { default ISBPLFastList<ISBPLUsable> getChildren() {
if(!children.containsKey(this)) if(!children.containsKey(this))
children.put(this, new ArrayList<>()); children.put(this, new ISBPLFastList<>(8));
return children.get(this); return children.get(this);
} }
default void addChild(ISBPLUsable it) { default void addChild(ISBPLUsable it) {
getChildren().add(it); getChildren().add(it);
} }
default void removeChild(ISBPLUsable it) { default boolean removeChild(ISBPLUsable it) {
getChildren().remove(it); return getChildren().remove(it);
} }
default boolean isUseless() { default boolean isUseless() {
return !children.containsKey(this); return !children.containsKey(this);
} }
default void useless() {} default void useless() {}
} }
interface ISBPLKeyword { interface ISBPLKeyword {
@ -2111,17 +2275,6 @@ class ISBPLType implements ISBPLUsable {
this.id = id; this.id = id;
} }
@Override
protected void finalize() throws Throwable {
ISBPL.uncollected--;
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
public void useless() { public void useless() {
id = -100; id = -100;
name = null; name = null;
@ -2170,6 +2323,86 @@ class ISBPLType implements ISBPLUsable {
} }
return false; return false;
} }
protected void finalize() throws Throwable {
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
}
class ISBPLArray implements ISBPLUsable {
private ISBPLObject[] backend;
public int length;
public ISBPLArray(ISBPLObject[] back) {
this.length = back.length;
backend = back;
for(int i = 0; i < length; i++) {
backend[i].usedBy(this);
}
}
public ISBPLArray(int length, ISBPLObject initial) {
this.length = length;
backend = new ISBPLObject[length];
for(int i = 0; i < length; i++) {
backend[i] = initial;
if(initial != null)
initial.usedBy(this);
}
}
public void set(int i, ISBPLObject item) {
item.usedBy(this);
if(backend[i] != null)
backend[i].unusedBy(this);
backend[i] = item;
}
public ISBPLObject get(int i) {
return backend[i];
}
public String toString() {
StringBuilder s = new StringBuilder("[");
for(int i = 0; i < length; i++) {
s.append(backend[i]);
if(i != length - 1) {
s.append(", ");
}
}
s.append("]");
return s.toString();
}
public boolean equals(Object o) {
if(this == o) return true;
if(!(o instanceof ISBPLArray)) return false;
ISBPLArray object = (ISBPLArray) o;
if(object.length != length) return false;
for(int i = 0; i < length; i++) {
if(!object.backend[i].equals(backend[i])) return false;
}
return true;
}
public void useless() {
backend = null;
length = -1;
}
protected void finalize() throws Throwable {
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
} }
class ISBPLObject implements ISBPLUsable { class ISBPLObject implements ISBPLUsable {
@ -2185,17 +2418,6 @@ class ISBPLObject implements ISBPLUsable {
} }
} }
@Override
protected void finalize() throws Throwable {
ISBPL.uncollected--;
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
public void useless() { public void useless() {
type.vars.remove(this); type.vars.remove(this);
object = null; object = null;
@ -2224,18 +2446,16 @@ class ISBPLObject implements ISBPLUsable {
return false; return false;
if(object.object == null) if(object.object == null)
return false; return false;
if(this.object.getClass().isArray() || object.object.getClass().isArray()) {
if(this.object.getClass().isArray() && object.object.getClass().isArray()) {
return Arrays.equals((Object[]) this.object, (Object[]) object.object);
}
else {
return false;
}
}
return this.object.equals(object.object); return this.object.equals(object.object);
} }
public void checkType(ISBPLType wanted) { public void checkType(ISBPLType wanted) {
if(type == null) {
throw new IllegalStateException("ISBPLObject was checked for its type, but the object has already been garbage-collected.");
}
if(wanted == null) {
throw new IllegalArgumentException("ISBPLObject was checked for its type with the wanted type being null.");
}
Queue<ISBPLType> types = new LinkedList<>(); Queue<ISBPLType> types = new LinkedList<>();
types.add(type); types.add(type);
while (!types.isEmpty()) { while (!types.isEmpty()) {
@ -2249,6 +2469,9 @@ class ISBPLObject implements ISBPLUsable {
} }
public void checkTypeMulti(ISBPLType... wanted) { public void checkTypeMulti(ISBPLType... wanted) {
if(type == null) {
throw new IllegalStateException("ISBPLObject was checked for its type, but the object has already been garbage-collected.");
}
StringBuilder wantedNames = new StringBuilder(); StringBuilder wantedNames = new StringBuilder();
for (int i = 0 ; i < wanted.length ; i++) { for (int i = 0 ; i < wanted.length ; i++) {
wantedNames.append(" ").append(wanted[i].name); wantedNames.append(" ").append(wanted[i].name);
@ -2267,16 +2490,6 @@ class ISBPLObject implements ISBPLUsable {
@Override @Override
public String toString() { public String toString() {
if(type != null && object instanceof ISBPLObject[]) {
try {
return "ISBPLObject{" +
"type=" + type +
", object=" + Arrays.toString(((ISBPLObject[]) object)) +
'}';
} catch (Exception e) {
e.printStackTrace();
}
}
return "ISBPLObject{" + return "ISBPLObject{" +
"type=" + type + "type=" + type +
", object=" + object + ", object=" + object +
@ -2342,6 +2555,15 @@ class ISBPLObject implements ISBPLUsable {
} }
throw new ISBPLError("InvalidArgument", "This type of number can't be negated!"); throw new ISBPLError("InvalidArgument", "This type of number can't be negated!");
} }
protected void finalize() throws Throwable {
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
} }
class ISBPLError extends RuntimeException { class ISBPLError extends RuntimeException {
@ -2740,20 +2962,38 @@ class ISBPLThreadLocal<T> {
class ISBPLStack<T extends ISBPLUsable> extends Stack<T> implements ISBPLUsable { class ISBPLStack<T extends ISBPLUsable> extends Stack<T> implements ISBPLUsable {
final ArrayList<T> toBeMarked = new ArrayList<>(); final ISBPLFastList<T> toBeMarked = new ISBPLFastList<>(3);
@Override @Override
public T push(T t) { public T push(T t) {
if(t == null) if(t == null)
new IllegalArgumentException("item is null").printStackTrace(); new IllegalArgumentException("item is null").printStackTrace();
if(t.isUseless()) {
throw new IllegalStateException("item was garbage-collected (" + t + ")");
}
if(t instanceof ISBPLObject && ((ISBPLObject) t).type == null) {
throw new IllegalStateException("item was garbage-collected (" + t + ") but was not marked");
}
t.usedBy(this); t.usedBy(this);
return super.push(t); return super.push(t);
} }
@Override
public T peek() {
T t = super.peek();
if(t.isUseless()) {
throw new IllegalStateException("item was garbage-collected (" + t + ") WHILE ON STACK!");
}
return t;
}
@Override @Override
public T pop() { public T pop() {
T t = super.pop(); T t = super.pop();
toBeMarked.add(t); toBeMarked.add(t);
if(t.isUseless()) {
throw new IllegalStateException("item was garbage-collected (" + t + ") WHILE ON STACK!");
}
return t; return t;
} }
@ -2767,6 +3007,15 @@ class ISBPLStack<T extends ISBPLUsable> extends Stack<T> implements ISBPLUsable
toBeMarked.remove(0); toBeMarked.remove(0);
} }
} }
protected void finalize() throws Throwable {
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
} }
class ISBPLFrame implements ISBPLUsable { class ISBPLFrame implements ISBPLUsable {
@ -2789,17 +3038,6 @@ class ISBPLFrame implements ISBPLUsable {
parentFrame.usedBy(this); parentFrame.usedBy(this);
} }
@Override
protected void finalize() throws Throwable {
ISBPL.uncollected--;
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
public void useless() { public void useless() {
context = null; context = null;
if(map != null) if(map != null)
@ -2834,15 +3072,18 @@ class ISBPLFrame implements ISBPLUsable {
} }
public void define(String name, ISBPLObject value) { public void define(String name, ISBPLObject value) {
value.usedBy(this);
Object var = new Object(); Object var = new Object();
variables.put(var, value); ISBPLObject old = variables.put(var, value);
if(old != null) {
old.unusedBy(this);
}
add(name, (stack) -> stack.push(variables.get(var))); add(name, (stack) -> stack.push(variables.get(var)));
add("=" + name, (stack) -> { add("=" + name, (stack) -> {
ISBPLObject o = stack.pop(); ISBPLObject o = stack.pop();
o.usedBy(this); o.usedBy(this);
variables.put(var, o).unusedBy(this); variables.put(var, o).unusedBy(this);
}); });
value.usedBy(this);
} }
public HashMap<String, ISBPLCallable> all() { public HashMap<String, ISBPLCallable> all() {
@ -2850,4 +3091,13 @@ class ISBPLFrame implements ISBPLUsable {
r.putAll(map); r.putAll(map);
return r; return r;
} }
protected void finalize() throws Throwable {
if(!isUseless())
ISBPL.gErrorStream.println("[ISBPL] [Please report] JVM GC'd " + this + ", but it was not picked up by ISBPL's GC!");
if(ISBPL.debug) {
ISBPL.gErrorStream.println("JVM deleting " + this);
}
super.finalize();
}
} }

View file

@ -1,7 +1,6 @@
"Brainfuck->ISBPL transpiler" # "Brainfuck->ISBPL transpiler" #
native acopy
"#stream.isbpl" include "#stream.isbpl" include
"#multi.isbpl" include "#multi.isbpl" include