feat: greatly improve Context API
This commit is contained in:
parent
9ea5cd9277
commit
c0b895e00a
@ -2,9 +2,8 @@ package me.topchetoeu.jscript.engine;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -14,35 +13,44 @@ import me.topchetoeu.jscript.engine.debug.DebugContext;
|
|||||||
import me.topchetoeu.jscript.engine.frame.CodeFrame;
|
import me.topchetoeu.jscript.engine.frame.CodeFrame;
|
||||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||||
|
import me.topchetoeu.jscript.engine.values.Symbol;
|
||||||
import me.topchetoeu.jscript.engine.values.Values;
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
import me.topchetoeu.jscript.lib.EnvironmentLib;
|
import me.topchetoeu.jscript.lib.EnvironmentLib;
|
||||||
import me.topchetoeu.jscript.mapping.SourceMap;
|
import me.topchetoeu.jscript.mapping.SourceMap;
|
||||||
|
|
||||||
public class Context extends ExtensionStack {
|
public class Context implements Extensions {
|
||||||
private final Stack<Environment> env = new Stack<>();
|
public final Context parent;
|
||||||
private final ArrayList<CodeFrame> frames = new ArrayList<>();
|
public final Environment environment;
|
||||||
|
public final CodeFrame frame;
|
||||||
public final Engine engine;
|
public final Engine engine;
|
||||||
|
public final int stackSize;
|
||||||
|
|
||||||
@Override
|
@Override public <T> void add(Symbol key, T obj) {
|
||||||
protected Extensions[] extensionStack() {
|
if (environment != null) environment.add(key, obj);
|
||||||
return new Extensions[] { environment(), engine.globalEnvironment };
|
else if (engine != null) engine.globalEnvironment.add(key, obj);
|
||||||
}
|
}
|
||||||
|
@Override public <T> T get(Symbol key) {
|
||||||
|
if (environment != null && environment.has(key)) return environment.get(key);
|
||||||
|
else if (engine != null && engine.globalEnvironment.has(key)) return engine.globalEnvironment.get(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Override public boolean has(Symbol key) {
|
||||||
|
return
|
||||||
|
environment != null && environment.has(key) ||
|
||||||
|
engine != null && engine.globalEnvironment.has(key);
|
||||||
|
}
|
||||||
|
@Override public boolean remove(Symbol key) {
|
||||||
|
var res = false;
|
||||||
|
|
||||||
public Environment environment() {
|
if (environment != null) res |= environment.remove(key);
|
||||||
return env.empty() ? null : env.peek();
|
else if (engine != null) res |= engine.globalEnvironment.remove(key);
|
||||||
}
|
|
||||||
|
|
||||||
private Context pushEnv(Environment env) {
|
return res;
|
||||||
this.env.push(env);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
private void popEnv() {
|
|
||||||
if (!env.empty()) this.env.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionValue compile(Filename filename, String raw) {
|
public FunctionValue compile(Filename filename, String raw) {
|
||||||
var env = environment();
|
var env = environment;
|
||||||
var result = Environment.compileFunc(this).call(this, null, raw, filename.toString(), new EnvironmentLib(env));
|
var result = Environment.compileFunc(this).call(this, null, raw, filename.toString(), new EnvironmentLib(env));
|
||||||
|
|
||||||
var function = (FunctionValue)Values.getMember(this, result, "function");
|
var function = (FunctionValue)Values.getMember(this, result, "function");
|
||||||
@ -74,33 +82,37 @@ public class Context extends ExtensionStack {
|
|||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushFrame(CodeFrame frame) {
|
public Context pushFrame(CodeFrame frame) {
|
||||||
frames.add(frame);
|
var res = new Context(this, frame.function.environment, frame, engine, stackSize + 1);
|
||||||
if (frames.size() > engine.maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
DebugContext.get(res).onFramePush(res, frame);
|
||||||
pushEnv(frame.function.environment);
|
return res;
|
||||||
DebugContext.get(this).onFramePush(this, frame);
|
|
||||||
}
|
|
||||||
public boolean popFrame(CodeFrame frame) {
|
|
||||||
if (frames.size() == 0) return false;
|
|
||||||
if (frames.get(frames.size() - 1) != frame) return false;
|
|
||||||
frames.remove(frames.size() - 1);
|
|
||||||
popEnv();
|
|
||||||
DebugContext.get(this).onFramePop(this, frame);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public CodeFrame peekFrame() {
|
|
||||||
if (frames.size() == 0) return null;
|
|
||||||
return frames.get(frames.size() - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CodeFrame> frames() {
|
public Iterable<CodeFrame> frames() {
|
||||||
return Collections.unmodifiableList(frames);
|
var self = this;
|
||||||
|
return () -> new Iterator<CodeFrame>() {
|
||||||
|
private Context curr = self;
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
while (curr.frame == null && curr != null) curr = curr.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean hasNext() {
|
||||||
|
update();
|
||||||
|
return curr != null;
|
||||||
|
}
|
||||||
|
@Override public CodeFrame next() {
|
||||||
|
update();
|
||||||
|
var res = curr.frame;
|
||||||
|
curr = curr.parent;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
public List<String> stackTrace() {
|
public List<String> stackTrace() {
|
||||||
var res = new ArrayList<String>();
|
var res = new ArrayList<String>();
|
||||||
|
|
||||||
for (var i = frames.size() - 1; i >= 0; i--) {
|
for (var el : frames()) {
|
||||||
var el = frames.get(i);
|
|
||||||
var name = el.function.name;
|
var name = el.function.name;
|
||||||
Location loc = null;
|
Location loc = null;
|
||||||
|
|
||||||
@ -120,11 +132,20 @@ public class Context extends ExtensionStack {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context(Engine engine) {
|
private Context(Context parent, Environment environment, CodeFrame frame, Engine engine, int stackSize) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.environment = environment;
|
||||||
|
this.frame = frame;
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
|
this.stackSize = stackSize;
|
||||||
|
|
||||||
|
if (engine != null && stackSize > engine.maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context(Engine engine) {
|
||||||
|
this(null, null, null, engine, 0);
|
||||||
}
|
}
|
||||||
public Context(Engine engine, Environment env) {
|
public Context(Engine engine, Environment env) {
|
||||||
this(engine);
|
this(null, env, null, engine, 0);
|
||||||
if (env != null) this.pushEnv(env);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public class Environment implements Extensions {
|
|||||||
}
|
}
|
||||||
public static FunctionValue regexConstructor(Extensions ext) {
|
public static FunctionValue regexConstructor(Extensions ext) {
|
||||||
return ext.init(COMPILE_FUNC, new NativeFunction("RegExp", (ctx, thisArg, args) -> {
|
return ext.init(COMPILE_FUNC, new NativeFunction("RegExp", (ctx, thisArg, args) -> {
|
||||||
throw EngineException.ofError("Regular expressions not supported.").setCtx(ctx.environment(), ctx.engine);
|
throw EngineException.ofError("Regular expressions not supported.").setCtx(ctx.environment, ctx.engine);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void updateFrames(Context ctx) {
|
private synchronized void updateFrames(Context ctx) {
|
||||||
var frame = ctx.peekFrame();
|
var frame = ctx.frame;
|
||||||
if (frame == null) return;
|
if (frame == null) return;
|
||||||
|
|
||||||
if (!codeFrameToFrame.containsKey(frame)) {
|
if (!codeFrameToFrame.containsKey(frame)) {
|
||||||
@ -249,10 +249,9 @@ public class SimpleDebugger implements Debugger {
|
|||||||
}
|
}
|
||||||
private JSONList serializeFrames(Context ctx) {
|
private JSONList serializeFrames(Context ctx) {
|
||||||
var res = new JSONList();
|
var res = new JSONList();
|
||||||
var frames = ctx.frames();
|
|
||||||
|
|
||||||
for (var i = frames.size() - 1; i >= 0; i--) {
|
for (var el : ctx.frames()) {
|
||||||
var frame = codeFrameToFrame.get(frames.get(i));
|
var frame = codeFrameToFrame.get(el);
|
||||||
if (frame.location == null) continue;
|
if (frame.location == null) continue;
|
||||||
frame.serialized.set("location", serializeLocation(frame.location));
|
frame.serialized.set("location", serializeLocation(frame.location));
|
||||||
if (frame.location != null) res.add(frame.serialized);
|
if (frame.location != null) res.add(frame.serialized);
|
||||||
@ -484,7 +483,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
env.global = new GlobalScope(codeFrame.local);
|
env.global = new GlobalScope(codeFrame.local);
|
||||||
|
|
||||||
var ctx = new Context(engine, env);
|
var ctx = new Context(engine, env);
|
||||||
var awaiter = engine.pushMsg(false, ctx.environment(), new Filename("jscript", "eval"), code, codeFrame.frame.thisArg, codeFrame.frame.args);
|
var awaiter = engine.pushMsg(false, ctx.environment, new Filename("jscript", "eval"), code, codeFrame.frame.thisArg, codeFrame.frame.args);
|
||||||
|
|
||||||
engine.run(true);
|
engine.run(true);
|
||||||
|
|
||||||
@ -496,7 +495,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
var passed = new HashSet<String>();
|
var passed = new HashSet<String>();
|
||||||
var tildas = "~";
|
var tildas = "~";
|
||||||
if (target == null) target = ctx.environment().global;
|
if (target == null) target = ctx.environment.global;
|
||||||
|
|
||||||
for (var proto = target; proto != null && proto != Values.NULL; proto = Values.getPrototype(ctx, proto)) {
|
for (var proto = target; proto != null && proto != Values.NULL; proto = Values.getPrototype(ctx, proto)) {
|
||||||
for (var el : Values.getMembers(ctx, proto, true, true)) {
|
for (var el : Values.getMembers(ctx, proto, true, true)) {
|
||||||
@ -944,7 +943,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
try { idToFrame.remove(codeFrameToFrame.remove(frame).id); }
|
try { idToFrame.remove(codeFrameToFrame.remove(frame).id); }
|
||||||
catch (NullPointerException e) { }
|
catch (NullPointerException e) { }
|
||||||
|
|
||||||
if (ctx.frames().size() == 0) {
|
if (ctx.stackSize == 0) {
|
||||||
if (state == State.PAUSED_EXCEPTION || state == State.PAUSED_NORMAL) resume(State.RESUMED);
|
if (state == State.PAUSED_EXCEPTION || state == State.PAUSED_NORMAL) resume(State.RESUMED);
|
||||||
}
|
}
|
||||||
else if (stepOutFrame != null && stepOutFrame.frame == frame && state == State.STEPPING_OUT) {
|
else if (stepOutFrame != null && stepOutFrame.frame == frame && state == State.STEPPING_OUT) {
|
||||||
|
@ -94,6 +94,7 @@ public class CodeFrame {
|
|||||||
public final Object[] args;
|
public final Object[] args;
|
||||||
public final Stack<TryCtx> tryStack = new Stack<>();
|
public final Stack<TryCtx> tryStack = new Stack<>();
|
||||||
public final CodeFunction function;
|
public final CodeFunction function;
|
||||||
|
public final Context ctx;
|
||||||
public Object[] stack = new Object[32];
|
public Object[] stack = new Object[32];
|
||||||
public int stackPtr = 0;
|
public int stackPtr = 0;
|
||||||
public int codePtr = 0;
|
public int codePtr = 0;
|
||||||
@ -187,7 +188,7 @@ public class CodeFrame {
|
|||||||
stack[stackPtr++] = Values.normalize(ctx, val);
|
stack[stackPtr++] = Values.normalize(ctx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next(Context ctx, Object value, Object returnValue, EngineException error) {
|
public Object next(Object value, Object returnValue, EngineException error) {
|
||||||
if (value != Runners.NO_RETURN) push(ctx, value);
|
if (value != Runners.NO_RETURN) push(ctx, value);
|
||||||
|
|
||||||
Instruction instr = null;
|
Instruction instr = null;
|
||||||
@ -314,5 +315,6 @@ public class CodeFrame {
|
|||||||
|
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
this.function = func;
|
this.function = func;
|
||||||
|
this.ctx = ctx.pushFrame(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class Runners {
|
|||||||
|
|
||||||
public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) {
|
public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var name = (String)instr.get(0);
|
var name = (String)instr.get(0);
|
||||||
ctx.environment().global.define(name);
|
ctx.environment.global.define(name);
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ public class Runners {
|
|||||||
public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) {
|
public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var i = instr.get(0);
|
var i = instr.get(0);
|
||||||
|
|
||||||
if (i instanceof String) frame.push(ctx, ctx.environment().global.get(ctx, (String)i));
|
if (i instanceof String) frame.push(ctx, ctx.environment.global.get(ctx, (String)i));
|
||||||
else frame.push(ctx, frame.scope.get((int)i).get(ctx));
|
else frame.push(ctx, frame.scope.get((int)i).get(ctx));
|
||||||
|
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
@ -154,7 +154,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execLoadGlob(Context ctx, Instruction instr, CodeFrame frame) {
|
public static Object execLoadGlob(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
frame.push(ctx, ctx.environment().global.obj);
|
frame.push(ctx, ctx.environment.global.obj);
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ public class Runners {
|
|||||||
captures[i - 1] = frame.scope.get(instr.get(i));
|
captures[i - 1] = frame.scope.get(instr.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
var func = new CodeFunction(ctx.environment(), "", Engine.functions.get(id), captures);
|
var func = new CodeFunction(ctx.environment, "", Engine.functions.get(id), captures);
|
||||||
|
|
||||||
frame.push(ctx, func);
|
frame.push(ctx, func);
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ public class Runners {
|
|||||||
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
|
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
|
||||||
var i = instr.get(0);
|
var i = instr.get(0);
|
||||||
|
|
||||||
if (i instanceof String) ctx.environment().global.set(ctx, (String)i, val);
|
if (i instanceof String) ctx.environment.global.set(ctx, (String)i, val);
|
||||||
else frame.scope.get((int)i).set(ctx, val);
|
else frame.scope.get((int)i).set(ctx, val);
|
||||||
|
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
@ -274,8 +274,8 @@ public class Runners {
|
|||||||
Object obj;
|
Object obj;
|
||||||
|
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
if (ctx.environment().global.has(ctx, name)) {
|
if (ctx.environment.global.has(ctx, name)) {
|
||||||
obj = ctx.environment().global.get(ctx, name);
|
obj = ctx.environment.global.get(ctx, name);
|
||||||
}
|
}
|
||||||
else obj = null;
|
else obj = null;
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,10 @@ public class CodeFunction extends FunctionValue {
|
|||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var frame = new CodeFrame(ctx, thisArg, args, this);
|
var frame = new CodeFrame(ctx, thisArg, args, this);
|
||||||
try {
|
|
||||||
ctx.pushFrame(frame);
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var res = frame.next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, null);
|
var res = frame.next(Runners.NO_RETURN, Runners.NO_RETURN, null);
|
||||||
if (res != Runners.NO_RETURN) return res;
|
if (res != Runners.NO_RETURN) return res;
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
ctx.popFrame(frame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ public class NativeWrapper extends ObjectValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectValue getPrototype(Context ctx) {
|
public ObjectValue getPrototype(Context ctx) {
|
||||||
if (prototype == NATIVE_PROTO) return ctx.environment().wrappers.getProto(wrapped.getClass());
|
if (prototype == NATIVE_PROTO) return ctx.environment.wrappers.getProto(wrapped.getClass());
|
||||||
else return super.getPrototype(ctx);
|
else return super.getPrototype(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +477,7 @@ public class Values {
|
|||||||
|
|
||||||
if (val instanceof Class) {
|
if (val instanceof Class) {
|
||||||
if (ctx == null) return null;
|
if (ctx == null) return null;
|
||||||
else return ctx.environment().wrappers.getConstr((Class<?>)val);
|
else return ctx.environment.wrappers.getConstr((Class<?>)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NativeWrapper(val);
|
return new NativeWrapper(val);
|
||||||
|
@ -38,7 +38,7 @@ public class EngineException extends RuntimeException {
|
|||||||
if (function.equals("")) function = null;
|
if (function.equals("")) function = null;
|
||||||
|
|
||||||
if (ctx == null) this.ctx = null;
|
if (ctx == null) this.ctx = null;
|
||||||
else this.ctx = new Context(ctx.engine, ctx.environment());
|
else this.ctx = new Context(ctx.engine, ctx.environment);
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ public class EngineException extends RuntimeException {
|
|||||||
public EngineException add(Context ctx, String name, Location location) {
|
public EngineException add(Context ctx, String name, Location location) {
|
||||||
var el = new StackElement(ctx, location, name);
|
var el = new StackElement(ctx, location, name);
|
||||||
if (el.function == null && el.location == null) return this;
|
if (el.function == null && el.location == null) return this;
|
||||||
setCtx(ctx.environment(), ctx.engine);
|
setCtx(ctx.environment, ctx.engine);
|
||||||
stackTrace.add(el);
|
stackTrace.add(el);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,11 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
|
|
||||||
private void next(Context ctx, Object inducedValue, Object inducedError) {
|
private void next(Context ctx, Object inducedValue, Object inducedError) {
|
||||||
Object res = null;
|
Object res = null;
|
||||||
ctx.pushFrame(frame);
|
|
||||||
|
|
||||||
awaiting = false;
|
awaiting = false;
|
||||||
while (!awaiting) {
|
while (!awaiting) {
|
||||||
try {
|
try {
|
||||||
res = frame.next(ctx, inducedValue, Runners.NO_RETURN, inducedError == Runners.NO_RETURN ? null : new EngineException(inducedError));
|
res = frame.next(inducedValue, Runners.NO_RETURN, inducedError == Runners.NO_RETURN ? null : new EngineException(inducedError));
|
||||||
inducedValue = inducedError = Runners.NO_RETURN;
|
inducedValue = inducedError = Runners.NO_RETURN;
|
||||||
if (res != Runners.NO_RETURN) {
|
if (res != Runners.NO_RETURN) {
|
||||||
promise.fulfill(ctx, res);
|
promise.fulfill(ctx, res);
|
||||||
@ -38,8 +37,6 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.popFrame(frame);
|
|
||||||
|
|
||||||
if (awaiting) {
|
if (awaiting) {
|
||||||
PromiseLib.then(ctx, frame.pop(), new NativeFunction(this::fulfill), new NativeFunction(this::reject));
|
PromiseLib.then(ctx, frame.pop(), new NativeFunction(this::fulfill), new NativeFunction(this::reject));
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,11 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object res = null;
|
Object res = null;
|
||||||
ctx.pushFrame(frame);
|
|
||||||
state = 0;
|
state = 0;
|
||||||
|
|
||||||
while (state == 0) {
|
while (state == 0) {
|
||||||
try {
|
try {
|
||||||
res = frame.next(ctx, inducedValue, inducedReturn, inducedError == Runners.NO_RETURN ? null : new EngineException(inducedError));
|
res = frame.next(inducedValue, inducedReturn, inducedError == Runners.NO_RETURN ? null : new EngineException(inducedError));
|
||||||
inducedValue = inducedReturn = inducedError = Runners.NO_RETURN;
|
inducedValue = inducedReturn = inducedError = Runners.NO_RETURN;
|
||||||
if (res != Runners.NO_RETURN) {
|
if (res != Runners.NO_RETURN) {
|
||||||
var obj = new ObjectValue();
|
var obj = new ObjectValue();
|
||||||
@ -49,8 +48,6 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.popFrame(frame);
|
|
||||||
|
|
||||||
if (state == 1) {
|
if (state == 1) {
|
||||||
PromiseLib.then(ctx, frame.pop(), new NativeFunction(this::fulfill), new NativeFunction(this::reject));
|
PromiseLib.then(ctx, frame.pop(), new NativeFunction(this::fulfill), new NativeFunction(this::reject));
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,11 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object res = null;
|
Object res = null;
|
||||||
ctx.pushFrame(frame);
|
|
||||||
yielding = false;
|
yielding = false;
|
||||||
|
|
||||||
while (!yielding) {
|
while (!yielding) {
|
||||||
try {
|
try {
|
||||||
res = frame.next(ctx, inducedValue, inducedReturn, inducedError == Runners.NO_RETURN ? null : new EngineException(inducedError));
|
res = frame.next(inducedValue, inducedReturn, inducedError == Runners.NO_RETURN ? null : new EngineException(inducedError));
|
||||||
inducedReturn = inducedError = Runners.NO_RETURN;
|
inducedReturn = inducedError = Runners.NO_RETURN;
|
||||||
if (res != Runners.NO_RETURN) {
|
if (res != Runners.NO_RETURN) {
|
||||||
done = true;
|
done = true;
|
||||||
@ -42,7 +41,6 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.popFrame(frame);
|
|
||||||
if (done) frame = null;
|
if (done) frame = null;
|
||||||
else res = frame.pop();
|
else res = frame.pop();
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class Internals {
|
|||||||
}
|
}
|
||||||
catch (InterruptedException e) { return; }
|
catch (InterruptedException e) { return; }
|
||||||
|
|
||||||
ctx.engine.pushMsg(false, ctx.environment(), func, null, args);
|
ctx.engine.pushMsg(false, ctx.environment, func, null, args);
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ public class Internals {
|
|||||||
}
|
}
|
||||||
catch (InterruptedException e) { return; }
|
catch (InterruptedException e) { return; }
|
||||||
|
|
||||||
ctx.engine.pushMsg(false, ctx.environment(), func, null, args);
|
ctx.engine.pushMsg(false, ctx.environment, func, null, args);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
this.val = val;
|
this.val = val;
|
||||||
this.state = STATE_FULFILLED;
|
this.state = STATE_FULFILLED;
|
||||||
|
|
||||||
ctx.engine.pushMsg(true, ctx.environment(), new NativeFunction((_ctx, _thisArg, _args) -> {
|
ctx.engine.pushMsg(true, ctx.environment, new NativeFunction((_ctx, _thisArg, _args) -> {
|
||||||
for (var handle : handles) {
|
for (var handle : handles) {
|
||||||
handle.fulfilled.call(handle.ctx, null, val);
|
handle.fulfilled.call(handle.ctx, null, val);
|
||||||
}
|
}
|
||||||
@ -288,10 +288,10 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
this.val = val;
|
this.val = val;
|
||||||
this.state = STATE_REJECTED;
|
this.state = STATE_REJECTED;
|
||||||
|
|
||||||
ctx.engine.pushMsg(true, ctx.environment(), new NativeFunction((_ctx, _thisArg, _args) -> {
|
ctx.engine.pushMsg(true, ctx.environment, new NativeFunction((_ctx, _thisArg, _args) -> {
|
||||||
for (var handle : handles) handle.rejected.call(handle.ctx, null, val);
|
for (var handle : handles) handle.rejected.call(handle.ctx, null, val);
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
Values.printError(new EngineException(val).setCtx(ctx.environment(), ctx.engine), "(in promise)");
|
Values.printError(new EngineException(val).setCtx(ctx.environment, ctx.engine), "(in promise)");
|
||||||
}
|
}
|
||||||
handles = null;
|
handles = null;
|
||||||
return null;
|
return null;
|
||||||
@ -305,9 +305,9 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handle(Context ctx, FunctionValue fulfill, FunctionValue reject) {
|
private void handle(Context ctx, FunctionValue fulfill, FunctionValue reject) {
|
||||||
if (state == STATE_FULFILLED) ctx.engine.pushMsg(true, ctx.environment(), fulfill, null, val);
|
if (state == STATE_FULFILLED) ctx.engine.pushMsg(true, ctx.environment, fulfill, null, val);
|
||||||
else if (state == STATE_REJECTED) {
|
else if (state == STATE_REJECTED) {
|
||||||
ctx.engine.pushMsg(true, ctx.environment(), reject, null, val);
|
ctx.engine.pushMsg(true, ctx.environment, reject, null, val);
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else handles.add(new Handle(ctx, fulfill, reject));
|
else handles.add(new Handle(ctx, fulfill, reject));
|
||||||
|
@ -25,7 +25,7 @@ public interface ModuleRepo {
|
|||||||
|
|
||||||
if (modules.containsKey(name)) return modules.get(name);
|
if (modules.containsKey(name)) return modules.get(name);
|
||||||
|
|
||||||
var env = ctx.environment().child();
|
var env = ctx.environment.child();
|
||||||
env.add(CWD, fs.normalize(name, ".."));
|
env.add(CWD, fs.normalize(name, ".."));
|
||||||
|
|
||||||
var mod = new SourceModule(filename, src, env);
|
var mod = new SourceModule(filename, src, env);
|
||||||
|
Loading…
Reference in New Issue
Block a user