fix: properly resolve breakpoints

This commit is contained in:
TopchetoEU 2024-03-30 12:13:04 +02:00
parent fda33112a7
commit 8acbc003c4
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
3 changed files with 34 additions and 22 deletions

View File

@ -1,4 +1,4 @@
project_group = me.topchetoeu project_group = me.topchetoeu
project_name = jscript project_name = jscript
project_version = 0.9.25-beta project_version = 0.9.26-beta
main_class = me.topchetoeu.jscript.utils.JScriptRepl main_class = me.topchetoeu.jscript.utils.JScriptRepl

View File

@ -104,7 +104,9 @@ public class FunctionMap {
var res = new ArrayList<Location>(candidates.size()); var res = new ArrayList<Location>(candidates.size());
for (var candidate : candidates.entrySet()) { for (var candidate : candidates.entrySet()) {
res.add(candidate.getValue().ceiling(new Location(line, column, candidate.getKey()))); var val = correctBreakpoint(new Location(line, column, candidate.getKey()));
if (val == null) continue;
res.add(val);
} }
return res; return res;

View File

@ -86,7 +86,9 @@ public class SimpleDebugger implements Debugger {
public final String condition; public final String condition;
public final Pattern pattern; public final Pattern pattern;
public final int line, start; public final int line, start;
public final WeakHashMap<FunctionBody, Set<Location>> resolvedLocations = new WeakHashMap<>(); public final long locNum;
public final HashMap<Filename, Location> resolvedLocations = new HashMap<>();
public final HashMap<Filename, Long> resolvedDistances = new HashMap<>();
public Breakpoint(int id, Pattern pattern, int line, int start, String condition) { public Breakpoint(int id, Pattern pattern, int line, int start, String condition) {
this.id = id; this.id = id;
@ -94,18 +96,28 @@ public class SimpleDebugger implements Debugger {
this.pattern = pattern; this.pattern = pattern;
this.line = line; this.line = line;
this.start = start; this.start = start;
this.locNum = start | ((long)line << 32);
if (condition != null && condition.trim().equals("")) condition = null; if (condition != null && condition.trim().equals("")) condition = null;
} }
// TODO: Figure out how to unload a breakpoint // TODO: Figure out how to unload a breakpoint
// TODO: Do location resolution with function boundaries
public void addFunc(FunctionBody body, FunctionMap map) { public void addFunc(FunctionBody body, FunctionMap map) {
try { try {
for (var loc : map.correctBreakpoint(pattern, line, start)) { for (var loc : map.correctBreakpoint(pattern, line, start)) {
if (!resolvedLocations.containsKey(body)) resolvedLocations.put(body, new HashSet<>()); var currNum = loc.start() + ((long)loc.line() << 32);
var set = resolvedLocations.get(body); long currDist = 0;
set.add(loc); if (currNum > locNum) currDist = currNum - locNum;
else currDist = locNum - currNum;
if ( currDist > resolvedDistances.getOrDefault(loc.filename(), Long.MAX_VALUE)) continue;
resolvedLocations.put(loc.filename(), loc);
resolvedDistances.put(loc.filename(), currDist);
}
for (var loc : resolvedLocations.values()) {
ws.send(new V8Event("Debugger.breakpointResolved", new JSONMap() ws.send(new V8Event("Debugger.breakpointResolved", new JSONMap()
.set("breakpointId", id) .set("breakpointId", id)
.set("location", serializeLocation(loc)) .set("location", serializeLocation(loc))
@ -207,7 +219,7 @@ public class SimpleDebugger implements Debugger {
private WeakHashMap<DebugContext, DebugContext> contexts = new WeakHashMap<>(); private WeakHashMap<DebugContext, DebugContext> contexts = new WeakHashMap<>();
private WeakHashMap<FunctionBody, FunctionMap> mappings = new WeakHashMap<>(); private WeakHashMap<FunctionBody, FunctionMap> mappings = new WeakHashMap<>();
private WeakHashMap<FunctionBody, HashMap<Location, Breakpoint>> bpLocs = new WeakHashMap<>(); private HashMap<Location, HashSet<Breakpoint>> bpLocs = new HashMap<>();
private HashMap<Integer, Breakpoint> idToBreakpoint = new HashMap<>(); private HashMap<Integer, Breakpoint> idToBreakpoint = new HashMap<>();
@ -297,13 +309,11 @@ public class SimpleDebugger implements Debugger {
bpLocs.clear(); bpLocs.clear();
for (var bp : idToBreakpoint.values()) { for (var bp : idToBreakpoint.values()) {
for (var el : bp.resolvedLocations.entrySet()) { for (var loc : bp.resolvedLocations.values()) {
if (!bpLocs.containsKey(el.getKey())) bpLocs.put(el.getKey(), new HashMap<>()); bpLocs.putIfAbsent(loc, new HashSet<>());
var map = bpLocs.get(el.getKey()); var set = bpLocs.get(loc);
for (var loc : el.getValue()) { set.add(bp);
map.put(loc, bp);
}
} }
} }
} }
@ -720,16 +730,15 @@ public class SimpleDebugger implements Debugger {
var bpt = new Breakpoint(nextId(), regex, line, col, cond); var bpt = new Breakpoint(nextId(), regex, line, col, cond);
idToBreakpoint.put(bpt.id, bpt); idToBreakpoint.put(bpt.id, bpt);
var locs = new JSONList();
for (var el : mappings.entrySet()) { for (var el : mappings.entrySet()) {
bpt.addFunc(el.getKey(), el.getValue()); bpt.addFunc(el.getKey(), el.getValue());
} }
for (var el : bpt.resolvedLocations.values()) { var locs = new JSONList();
for (var loc : el) {
locs.add(serializeLocation(loc)); for (var loc : bpt.resolvedLocations.values()) {
} locs.add(serializeLocation(loc));
} }
ws.send(msg.respond(new JSONMap() ws.send(msg.respond(new JSONMap()
@ -969,10 +978,11 @@ public class SimpleDebugger implements Debugger {
) { ) {
pauseDebug(ctx, null); pauseDebug(ctx, null);
} }
else if (isBreakpointable && bpLocs.getOrDefault(cf.function.body, new HashMap<>()).containsKey(loc)) { else if (isBreakpointable && bpLocs.containsKey(loc)) {
var bp = bpLocs.get(cf.function.body).get(loc); for (var bp : bpLocs.get(loc)) {
var ok = bp.condition == null ? true : Values.toBoolean(run(currFrame, bp.condition).result); var ok = bp.condition == null ? true : Values.toBoolean(run(currFrame, bp.condition).result);
if (ok) pauseDebug(ctx, bp); if (ok) pauseDebug(ctx, bp);
}
} }
// else if (isBreakpointable && tmpBreakpts.remove(loc)) pauseDebug(ctx, null); // else if (isBreakpointable && tmpBreakpts.remove(loc)) pauseDebug(ctx, null);
else if (isBreakpointable && pendingPause) { else if (isBreakpointable && pendingPause) {