From fed5637d4ddd5538bd407c25b5d12442c021fc81 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Wed, 20 Aug 2014 12:51:28 +0400 Subject: [PATCH] Fixes bugs in stepping --- .../org/teavm/debugging/DebugInformation.java | 55 +++++++++++++------ .../debugging/DebugInformationBuilder.java | 10 +++- .../debugging/DebugInformationReader.java | 25 +++++---- .../debugging/DebugInformationWriter.java | 2 +- .../java/org/teavm/debugging/Debugger.java | 9 +-- 5 files changed, 67 insertions(+), 34 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/debugging/DebugInformation.java b/teavm-core/src/main/java/org/teavm/debugging/DebugInformation.java index 6899a05f3..aef99bbb6 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/DebugInformation.java +++ b/teavm-core/src/main/java/org/teavm/debugging/DebugInformation.java @@ -228,7 +228,7 @@ public class DebugInformation { public MethodReference getExactMethod(int index) { long item = exactMethods[index]; - int classIndex = (int)(item >> 32); + int classIndex = (int)(item >>> 32); int methodIndex = (int)item; return new MethodReference(classNames[classIndex], MethodDescriptor.parse(methods[methodIndex])); } @@ -372,7 +372,7 @@ public class DebugInformation { int lastClass = -1; for (int i = 0; i < exactMethods.length; ++i) { long exactMethod = exactMethods[i]; - int classIndex = (int)(exactMethod >> 32); + int classIndex = (int)(exactMethod >>> 32); if (classIndex != lastClass) { if (lastClass >= 0) { ClassMetadata clsData = classesMetadata.get(lastClass); @@ -454,6 +454,7 @@ public class DebugInformation { next = new IntegerArray(0); int methodMappingIndex = 0; int classMappingIndex = 0; + GeneratedLocation previousLocation = new GeneratedLocation(0, 0); while (methodMappingIndex < methodMapping.lines.length && classMappingIndex < classMapping.lines.length) { GeneratedLocation methodLoc = new GeneratedLocation(methodMapping.lines[methodMappingIndex], @@ -462,38 +463,39 @@ public class DebugInformation { classMapping.columns[classMappingIndex]); int cmp = methodLoc.compareTo(classLoc); if (cmp < 0) { + addMethodEntrance(previousLocation, methodLoc); + previousLocation = methodLoc; methodIndex = methodMapping.values[methodMappingIndex++]; - addMethodEntrance(methodLoc); } else if (cmp > 0) { + addMethodEntrance(previousLocation, classLoc); + previousLocation = classLoc; classIndex = classMapping.values[classMappingIndex++]; - addMethodEntrance(classLoc); } else { + addMethodEntrance(previousLocation, classLoc); + previousLocation = classLoc; methodIndex = methodMapping.values[methodMappingIndex++]; classIndex = classMapping.values[classMappingIndex++]; - addMethodEntrance(classLoc); } } while (methodMappingIndex < methodMapping.lines.length) { GeneratedLocation methodLoc = new GeneratedLocation(methodMapping.lines[methodMappingIndex], methodMapping.columns[methodMappingIndex]); + addMethodEntrance(previousLocation, methodLoc); + previousLocation = methodLoc; methodIndex = methodMapping.values[methodMappingIndex++]; - addMethodEntrance(methodLoc); } while (classMappingIndex < classMapping.lines.length) { GeneratedLocation classLoc = new GeneratedLocation(classMapping.lines[classMappingIndex], classMapping.columns[classMappingIndex]); + addMethodEntrance(previousLocation, classLoc); + previousLocation = classLoc; classIndex = classMapping.values[classMappingIndex++]; - addMethodEntrance(classLoc); } return assemble(); } - private void addMethodEntrance(GeneratedLocation location) { - int lineIndex = indexByKey(lineMapping, location); - if (lineIndex < 0) { - return; - } - if (lineMapping.values[lineIndex] < 0) { + private void addMethodEntrance(GeneratedLocation location, GeneratedLocation limit) { + if (classIndex < 0 || methodIndex < 0) { return; } long exactMethod = ((long)classIndex << 32) | methodIndex; @@ -501,14 +503,35 @@ public class DebugInformation { if (exactMethodIndex == null) { return; } + + int lineIndex = indexByKey(lineMapping, location); + if (lineIndex < 0) { + lineIndex = 0; + } + int line = -1; + while (lineIndex < lineMapping.values.length) { + location = new GeneratedLocation(lineMapping.lines[lineIndex], lineMapping.columns[lineIndex]); + if (location.compareTo(limit) >= 0) { + break; + } + if (lineMapping.values[lineIndex] >= 0) { + line = lineMapping.values[lineIndex]; + break; + } + ++lineIndex; + } + if (line == -1) { + return; + } + int ptr = start[exactMethodIndex]; start[exactMethodIndex] = data.size(); next.add(ptr); - data.add(location.getColumn()); ptr = data.size(); + data.add(location.getColumn()); next.add(ptr); - data.add(location.getLine()); start[exactMethodIndex] = data.size(); + data.add(location.getLine()); } private MethodEntrances assemble() { @@ -728,7 +751,7 @@ public class DebugInformation { MethodReference[] references = new MethodReference[end - start]; for (int i = 0; i < references.length; ++i) { long item = exactMethods[data[start + i]]; - int classIndex = (int)(item >> 32); + int classIndex = (int)(item >>> 32); int methodIndex = (int)item; references[i] = new MethodReference(classNames[classIndex], MethodDescriptor.parse(methods[methodIndex])); diff --git a/teavm-core/src/main/java/org/teavm/debugging/DebugInformationBuilder.java b/teavm-core/src/main/java/org/teavm/debugging/DebugInformationBuilder.java index ecf49b4fa..07db800e1 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/DebugInformationBuilder.java +++ b/teavm-core/src/main/java/org/teavm/debugging/DebugInformationBuilder.java @@ -90,6 +90,14 @@ public class DebugInformationBuilder implements DebugInformationEmitter { methodMapping.add(locationProvider, methodIndex); currentMethod = method; } + if (currentClass != null) { + int classIndex = classes.index(currentClass); + long fullIndex = ((long)classIndex << 32) | methodIndex; + if (!exactMethodMap.containsKey(fullIndex)) { + exactMethodMap.put(fullIndex, exactMethods.size()); + exactMethods.add(fullIndex); + } + } } @Override @@ -113,7 +121,7 @@ public class DebugInformationBuilder implements DebugInformationEmitter { if (method != null) { int methodIndex = methods.index(method.getDescriptor().toString()); int classIndex = classes.index(method.getClassName()); - long fullIndex = (((long)classIndex << 32) | methodIndex) + 1; + long fullIndex = ((long)classIndex << 32) | methodIndex; Integer exactMethodIndex = exactMethodMap.get(fullIndex); if (exactMethodIndex == null) { exactMethodIndex = exactMethods.size(); diff --git a/teavm-core/src/main/java/org/teavm/debugging/DebugInformationReader.java b/teavm-core/src/main/java/org/teavm/debugging/DebugInformationReader.java index 68173ff9f..aa6dfb74e 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/DebugInformationReader.java +++ b/teavm-core/src/main/java/org/teavm/debugging/DebugInformationReader.java @@ -98,10 +98,12 @@ class DebugInformationReader { int[] lines = new int[readUnsignedNumber()]; int[] files = new int[lines.length]; int i = 0; - int line = 0; - offsets.add(0); + int line = -1; while (i < lines.length) { int passedLines = readUnsignedNumber(); + for (int j = 0; j < passedLines; ++j) { + offsets.add(i); + } line += passedLines; int sz = readUnsignedNumber(); if (sz == 0) { @@ -110,18 +112,17 @@ class DebugInformationReader { } else if (sz == 1) { lines[i] = line + 1; files[i++] = index; - } - sz -= 1; - int last = line; - for (int j = 0; j < sz; ++j) { - last += readNumber(); - lines[i] = last; - files[i++] = index + readNumber(); - } - for (int j = 0; j < passedLines; ++j) { - offsets.add(i); + } else { + sz -= 1; + int last = line; + for (int j = 0; j < sz; ++j) { + last += readNumber(); + lines[i] = last; + files[i++] = index + readNumber(); + } } } + offsets.add(i); DebugInformation.CFG cfg = new DebugInformation.CFG(); cfg.offsets = offsets.getAll(); cfg.lines = lines; diff --git a/teavm-core/src/main/java/org/teavm/debugging/DebugInformationWriter.java b/teavm-core/src/main/java/org/teavm/debugging/DebugInformationWriter.java index 40ac27aa7..290146af2 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/DebugInformationWriter.java +++ b/teavm-core/src/main/java/org/teavm/debugging/DebugInformationWriter.java @@ -165,7 +165,7 @@ class DebugInformationWriter { private void writeCFG(DebugInformation.CFG mapping, int fileIndex) throws IOException { writeUnsignedNumber(mapping.lines.length); - int lastLine = 0; + int lastLine = -1; for (int i = 0; i < mapping.offsets.length - 1; ++i) { int start = mapping.offsets[i]; int sz = mapping.offsets[i + 1] - start; diff --git a/teavm-core/src/main/java/org/teavm/debugging/Debugger.java b/teavm-core/src/main/java/org/teavm/debugging/Debugger.java index e2eb4709f..dfd9258ba 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/Debugger.java +++ b/teavm-core/src/main/java/org/teavm/debugging/Debugger.java @@ -102,8 +102,9 @@ public class Debugger { GeneratedLocation genLoc = new GeneratedLocation(frame.originalLocation.getLine(), frame.originalLocation.getColumn()); MethodReference callMethod = mainDebugInfo != null ? mainDebugInfo.getCallSite(genLoc) : null; - for (Map.Entry entry : debugInformationMap.entrySet()) { - DebugInformation debugInfo = entry.getValue(); + String script = frame.originalLocation.getScript(); + DebugInformation debugInfo = debugInformationMap.get(script); + if (debugInfo != null) { SourceLocation[] following = debugInfo.getFollowingLines(frame.getLocation()); if (following != null) { for (SourceLocation successor : following) { @@ -111,7 +112,7 @@ public class Debugger { exits = true; } else { for (GeneratedLocation loc : debugInfo.getGeneratedLocations(successor)) { - successors.add(new JavaScriptLocation(entry.getKey(), loc.getLine(), loc.getColumn())); + successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn())); } } } @@ -119,7 +120,7 @@ public class Debugger { if (enterMethod && callMethod != null) { for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callMethod)) { for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) { - successors.add(new JavaScriptLocation(entry.getKey(), loc.getLine(), loc.getColumn())); + successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn())); } } }