diff --git a/src/me/topchetoeu/jscript/Main.java b/src/me/topchetoeu/jscript/Main.java index 4180c06..fe9625e 100644 --- a/src/me/topchetoeu/jscript/Main.java +++ b/src/me/topchetoeu/jscript/Main.java @@ -102,7 +102,7 @@ public class Main { var raw = in.readLine(); if (raw == null) break; - engine.pushMsg(false, new Context(env, new Message(engine)), "", raw, null).toObservable().once(valuePrinter); + engine.pushMsg(false, env.context(new Message(engine)), "", raw, null).toObservable().once(valuePrinter); } catch (EngineException e) { try { diff --git a/src/me/topchetoeu/jscript/engine/Data.java b/src/me/topchetoeu/jscript/engine/Data.java new file mode 100644 index 0000000..49d18b7 --- /dev/null +++ b/src/me/topchetoeu/jscript/engine/Data.java @@ -0,0 +1,58 @@ +package me.topchetoeu.jscript.engine; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +@SuppressWarnings("unchecked") +public class Data implements Iterable, ?>> { + private HashMap, Object> data = new HashMap<>(); + + public Data copy() { + return new Data().addAll(this); + } + + public Data addAll(Iterable, ?>> data) { + for (var el : data) { + add((DataKey)el.getKey(), (Object)el.getValue()); + } + return this; + } + + public Data set(DataKey key, T val) { + if (val == null) data.remove(key); + else data.put((DataKey)key, (Object)val); + return this; + } + public T add(DataKey key, T val) { + if (data.containsKey(key)) return (T)data.get(key); + else { + if (val == null) data.remove(key); + else data.put((DataKey)key, (Object)val); + return val; + } + } + public T get(DataKey key) { + return get(key, null); + } + public T get(DataKey key, T defaultVal) { + if (!has(key)) return defaultVal; + else return (T)data.get(key); + } + public boolean has(DataKey key) { return data.containsKey(key); } + + public Data increase(DataKey key, int n, int start) { + return set(key, get(key, start) + n); + } + public Data increase(DataKey key, int n) { + return increase(key, n, 0); + } + public Data increase(DataKey key) { + return increase(key, 1, 0); + } + + @Override + public Iterator, ?>> iterator() { + return (Iterator, ?>>)data.entrySet(); + } +} diff --git a/src/me/topchetoeu/jscript/engine/DataKey.java b/src/me/topchetoeu/jscript/engine/DataKey.java new file mode 100644 index 0000000..017fa2a --- /dev/null +++ b/src/me/topchetoeu/jscript/engine/DataKey.java @@ -0,0 +1,3 @@ +package me.topchetoeu.jscript.engine; + +public class DataKey { } \ No newline at end of file diff --git a/src/me/topchetoeu/jscript/engine/Engine.java b/src/me/topchetoeu/jscript/engine/Engine.java index aa83065..013b66e 100644 --- a/src/me/topchetoeu/jscript/engine/Engine.java +++ b/src/me/topchetoeu/jscript/engine/Engine.java @@ -11,19 +11,19 @@ public class Engine { private class UncompiledFunction extends FunctionValue { public final String filename; public final String raw; - public final Environment ctx; + public final Environment env; @Override public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { - ctx = new Context(this.ctx, ctx.message); + ctx = ctx.setEnv(env); return ctx.compile(filename, raw).call(ctx, thisArg, args); } - public UncompiledFunction(Environment ctx, String filename, String raw) { + public UncompiledFunction(Environment env, String filename, String raw) { super(filename, 0); this.filename = filename; this.raw = raw; - this.ctx = ctx; + this.env = env; } } @@ -32,10 +32,10 @@ public class Engine { public final Object thisArg; public final Object[] args; public final DataNotifier notifier = new DataNotifier<>(); - public final Message ctx; + public final Message msg; public Task(Message ctx, FunctionValue func, Object thisArg, Object[] args) { - this.ctx = ctx; + this.msg = ctx; this.func = func; this.thisArg = thisArg; this.args = args; @@ -52,7 +52,7 @@ public class Engine { private void runTask(Task task) throws InterruptedException { try { - task.notifier.next(task.func.call(new Context(null, task.ctx), task.thisArg, task.args)); + task.notifier.next(task.func.call(task.msg.context(null), task.thisArg, task.args)); } catch (InterruptedException e) { task.notifier.error(new RuntimeException(e)); diff --git a/src/me/topchetoeu/jscript/engine/Environment.java b/src/me/topchetoeu/jscript/engine/Environment.java index 5821c04..c8136cf 100644 --- a/src/me/topchetoeu/jscript/engine/Environment.java +++ b/src/me/topchetoeu/jscript/engine/Environment.java @@ -15,15 +15,23 @@ import me.topchetoeu.jscript.interop.NativeWrapperProvider; public class Environment { private HashMap prototypes = new HashMap<>(); + + public final Data data = new Data(); + public final HashMap symbols = new HashMap<>(); + public GlobalScope global; public WrappersProvider wrappersProvider; - /** NOTE: This is not the register for Symbol.for, but for the symbols like Symbol.iterator */ - public HashMap symbols = new HashMap<>(); @Native public FunctionValue compile; @Native public FunctionValue regexConstructor = new NativeFunction("RegExp", (ctx, thisArg, args) -> { throw EngineException.ofError("Regular expressions not supported.").setContext(ctx); }); + + public Environment addData(Data data) { + this.data.addAll(data); + return this; + } + @Native public ObjectValue proto(String name) { return prototypes.get(name); } diff --git a/src/me/topchetoeu/jscript/engine/Message.java b/src/me/topchetoeu/jscript/engine/Message.java index 974893f..b61f522 100644 --- a/src/me/topchetoeu/jscript/engine/Message.java +++ b/src/me/topchetoeu/jscript/engine/Message.java @@ -13,8 +13,15 @@ public class Message { private final ArrayList frames = new ArrayList<>(); public int maxStackFrames = 1000; + public final Data data = new Data(); + public List frames() { return Collections.unmodifiableList(frames); } + public Message addData(Data data) { + this.data.addAll(data); + return this; + } + public Message pushFrame(Context ctx, CodeFrame frame) throws InterruptedException { this.frames.add(frame); if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!"); diff --git a/src/me/topchetoeu/jscript/engine/values/CodeFunction.java b/src/me/topchetoeu/jscript/engine/values/CodeFunction.java index 0b34425..c0025b3 100644 --- a/src/me/topchetoeu/jscript/engine/values/CodeFunction.java +++ b/src/me/topchetoeu/jscript/engine/values/CodeFunction.java @@ -29,7 +29,7 @@ public class CodeFunction extends FunctionValue { @Override public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { - return new CodeFrame(ctx, thisArg, args, this).run(new Context(environment, ctx.message)); + return new CodeFrame(ctx, thisArg, args, this).run(ctx.setEnv(environment)); } public CodeFunction(Environment environment, String name, int localsN, int length, ValueVariable[] captures, Instruction[] body) {