mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 07:54:11 -08:00
Start refactoring of debug information
This commit is contained in:
parent
7e1ff76c5d
commit
88c47095a6
|
@ -76,7 +76,18 @@ public class RecordArrayBuilder {
|
|||
}
|
||||
builtSubstart[i + 1] = builtSubdata.size();
|
||||
}
|
||||
return new RecordArray(recordSize, arraysPerRecord, size, data.getAll(), builtSubstart, builtSubdata.getAll());
|
||||
int[] builtSubdataArray = builtSubdata.getAll();
|
||||
for (int i = 1; i < builtSubstart.length; ++i) {
|
||||
int start = builtSubstart[i - 1];
|
||||
int end = builtSubstart[i];
|
||||
int h = (builtSubstart[i] - start) / 2;
|
||||
for (int j = 0; j < h; ++j) {
|
||||
int tmp = builtSubdataArray[start + j];
|
||||
builtSubdataArray[start + j] = builtSubdataArray[end - j - 1];
|
||||
builtSubdataArray[end - j - 1] = tmp;
|
||||
}
|
||||
}
|
||||
return new RecordArray(recordSize, arraysPerRecord, size, data.getAll(), builtSubstart, builtSubdataArray);
|
||||
}
|
||||
|
||||
public class Record {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class ClassNameIterator {
|
||||
|
||||
}
|
|
@ -40,41 +40,56 @@ public class DebugInformation {
|
|||
Map<String, Integer> variableNameMap;
|
||||
long[] exactMethods;
|
||||
Map<Long, Integer> exactMethodMap;
|
||||
FileDescription[] fileDescriptions;
|
||||
Mapping fileMapping;
|
||||
Mapping classMapping;
|
||||
Mapping methodMapping;
|
||||
Mapping lineMapping;
|
||||
Mapping callSiteMapping;
|
||||
RecordArray[] fileDescriptions;
|
||||
RecordArray fileMapping;
|
||||
RecordArray classMapping;
|
||||
RecordArray methodMapping;
|
||||
RecordArray lineMapping;
|
||||
RecordArray callSiteMapping;
|
||||
MultiMapping[] variableMappings;
|
||||
RecordArray[] lineCallSites;
|
||||
CFG[] controlFlowGraphs;
|
||||
List<ClassMetadata> classesMetadata;
|
||||
MethodEntrances methodEntrances;
|
||||
RecordArray methodEntrances;
|
||||
MethodTree methodTree;
|
||||
|
||||
public String[] getCoveredSourceFiles() {
|
||||
public String[] getFilesNames() {
|
||||
return fileNames.clone();
|
||||
}
|
||||
|
||||
public String[] getVariableNames() {
|
||||
return variableNames.clone();
|
||||
}
|
||||
|
||||
public LineNumberIterator iterateOverLineNumbers() {
|
||||
return new LineNumberIterator(this);
|
||||
}
|
||||
|
||||
public FileNameIterator iterateOverFileNames() {
|
||||
return new FileNameIterator(this);
|
||||
}
|
||||
|
||||
public String getFileName(int fileNameId) {
|
||||
return fileNames[fileNameId];
|
||||
}
|
||||
|
||||
public Collection<GeneratedLocation> getGeneratedLocations(String fileName, int line) {
|
||||
Integer fileIndex = fileNameMap.get(fileName);
|
||||
if (fileIndex == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
FileDescription description = fileIndex >= 0 ? fileDescriptions[fileIndex] : null;
|
||||
RecordArray description = fileIndex >= 0 ? fileDescriptions[fileIndex] : null;
|
||||
if (description == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (line >= description.generatedLocationStart.length - 1) {
|
||||
if (line >= description.size()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
int start = description.generatedLocationStart[line];
|
||||
int end = description.generatedLocationStart[line + 1];
|
||||
GeneratedLocation[] resultArray = new GeneratedLocation[(end - start) / 2];
|
||||
int[] data = description.get(line).getArray(0);
|
||||
GeneratedLocation[] resultArray = new GeneratedLocation[data.length / 2];
|
||||
for (int i = 0; i < resultArray.length; ++i) {
|
||||
int genLine = description.generatedLocationData[start++];
|
||||
int genColumn = description.generatedLocationData[start++];
|
||||
int genLine = data[i * 2];
|
||||
int genColumn = data[i * 2 + 1];
|
||||
resultArray[i] = new GeneratedLocation(genLine, genColumn);
|
||||
}
|
||||
return Arrays.asList(resultArray);
|
||||
|
@ -84,6 +99,10 @@ public class DebugInformation {
|
|||
return getGeneratedLocations(sourceLocation.getFileName(), sourceLocation.getLine());
|
||||
}
|
||||
|
||||
public SourceLocationIterator iterateOverSourceLocations() {
|
||||
return new SourceLocationIterator(this);
|
||||
}
|
||||
|
||||
public SourceLocation getSourceLocation(int line, int column) {
|
||||
return getSourceLocation(new GeneratedLocation(line, column));
|
||||
}
|
||||
|
@ -91,7 +110,7 @@ public class DebugInformation {
|
|||
public SourceLocation getSourceLocation(GeneratedLocation generatedLocation) {
|
||||
String fileName = componentByKey(fileMapping, fileNames, generatedLocation);
|
||||
int lineNumberIndex = indexByKey(lineMapping, generatedLocation);
|
||||
int lineNumber = lineNumberIndex >= 0 ? lineMapping.values[lineNumberIndex] : -1;
|
||||
int lineNumber = lineNumberIndex >= 0 ? lineMapping.get(lineNumberIndex).get(2) : -1;
|
||||
return new SourceLocation(fileName, lineNumber);
|
||||
}
|
||||
|
||||
|
@ -178,34 +197,31 @@ public class DebugInformation {
|
|||
return null;
|
||||
}
|
||||
|
||||
public MethodReference getCallSite(GeneratedLocation location) {
|
||||
public DebuggerCallSite getCallSite(GeneratedLocation location) {
|
||||
int keyIndex = indexByKey(callSiteMapping, location);
|
||||
if (keyIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
int valueIndex = callSiteMapping.values[keyIndex];
|
||||
if (valueIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
return getExactMethod(valueIndex);
|
||||
return keyIndex >= 0 ? getCallSite(keyIndex) : null;
|
||||
}
|
||||
|
||||
public MethodReference getCallSite(int line, int column) {
|
||||
private DebuggerCallSite getCallSite(int index) {
|
||||
RecordArray.Record record = callSiteMapping.get(index);
|
||||
int type = record.get(0);
|
||||
int[] data = record.getArray(0);
|
||||
switch (type) {
|
||||
case DebuggerCallSite.NONE:
|
||||
return null;
|
||||
case DebuggerCallSite.STATIC:
|
||||
return new DebuggerStaticCallSite(getExactMethod(data[0]));
|
||||
case DebuggerCallSite.VIRTUAL:
|
||||
return new DebuggerVirtualCallSite(getExactMethod(data[0]), data[1], variableNames[data[1]]);
|
||||
default:
|
||||
throw new AssertionError("Unrecognized call site type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public DebuggerCallSite getCallSite(int line, int column) {
|
||||
return getCallSite(new GeneratedLocation(line, column));
|
||||
}
|
||||
|
||||
public GeneratedLocation[] getCallSiteEntrances(GeneratedLocation location) {
|
||||
MethodReference method = getCallSite(location);
|
||||
if (method == null) {
|
||||
return null;
|
||||
}
|
||||
Set<GeneratedLocation> locations = new HashSet<>();
|
||||
for (MethodReference overriding : getOverridingMethods(method)) {
|
||||
locations.addAll(Arrays.asList(getMethodEntrances(overriding)));
|
||||
}
|
||||
return locations.toArray(new GeneratedLocation[0]);
|
||||
}
|
||||
|
||||
public GeneratedLocation[] getMethodEntrances(MethodReference methodRef) {
|
||||
Integer index = getExactMethodIndex(methodRef);
|
||||
if (index == null) {
|
||||
|
@ -261,27 +277,26 @@ public class DebugInformation {
|
|||
}
|
||||
}
|
||||
|
||||
public MethodReference[] getCallSites(SourceLocation location) {
|
||||
public DebuggerCallSite[] getCallSites(SourceLocation location) {
|
||||
Integer fileIndex = fileNameMap.get(location.getFileName());
|
||||
if (fileIndex == null) {
|
||||
return new MethodReference[0];
|
||||
return new DebuggerCallSite[0];
|
||||
}
|
||||
RecordArray mapping = lineCallSites[fileIndex];
|
||||
if (location.getLine() >= mapping.size()) {
|
||||
return new MethodReference[0];
|
||||
return new DebuggerCallSite[0];
|
||||
}
|
||||
int[] callSiteIds = mapping.get(location.getLine()).getArray(0);
|
||||
MethodReference[] methods = new MethodReference[callSiteIds.length];
|
||||
DebuggerCallSite[] callSites = new DebuggerCallSite[callSiteIds.length];
|
||||
for (int i = 0; i < callSiteIds.length; ++i) {
|
||||
int exactMethodId = callSiteMapping.values[callSiteIds[i]];
|
||||
methods[i] = getExactMethod(exactMethodId);
|
||||
callSites[i] = getCallSite(callSiteIds[i]);
|
||||
}
|
||||
return methods;
|
||||
return callSites;
|
||||
}
|
||||
|
||||
private <T> T componentByKey(Mapping mapping, T[] values, GeneratedLocation location) {
|
||||
private <T> T componentByKey(RecordArray mapping, T[] values, GeneratedLocation location) {
|
||||
int keyIndex = indexByKey(mapping, location);
|
||||
int valueIndex = keyIndex >= 0 ? mapping.values[keyIndex] : -1;
|
||||
int valueIndex = keyIndex >= 0 ? mapping.get(keyIndex).get(2) : -1;
|
||||
return valueIndex >= 0 ? values[valueIndex] : null;
|
||||
}
|
||||
|
||||
|
@ -299,14 +314,14 @@ public class DebugInformation {
|
|||
return result;
|
||||
}
|
||||
|
||||
private int indexByKey(Mapping mapping, GeneratedLocation location) {
|
||||
int index = Collections.binarySearch(mapping.keyList(), location);
|
||||
private int indexByKey(RecordArray mapping, GeneratedLocation location) {
|
||||
int index = Collections.binarySearch(new LocationList(mapping), location);
|
||||
return index >= 0 ? index : -index - 2;
|
||||
}
|
||||
|
||||
private int valueByKey(Mapping mapping, GeneratedLocation location) {
|
||||
private int valueByKey(RecordArray mapping, GeneratedLocation location) {
|
||||
int index = indexByKey(mapping, location);
|
||||
return index >= 0 ? mapping.values[index] : -1;
|
||||
return index >= 0 ? mapping.get(index).get(2) : -1;
|
||||
}
|
||||
|
||||
private int indexByKey(MultiMapping mapping, GeneratedLocation location) {
|
||||
|
@ -363,33 +378,41 @@ public class DebugInformation {
|
|||
int currentFile = -1;
|
||||
int currentLine = -1;
|
||||
while (fileIndex < fileMapping.size() && lineIndex < lineMapping.size()) {
|
||||
GeneratedLocation fileLoc = fileMapping.key(fileIndex);
|
||||
GeneratedLocation lineLoc = lineMapping.key(lineIndex);
|
||||
RecordArray.Record fileRec = fileMapping.get(fileIndex);
|
||||
RecordArray.Record lineRec = lineMapping.get(lineIndex);
|
||||
GeneratedLocation fileLoc = key(fileRec);
|
||||
GeneratedLocation lineLoc = key(lineRec);
|
||||
int cmp = fileLoc.compareTo(lineLoc);
|
||||
if (cmp < 0) {
|
||||
currentFile = fileMapping.values[fileIndex++];
|
||||
currentFile = fileRec.get(2);
|
||||
fileIndex++;
|
||||
} else if (cmp > 0){
|
||||
currentLine = lineMapping.values[lineIndex++];
|
||||
currentLine = lineRec.get(2);
|
||||
lineIndex++;
|
||||
} else {
|
||||
currentFile = fileMapping.values[fileIndex++];
|
||||
currentLine = lineMapping.values[lineIndex++];
|
||||
currentFile = fileRec.get(2);
|
||||
currentLine = lineRec.get(2);
|
||||
fileIndex++;
|
||||
lineIndex++;
|
||||
}
|
||||
builder.emit(fileLoc.getLine(), fileLoc.getColumn(), currentFile, currentLine);
|
||||
}
|
||||
while (fileIndex < fileMapping.size()) {
|
||||
builder.emit(fileMapping.lines[fileIndex], fileMapping.columns[fileIndex],
|
||||
fileMapping.values[fileIndex], currentLine);
|
||||
++fileIndex;
|
||||
RecordArray.Record fileRec = fileMapping.get(fileIndex++);
|
||||
builder.emit(fileRec.get(0), fileRec.get(1), fileRec.get(2), currentLine);
|
||||
}
|
||||
while (lineIndex < lineMapping.size()) {
|
||||
builder.emit(lineMapping.lines[lineIndex], lineMapping.columns[lineIndex], currentFile,
|
||||
lineMapping.values[lineIndex]);
|
||||
++lineIndex;
|
||||
RecordArray.Record lineRec = lineMapping.get(lineIndex++);
|
||||
builder.emit(lineRec.get(0), lineRec.get(1), currentFile, lineRec.get(2));
|
||||
}
|
||||
fileDescriptions = builder.build();
|
||||
}
|
||||
|
||||
void rebuildEntrances() {
|
||||
RecordArrayBuilder builder = new RecordArrayBuilder(0, 1);
|
||||
for (SourceLocationIterator iter = iterateOverSourceLocations(); !iter.isEndReached(); iter.next()) {
|
||||
iter.getLocation();
|
||||
}
|
||||
methodEntrances = new MethodEntrancesBuilder().build();
|
||||
}
|
||||
|
||||
|
@ -472,10 +495,11 @@ public class DebugInformation {
|
|||
for (int i = 0; i < lineCallSites.length; ++i) {
|
||||
builders[i] = new RecordArrayBuilder(0, 1);
|
||||
}
|
||||
for (int i = 0; i < callSiteMapping.lines.length; ++i) {
|
||||
GeneratedLocation loc = callSiteMapping.key(i);
|
||||
int methodId = callSiteMapping.values[i];
|
||||
if (methodId >= 0) {
|
||||
for (int i = 0; i < callSiteMapping.size(); ++i) {
|
||||
RecordArray.Record callSiteRec = callSiteMapping.get(i);
|
||||
GeneratedLocation loc = key(callSiteRec);
|
||||
int callSiteType = callSiteRec.get(2);
|
||||
if (callSiteType != DebuggerCallSite.NONE) {
|
||||
int line = valueByKey(lineMapping, loc);
|
||||
int fileId = valueByKey(fileMapping, loc);
|
||||
if (fileId >= 0 && line >= 0) {
|
||||
|
@ -606,14 +630,14 @@ public class DebugInformation {
|
|||
}
|
||||
|
||||
static class FileDescriptionBuilder {
|
||||
FileDescriptionProto[] files;
|
||||
RecordArrayBuilder[] files;
|
||||
int lastFileIndex = -1;
|
||||
int lastSourceLine = -1;
|
||||
|
||||
public FileDescriptionBuilder(int size) {
|
||||
files = new FileDescriptionProto[size];
|
||||
files = new RecordArrayBuilder[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
files[i] = new FileDescriptionProto();
|
||||
files[i] = new RecordArrayBuilder(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,12 +650,17 @@ public class DebugInformation {
|
|||
}
|
||||
lastFileIndex = fileIndex;
|
||||
lastSourceLine = sourceLine;
|
||||
FileDescriptionProto proto = files[fileIndex];
|
||||
proto.addLocation(sourceLine, line, column);
|
||||
RecordArrayBuilder proto = files[fileIndex];
|
||||
while (proto.size() <= sourceLine) {
|
||||
proto.add();
|
||||
}
|
||||
RecordArrayBuilder.RecordSubArray array = proto.get(sourceLine).getArray(0);
|
||||
array.add(line);
|
||||
array.add(column);
|
||||
}
|
||||
|
||||
public FileDescription[] build() {
|
||||
FileDescription[] descriptions = new FileDescription[files.length];
|
||||
public RecordArray[] build() {
|
||||
RecordArray[] descriptions = new RecordArray[files.length];
|
||||
for (int i = 0; i < files.length; ++i) {
|
||||
descriptions[i] = files[i].build();
|
||||
}
|
||||
|
@ -639,81 +668,8 @@ public class DebugInformation {
|
|||
}
|
||||
}
|
||||
|
||||
static class FileDescriptionProto {
|
||||
IntegerArray generatedLocationData = new IntegerArray(1);
|
||||
IntegerArray generatedLocationPointers = new IntegerArray(1);
|
||||
IntegerArray generatedLocationStart = new IntegerArray(1);
|
||||
IntegerArray generatedLocationSize = new IntegerArray(1);
|
||||
|
||||
public void addLocation(int sourceLine, int line, int column) {
|
||||
ensureLine(sourceLine);
|
||||
generatedLocationSize.set(sourceLine, generatedLocationSize.get(sourceLine) + 1);
|
||||
int slot = generatedLocationStart.get(sourceLine);
|
||||
slot = addData(slot, line);
|
||||
slot = addData(slot, column);
|
||||
generatedLocationStart.set(sourceLine, slot);
|
||||
}
|
||||
|
||||
int addData(int slot, int value) {
|
||||
int result = generatedLocationData.size();
|
||||
generatedLocationData.add(value);
|
||||
generatedLocationPointers.add(slot);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ensureLine(int sourceLine) {
|
||||
while (sourceLine >= generatedLocationSize.size()) {
|
||||
generatedLocationSize.add(0);
|
||||
generatedLocationStart.add(-1);
|
||||
}
|
||||
}
|
||||
|
||||
FileDescription build() {
|
||||
FileDescription description = new FileDescription();
|
||||
description.generatedLocationData = new int[generatedLocationData.size()];
|
||||
description.generatedLocationStart = new int[generatedLocationStart.size() + 1];
|
||||
int current = 0;
|
||||
for (int i = 0; i < generatedLocationStart.size(); ++i) {
|
||||
current += generatedLocationSize.get(i) * 2;
|
||||
int j = current;
|
||||
int ptr = generatedLocationStart.get(i);
|
||||
while (ptr >= 0) {
|
||||
description.generatedLocationData[--j] = generatedLocationData.get(ptr);
|
||||
ptr = generatedLocationPointers.get(ptr);
|
||||
}
|
||||
description.generatedLocationStart[i + 1] = current;
|
||||
}
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
static class FileDescription {
|
||||
int[] generatedLocationData;
|
||||
int[] generatedLocationStart;
|
||||
}
|
||||
|
||||
static class Mapping {
|
||||
int[] lines;
|
||||
int[] columns;
|
||||
int[] values;
|
||||
|
||||
public Mapping(int[] lines, int[] columns, int[] values) {
|
||||
this.lines = lines;
|
||||
this.columns = columns;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public LocationList keyList() {
|
||||
return new LocationList(lines, columns);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return lines.length;
|
||||
}
|
||||
|
||||
public GeneratedLocation key(int index) {
|
||||
return new GeneratedLocation(lines[index], columns[index]);
|
||||
}
|
||||
static GeneratedLocation key(RecordArray.Record record) {
|
||||
return new GeneratedLocation(record.get(0), record.get(1));
|
||||
}
|
||||
|
||||
static class MultiMapping {
|
||||
|
@ -743,22 +699,21 @@ public class DebugInformation {
|
|||
}
|
||||
|
||||
static class LocationList extends AbstractList<GeneratedLocation> {
|
||||
private int[] lines;
|
||||
private int[] columns;
|
||||
private RecordArray recordArray;
|
||||
|
||||
public LocationList(int[] lines, int[] columns) {
|
||||
this.lines = lines;
|
||||
this.columns = columns;
|
||||
public LocationList(RecordArray recordArray) {
|
||||
this.recordArray = recordArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeneratedLocation get(int index) {
|
||||
return new GeneratedLocation(lines[index], columns[index]);
|
||||
RecordArray.Record record = recordArray.get(index);
|
||||
return new GeneratedLocation(record.get(0), record.get(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return lines.length;
|
||||
return recordArray.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,24 +729,6 @@ public class DebugInformation {
|
|||
int[] offsets;
|
||||
}
|
||||
|
||||
static class MethodEntrances {
|
||||
int[] data;
|
||||
int[] offsets;
|
||||
|
||||
public GeneratedLocation[] getEntrances(int index) {
|
||||
if (index < 0 || index > offsets.length - 1) {
|
||||
return new GeneratedLocation[0];
|
||||
}
|
||||
int start = offsets[index];
|
||||
int end = offsets[index + 1];
|
||||
GeneratedLocation[] result = new GeneratedLocation[(end - start) / 2];
|
||||
for (int i = 0; i < result.length; ++i) {
|
||||
result[i] = new GeneratedLocation(data[start + i * 2], data[start + i * 2 + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class MethodTree {
|
||||
int[] data;
|
||||
int[] offsets;
|
||||
|
|
|
@ -291,7 +291,7 @@ public class Debugger {
|
|||
updateBreakpoints();
|
||||
return;
|
||||
}
|
||||
for (String sourceFile : debugInfo.getCoveredSourceFiles()) {
|
||||
for (String sourceFile : debugInfo.getFilesNames()) {
|
||||
ConcurrentMap<DebugInformation, Object> list = debugInformationFileMap.get(sourceFile);
|
||||
if (list == null) {
|
||||
list = new ConcurrentHashMap<>();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public abstract class DebuggerCallSite {
|
||||
static final int NONE = 0;
|
||||
static final int STATIC = 1;
|
||||
static final int VIRTUAL = 2;
|
||||
|
||||
public abstract void acceptVisitor(DebuggerCallSiteVisitor visitor);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public interface DebuggerCallSiteVisitor {
|
||||
void visit(DebuggerVirtualCallSite callSite);
|
||||
|
||||
void visit(DebuggerStaticCallSite callSite);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class DebuggerStaticCallSite extends DebuggerCallSite {
|
||||
private MethodReference method;
|
||||
|
||||
DebuggerStaticCallSite(MethodReference method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public MethodReference getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(DebuggerCallSiteVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class DebuggerVirtualCallSite extends DebuggerCallSite {
|
||||
private MethodReference method;
|
||||
private int variableId;
|
||||
private String variableName;
|
||||
|
||||
DebuggerVirtualCallSite(MethodReference method, int variableId, String variableName) {
|
||||
this.method = method;
|
||||
this.variableId = variableId;
|
||||
this.variableName = variableName;
|
||||
}
|
||||
|
||||
public MethodReference getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(MethodReference method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public int getVariableId() {
|
||||
return variableId;
|
||||
}
|
||||
|
||||
public void setVariableId(int variableId) {
|
||||
this.variableId = variableId;
|
||||
}
|
||||
|
||||
public String getVariableName() {
|
||||
return variableName;
|
||||
}
|
||||
|
||||
public void setVariableName(String variableName) {
|
||||
this.variableName = variableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(DebuggerCallSiteVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class FileNameIterator {
|
||||
private DebugInformation debugInformation;
|
||||
private int index;
|
||||
|
||||
FileNameIterator(DebugInformation debugInformation) {
|
||||
this.debugInformation = debugInformation;
|
||||
}
|
||||
|
||||
public boolean isEndReached() {
|
||||
return index < debugInformation.fileMapping.size();
|
||||
}
|
||||
|
||||
public GeneratedLocation getLocation() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return DebugInformation.key(debugInformation.fileMapping.get(index));
|
||||
}
|
||||
|
||||
public int getFileNameId() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return debugInformation.fileMapping.get(index).get(2);
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
int fileNameId = getFileNameId();
|
||||
return fileNameId >= 0 ? debugInformation.getFileName(fileNameId) : null;
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class LineNumberIterator {
|
||||
private DebugInformation debugInformation;
|
||||
private int index;
|
||||
|
||||
LineNumberIterator(DebugInformation debugInformation) {
|
||||
this.debugInformation = debugInformation;
|
||||
}
|
||||
|
||||
public boolean isEndReached() {
|
||||
return index < debugInformation.lineMapping.size();
|
||||
}
|
||||
|
||||
public GeneratedLocation getLocation() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return DebugInformation.key(debugInformation.lineMapping.get(index));
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return debugInformation.lineMapping.get(index).get(2);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
import org.teavm.common.RecordArray;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class SourceLocationIterator {
|
||||
private DebugInformation debugInformation;
|
||||
private int lineIndex;
|
||||
private int fileIndex;
|
||||
private GeneratedLocation location;
|
||||
private int fileId = -1;
|
||||
private int line = -1;
|
||||
private boolean endReached;
|
||||
|
||||
SourceLocationIterator(DebugInformation debugInformation) {
|
||||
this.debugInformation = debugInformation;
|
||||
read();
|
||||
}
|
||||
|
||||
public boolean isEndReached() {
|
||||
return endReached;
|
||||
}
|
||||
|
||||
private void read() {
|
||||
if (lineIndex >= debugInformation.lineMapping.size()) {
|
||||
nextFileRecord();
|
||||
} else if (fileIndex >= debugInformation.fileMapping.size()) {
|
||||
nextLineRecord();
|
||||
} else if (fileIndex < debugInformation.fileMapping.size() &&
|
||||
lineIndex < debugInformation.lineMapping.size()) {
|
||||
RecordArray.Record fileRecord = debugInformation.fileMapping.get(fileIndex++);
|
||||
RecordArray.Record lineRecord = debugInformation.lineMapping.get(lineIndex++);
|
||||
GeneratedLocation fileLoc = DebugInformation.key(fileRecord);
|
||||
GeneratedLocation lineLoc = DebugInformation.key(lineRecord);
|
||||
int cmp = fileLoc.compareTo(lineLoc);
|
||||
if (cmp < 0) {
|
||||
nextFileRecord();
|
||||
} else if (cmp > 0) {
|
||||
nextLineRecord();
|
||||
} else {
|
||||
nextFileRecord();
|
||||
nextLineRecord();
|
||||
}
|
||||
} else {
|
||||
endReached = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void nextFileRecord() {
|
||||
RecordArray.Record record = debugInformation.fileMapping.get(fileIndex++);
|
||||
location = DebugInformation.key(record);
|
||||
fileId = record.get(2);
|
||||
}
|
||||
|
||||
private void nextLineRecord() {
|
||||
RecordArray.Record record = debugInformation.lineMapping.get(lineIndex++);
|
||||
location = DebugInformation.key(record);
|
||||
line = record.get(2);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
read();
|
||||
}
|
||||
|
||||
public GeneratedLocation getLocation() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public int getFileNameId() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
int fileId = getFileNameId();
|
||||
return fileId >= 0 ? debugInformation.getFileName(fileId) : null;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
if (isEndReached()) {
|
||||
throw new IllegalStateException("End already reached");
|
||||
}
|
||||
return line;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user