move FunctionMap logic away from core
This commit is contained in:
@@ -30,6 +30,7 @@ import me.topchetoeu.j2s.repl.buffers.Int32ArrayValue;
|
||||
import me.topchetoeu.j2s.repl.buffers.Int8ArrayValue;
|
||||
import me.topchetoeu.j2s.repl.buffers.TypedArrayValue;
|
||||
import me.topchetoeu.j2s.repl.buffers.Uint8ArrayValue;
|
||||
import me.topchetoeu.j2s.repl.debug.SimpleDebugHandler;
|
||||
import me.topchetoeu.j2s.repl.debug.DebugServer;
|
||||
import me.topchetoeu.j2s.repl.debug.Debugger;
|
||||
import me.topchetoeu.j2s.repl.debug.SimpleDebugger;
|
||||
@@ -39,7 +40,7 @@ import me.topchetoeu.j2s.runtime.Compiler;
|
||||
import me.topchetoeu.j2s.runtime.Engine;
|
||||
import me.topchetoeu.j2s.runtime.EventLoop;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugContext;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugHandler;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
import me.topchetoeu.j2s.runtime.values.functions.CodeFunction;
|
||||
@@ -61,9 +62,9 @@ public class SimpleRepl {
|
||||
var res = JavaScript.compile(env, filename, raw, true);
|
||||
var body = res.body();
|
||||
|
||||
DebugContext.get(env).onSource(filename, raw);
|
||||
DebugHandler.get(env).onSourceLoad(filename, raw);
|
||||
for (var el : res.all()) {
|
||||
DebugContext.get(env).onFunctionLoad(el.body(), el.map(mapper));
|
||||
DebugHandler.get(env).onFunctionLoad(el.body(), el.map(mapper));
|
||||
}
|
||||
|
||||
return new CodeFunction(env, filename.toString(), body, new Value[0][]);
|
||||
@@ -98,8 +99,8 @@ public class SimpleRepl {
|
||||
server = new DebugServer();
|
||||
debugTask = server.start(new InetSocketAddress("127.0.0.1", 9229), true);
|
||||
server.targets.put("default", (socket, req) -> new SimpleDebugger(socket)
|
||||
.attach(DebugContext.get(environment))
|
||||
.attach(DebugContext.get(tsEnvironment))
|
||||
.attach((SimpleDebugHandler)DebugHandler.get(environment))
|
||||
.attach((SimpleDebugHandler)DebugHandler.get(tsEnvironment))
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -846,7 +847,7 @@ public class SimpleRepl {
|
||||
private static Environment initEnv() {
|
||||
var env = new Environment();
|
||||
env.add(EventLoop.KEY, engine);
|
||||
env.add(DebugContext.KEY, new DebugContext());
|
||||
env.add(DebugHandler.KEY, new SimpleDebugHandler());
|
||||
env.add(Compiler.KEY, DEFAULT_COMPILER);
|
||||
// env.add(CompileResult.DEBUG_LOG);
|
||||
|
||||
@@ -905,7 +906,7 @@ public class SimpleRepl {
|
||||
tsGlob.defineOwnField(tsEnvironment, "registerSource", new NativeFunction(args -> {
|
||||
var filename = Filename.parse(args.get(0).toString(args.env));
|
||||
var src = args.get(1).toString(args.env);
|
||||
DebugContext.get(environment).onSource(filename, src);
|
||||
DebugHandler.get(environment).onSourceLoad(filename, src);
|
||||
return Value.UNDEFINED;
|
||||
}));
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package me.topchetoeu.j2s.repl.debug;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import me.topchetoeu.j2s.common.Environment;
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.FunctionBody;
|
||||
import me.topchetoeu.j2s.common.FunctionMap;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugHandler;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
|
||||
public class SimpleDebugHandler implements DebugHandler {
|
||||
private HashMap<Filename, String> sources;
|
||||
private WeakHashMap<FunctionBody, FunctionMap> maps;
|
||||
private DebugHandler debugger;
|
||||
|
||||
public synchronized boolean attachDebugger(DebugHandler debugger) {
|
||||
if (this.debugger != null) return false;
|
||||
|
||||
if (sources != null) {
|
||||
for (var source : sources.entrySet()) debugger.onSourceLoad(source.getKey(), source.getValue());
|
||||
}
|
||||
if (maps != null) {
|
||||
for (var map : maps.entrySet()) debugger.onFunctionLoad(map.getKey(), map.getValue());
|
||||
}
|
||||
|
||||
this.debugger = debugger;
|
||||
return true;
|
||||
}
|
||||
public boolean detachDebugger(DebugHandler debugger) {
|
||||
if (this.debugger != debugger) return false;
|
||||
return detachDebugger();
|
||||
}
|
||||
public boolean detachDebugger() {
|
||||
this.debugger = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public DebugHandler debugger() {
|
||||
return debugger;
|
||||
}
|
||||
|
||||
public FunctionMap getMap(Environment env, FunctionBody func) {
|
||||
if (maps == null) return null;
|
||||
return maps.get(func);
|
||||
}
|
||||
|
||||
public void onFramePop(Environment env, Frame frame) {
|
||||
if (debugger != null) debugger.onFramePop(env, frame);
|
||||
}
|
||||
public void onFramePush(Environment env, Frame frame) {
|
||||
if (debugger != null) debugger.onFramePush(env, frame);
|
||||
}
|
||||
|
||||
@Override public boolean onInstruction(Environment env, Frame frame, Instruction instruction, Value returnVal, EngineException error, boolean caught) {
|
||||
if (debugger != null) return debugger.onInstruction(env, frame, instruction, returnVal, error, caught);
|
||||
else return false;
|
||||
}
|
||||
@Override public void onSourceLoad(Filename filename, String source) {
|
||||
if (debugger != null) debugger.onSourceLoad(filename, source);
|
||||
if (sources != null) sources.put(filename, source);
|
||||
}
|
||||
@Override public void onFunctionLoad(FunctionBody func, FunctionMap map) {
|
||||
if (maps != null) maps.put(func, map);
|
||||
if (debugger != null) debugger.onFunctionLoad(func, map);
|
||||
}
|
||||
|
||||
private SimpleDebugHandler(boolean enabled) {
|
||||
if (enabled) {
|
||||
sources = new HashMap<>();
|
||||
maps = new WeakHashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleDebugHandler() {
|
||||
this(true);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import me.topchetoeu.j2s.runtime.Compiler;
|
||||
import me.topchetoeu.j2s.runtime.Engine;
|
||||
import me.topchetoeu.j2s.runtime.EventLoop;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugContext;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugHandler;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
import me.topchetoeu.j2s.runtime.values.Member.FieldMember;
|
||||
@@ -201,11 +201,11 @@ public class SimpleDebugger implements Debugger {
|
||||
this.frame = frame;
|
||||
this.id = id;
|
||||
|
||||
var map = DebugContext.get(frame.env).getMapOrEmpty(frame.function);
|
||||
var map = DebugHandler.get(frame.env).getMapOrEmpty(frame.env, frame.function);
|
||||
this.globals = Value.global(frame.env);
|
||||
this.locals = ScopeObject.locals(frame, map.localNames);
|
||||
this.capturables = ScopeObject.capturables(frame, map.capturableNames);
|
||||
this.captures = ScopeObject.captures(frame, map.captureNames);
|
||||
this.locals = ScopeObject.locals(frame, map.localNames());
|
||||
this.capturables = ScopeObject.capturables(frame, map.capturableNames());
|
||||
this.captures = ScopeObject.captures(frame, map.captureNames());
|
||||
if (this.globals instanceof ObjectValue) {
|
||||
this.variables = ScopeObject.combine((ObjectValue)this.globals, locals, capturables, captures);
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class SimpleDebugger implements Debugger {
|
||||
|
||||
private ObjectValue emptyObject = new ObjectValue();
|
||||
|
||||
private WeakHashMap<DebugContext, DebugContext> contexts = new WeakHashMap<>();
|
||||
private WeakHashMap<SimpleDebugHandler, SimpleDebugHandler> contexts = new WeakHashMap<>();
|
||||
private WeakHashMap<FunctionBody, FunctionMap> mappings = new WeakHashMap<>();
|
||||
private HashMap<Location, HashSet<Breakpoint>> bpLocs = new HashMap<>();
|
||||
|
||||
@@ -617,22 +617,12 @@ public class SimpleDebugger implements Debugger {
|
||||
}
|
||||
}
|
||||
|
||||
// private Environment sanitizeEnvironment(Environment env) {
|
||||
// var res = env.child();
|
||||
|
||||
// res.remove(EventLoop.KEY);
|
||||
// res.remove(DebugContext.KEY);
|
||||
// res.add(DebugContext.IGNORE);
|
||||
|
||||
// return res;
|
||||
// }
|
||||
|
||||
private RunResult run(DebugFrame codeFrame, String code) {
|
||||
if (codeFrame == null) return new RunResult(null, null, EngineException.ofError("Invalid code frame!"));
|
||||
var engine = new Engine();
|
||||
var env = codeFrame.frame.env.child();
|
||||
|
||||
env.remove(DebugContext.KEY);
|
||||
env.remove(DebugHandler.KEY);
|
||||
env.remove(EventLoop.KEY);
|
||||
env.remove(Value.GLOBAL);
|
||||
env.add(Compiler.KEY, SimpleRepl.DEFAULT_COMPILER);
|
||||
@@ -1076,7 +1066,7 @@ public class SimpleDebugger implements Debugger {
|
||||
}
|
||||
|
||||
private boolean instructionLock;
|
||||
|
||||
|
||||
@Override public boolean onInstruction(Environment env, Frame cf, Instruction instruction, Value returnVal, EngineException error, boolean caught) {
|
||||
if (!enabled) return false;
|
||||
if (instructionLock) return false;
|
||||
@@ -1090,7 +1080,7 @@ public class SimpleDebugger implements Debugger {
|
||||
|
||||
frame = getFrame(cf);
|
||||
|
||||
var map = DebugContext.get(env).getMap(frame.frame.function);
|
||||
var map = DebugHandler.get(env).getMap(env, frame.frame.function);
|
||||
|
||||
frame.updateLoc(map.toLocation(frame.frame.codePtr));
|
||||
loc = frame.location;
|
||||
@@ -1197,7 +1187,11 @@ public class SimpleDebugger implements Debugger {
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleDebugger attach(DebugContext ctx) {
|
||||
@Override public FunctionMap getMap(Environment env, FunctionBody func) {
|
||||
return mappings.get(func);
|
||||
}
|
||||
|
||||
public SimpleDebugger attach(SimpleDebugHandler ctx) {
|
||||
ctx.attachDebugger(this);
|
||||
contexts.put(ctx, ctx);
|
||||
return this;
|
||||
|
||||
Reference in New Issue
Block a user