feat: add old data to both subcontexts
This commit is contained in:
parent
68f3b6d926
commit
6c7fe6deaf
@ -102,7 +102,7 @@ public class Main {
|
|||||||
var raw = in.readLine();
|
var raw = in.readLine();
|
||||||
|
|
||||||
if (raw == null) break;
|
if (raw == null) break;
|
||||||
engine.pushMsg(false, new Context(env, new Message(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter);
|
engine.pushMsg(false, env.context(new Message(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter);
|
||||||
}
|
}
|
||||||
catch (EngineException e) {
|
catch (EngineException e) {
|
||||||
try {
|
try {
|
||||||
|
58
src/me/topchetoeu/jscript/engine/Data.java
Normal file
58
src/me/topchetoeu/jscript/engine/Data.java
Normal file
@ -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<Entry<DataKey<?>, ?>> {
|
||||||
|
private HashMap<DataKey<Object>, Object> data = new HashMap<>();
|
||||||
|
|
||||||
|
public Data copy() {
|
||||||
|
return new Data().addAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data addAll(Iterable<Entry<DataKey<?>, ?>> data) {
|
||||||
|
for (var el : data) {
|
||||||
|
add((DataKey<Object>)el.getKey(), (Object)el.getValue());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Data set(DataKey<T> key, T val) {
|
||||||
|
if (val == null) data.remove(key);
|
||||||
|
else data.put((DataKey<Object>)key, (Object)val);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public <T> T add(DataKey<T> key, T val) {
|
||||||
|
if (data.containsKey(key)) return (T)data.get(key);
|
||||||
|
else {
|
||||||
|
if (val == null) data.remove(key);
|
||||||
|
else data.put((DataKey<Object>)key, (Object)val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public <T> T get(DataKey<T> key) {
|
||||||
|
return get(key, null);
|
||||||
|
}
|
||||||
|
public <T> T get(DataKey<T> 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<Integer> key, int n, int start) {
|
||||||
|
return set(key, get(key, start) + n);
|
||||||
|
}
|
||||||
|
public Data increase(DataKey<Integer> key, int n) {
|
||||||
|
return increase(key, n, 0);
|
||||||
|
}
|
||||||
|
public Data increase(DataKey<Integer> key) {
|
||||||
|
return increase(key, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Entry<DataKey<?>, ?>> iterator() {
|
||||||
|
return (Iterator<Entry<DataKey<?>, ?>>)data.entrySet();
|
||||||
|
}
|
||||||
|
}
|
3
src/me/topchetoeu/jscript/engine/DataKey.java
Normal file
3
src/me/topchetoeu/jscript/engine/DataKey.java
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package me.topchetoeu.jscript.engine;
|
||||||
|
|
||||||
|
public class DataKey<T> { }
|
@ -11,19 +11,19 @@ public class Engine {
|
|||||||
private class UncompiledFunction extends FunctionValue {
|
private class UncompiledFunction extends FunctionValue {
|
||||||
public final String filename;
|
public final String filename;
|
||||||
public final String raw;
|
public final String raw;
|
||||||
public final Environment ctx;
|
public final Environment env;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
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);
|
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);
|
super(filename, 0);
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
this.raw = raw;
|
this.raw = raw;
|
||||||
this.ctx = ctx;
|
this.env = env;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,10 +32,10 @@ public class Engine {
|
|||||||
public final Object thisArg;
|
public final Object thisArg;
|
||||||
public final Object[] args;
|
public final Object[] args;
|
||||||
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
||||||
public final Message ctx;
|
public final Message msg;
|
||||||
|
|
||||||
public Task(Message ctx, FunctionValue func, Object thisArg, Object[] args) {
|
public Task(Message ctx, FunctionValue func, Object thisArg, Object[] args) {
|
||||||
this.ctx = ctx;
|
this.msg = ctx;
|
||||||
this.func = func;
|
this.func = func;
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
@ -52,7 +52,7 @@ public class Engine {
|
|||||||
|
|
||||||
private void runTask(Task task) throws InterruptedException {
|
private void runTask(Task task) throws InterruptedException {
|
||||||
try {
|
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) {
|
catch (InterruptedException e) {
|
||||||
task.notifier.error(new RuntimeException(e));
|
task.notifier.error(new RuntimeException(e));
|
||||||
|
@ -15,15 +15,23 @@ import me.topchetoeu.jscript.interop.NativeWrapperProvider;
|
|||||||
|
|
||||||
public class Environment {
|
public class Environment {
|
||||||
private HashMap<String, ObjectValue> prototypes = new HashMap<>();
|
private HashMap<String, ObjectValue> prototypes = new HashMap<>();
|
||||||
|
|
||||||
|
public final Data data = new Data();
|
||||||
|
public final HashMap<String, Symbol> symbols = new HashMap<>();
|
||||||
|
|
||||||
public GlobalScope global;
|
public GlobalScope global;
|
||||||
public WrappersProvider wrappersProvider;
|
public WrappersProvider wrappersProvider;
|
||||||
/** NOTE: This is not the register for Symbol.for, but for the symbols like Symbol.iterator */
|
|
||||||
public HashMap<String, Symbol> symbols = new HashMap<>();
|
|
||||||
|
|
||||||
@Native public FunctionValue compile;
|
@Native public FunctionValue compile;
|
||||||
@Native public FunctionValue regexConstructor = new NativeFunction("RegExp", (ctx, thisArg, args) -> {
|
@Native public FunctionValue regexConstructor = new NativeFunction("RegExp", (ctx, thisArg, args) -> {
|
||||||
throw EngineException.ofError("Regular expressions not supported.").setContext(ctx);
|
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) {
|
@Native public ObjectValue proto(String name) {
|
||||||
return prototypes.get(name);
|
return prototypes.get(name);
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,15 @@ public class Message {
|
|||||||
private final ArrayList<CodeFrame> frames = new ArrayList<>();
|
private final ArrayList<CodeFrame> frames = new ArrayList<>();
|
||||||
public int maxStackFrames = 1000;
|
public int maxStackFrames = 1000;
|
||||||
|
|
||||||
|
public final Data data = new Data();
|
||||||
|
|
||||||
public List<CodeFrame> frames() { return Collections.unmodifiableList(frames); }
|
public List<CodeFrame> 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 {
|
public Message pushFrame(Context ctx, CodeFrame frame) throws InterruptedException {
|
||||||
this.frames.add(frame);
|
this.frames.add(frame);
|
||||||
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
||||||
|
@ -29,7 +29,7 @@ public class CodeFunction extends FunctionValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
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) {
|
public CodeFunction(Environment environment, String name, int localsN, int length, ValueVariable[] captures, Instruction[] body) {
|
||||||
|
Loading…
Reference in New Issue
Block a user