Refactored debugger source map builder

master
Marco Maccaferri 2019-02-05 10:01:59 +01:00
rodzic 228160fb62
commit fc0b5db0a7
4 zmienionych plików z 175 dodań i 68 usunięć

Wyświetl plik

@ -27,10 +27,8 @@ import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.databinding.observable.Realm;
@ -89,6 +87,7 @@ import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import com.maccasoft.tools.SourceMap.LineEntry;
import com.maccasoft.tools.editor.Z80TokenMarker;
import com.maccasoft.tools.internal.BusyIndicator;
import com.maccasoft.tools.internal.ImageRegistry;
@ -134,19 +133,7 @@ public class Application {
Z80 proc;
MemIoOps memIoOps;
int entryAddress;
class LineEntry {
int lineNumber;
Line line;
LineEntry(int lineNumber, Line line) {
this.lineNumber = lineNumber;
this.line = line;
}
}
Map<Integer, LineEntry> list;
SourceMap sourceMap;
int stepOverPC1;
int stepOverPC2;
@ -2518,27 +2505,15 @@ public class Application {
});
proc.setBreakpoint(0x0005, true);
list = new HashMap<Integer, LineEntry>();
entryAddress = -1;
int lineNumber = 0;
for (Line line : source.getLines()) {
int address = line.getScope().getAddress();
byte[] code = line.getBytes();
if (code.length != 0 && entryAddress == -1) {
entryAddress = address;
}
System.arraycopy(code, 0, memIoOps.getRam(), address, code.length);
list.put(address, new LineEntry(lineNumber++, line));
}
sourceMap = new SourceMap(source, memIoOps);
sourceMap.build();
display.syncExec(new Runnable() {
@Override
public void run() {
memory.setData(memIoOps.getRam());
viewer.setSource(source);
viewer.setSourceMap(sourceMap);
handleReset();
reparentControls();
@ -2613,9 +2588,9 @@ public class Application {
proc.setPinReset();
proc.reset();
proc.setRegPC(entryAddress);
proc.setRegPC(sourceMap.getEntryAddress());
memory.setSelection(entryAddress);
memory.setSelection(sourceMap.getEntryAddress());
updateDebuggerState();
}
@ -2625,16 +2600,16 @@ public class Application {
memory.clearUpdates();
viewer.getControl().setFocus();
LineEntry lineEntry = list.get(proc.getRegPC());
LineEntry lineEntry = sourceMap.getLineAtAddress(proc.getRegPC());
if (lineEntry != null) {
stepOverPC1 = proc.getRegPC() + lineEntry.line.getSize();
stepOverPC1 = proc.getRegPC() + lineEntry.code.length;
stepOverPC2 = memIoOps.peek16(proc.getRegSP());
stepOverSP = proc.getRegSP();
boolean repeat = isRepeatInstruction();
proc.execute();
if (repeat || list.get(proc.getRegPC()) == null) {
if (repeat || sourceMap.getLineAtAddress(proc.getRegPC()) == null) {
display.asyncExec(stepOverRunnable);
return;
}
@ -2670,9 +2645,9 @@ public class Application {
memory.clearUpdates();
viewer.getControl().setFocus();
LineEntry lineEntry = list.get(proc.getRegPC());
LineEntry lineEntry = sourceMap.getLineAtAddress(proc.getRegPC());
if (lineEntry != null) {
stepOverPC1 = proc.getRegPC() + lineEntry.line.getSize();
stepOverPC1 = proc.getRegPC() + lineEntry.code.length;
stepOverPC2 = memIoOps.peek16(proc.getRegSP());
stepOverSP = proc.getRegSP();
display.asyncExec(stepOverRunnable);
@ -2691,10 +2666,10 @@ public class Application {
int caretOffset = viewer.getStyledText().getCaretOffset();
int lineAtOffset = viewer.getStyledText().getLineAtOffset(caretOffset);
Line line = viewer.getSource().getLines().get(lineAtOffset);
LineEntry lineEntry = viewer.getSourceMap().getLines().get(lineAtOffset);
if (line.getScope().getAddress() != proc.getRegPC()) {
stepOverPC1 = line.getScope().getAddress();
if (lineEntry.address != proc.getRegPC()) {
stepOverPC1 = lineEntry.address;
display.asyncExec(runToLineRunnable);
}
}
@ -2709,9 +2684,9 @@ public class Application {
int caretOffset = viewer.getStyledText().getCaretOffset();
int lineAtOffset = viewer.getStyledText().getLineAtOffset(caretOffset);
Line line = viewer.getSource().getLines().get(lineAtOffset);
if (line != null) {
int address = line.getScope().getAddress();
LineEntry lineEntry = viewer.getSourceMap().getLines().get(lineAtOffset);
if (lineEntry != null) {
int address = lineEntry.address;
viewer.toggleBreakpoint(address);
proc.setBreakpoint(address, viewer.isBreakpoint(address));
}
@ -2735,7 +2710,7 @@ public class Application {
memory.update();
registers.updateRegisters(proc);
LineEntry lineEntry = list.get(proc.getRegPC());
LineEntry lineEntry = sourceMap.getLineAtAddress(proc.getRegPC());
if (lineEntry != null) {
viewer.gotToLineColumn(lineEntry.lineNumber, 0);
}

Wyświetl plik

@ -30,8 +30,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
import nl.grauw.glass.Line;
import nl.grauw.glass.Source;
import com.maccasoft.tools.SourceMap.LineEntry;
public class CodeRuler {
@ -40,7 +39,7 @@ public class CodeRuler {
FontMetrics fontMetrics;
StyledText text;
Source source;
SourceMap sourceMap;
boolean[] breakpoint;
int leftMargin;
@ -119,8 +118,8 @@ public class CodeRuler {
this.text.addCaretListener(caretListener);
}
public void setSource(Source source) {
this.source = source;
public void setSourceMap(SourceMap sourceMap) {
this.sourceMap = sourceMap;
}
void onPaintControl(GC gc) {
@ -136,18 +135,16 @@ public class CodeRuler {
break;
}
if (source != null && lineNumber >= 0 && lineNumber < source.getLines().size()) {
Line line = source.getLines().get(lineNumber);
int address = line.getScope().getAddress();
byte[] code = line.getBytes();
if (sourceMap != null && lineNumber >= 0 && lineNumber < sourceMap.getLines().size()) {
LineEntry line = sourceMap.getLine(lineNumber);
StringBuilder sb = new StringBuilder();
sb.append(String.format("%04X ", line.getScope().getAddress()));
for (int i = 0; i < code.length; i++) {
sb.append(String.format("%04X ", line.address));
for (int i = 0; i < line.code.length; i++) {
if (i != 0) {
sb.append(' ');
}
sb.append(String.format("%02X", code[i]));
sb.append(String.format("%02X", line.code[i]));
}
if (lineNumber == currentLine) {
gc.setBackground(currentLineBackground);
@ -156,7 +153,7 @@ public class CodeRuler {
else {
gc.setBackground(canvas.getBackground());
}
gc.setFont((breakpoint[address] && code.length != 0) ? fontBold : font);
gc.setFont((breakpoint[line.address] && line.code.length != 0) ? fontBold : font);
gc.drawString(sb.toString(), leftMargin, y, true);
}

Wyświetl plik

@ -0,0 +1,137 @@
/*
* Copyright (c) 2018-19 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nl.grauw.glass.AssemblyException;
import nl.grauw.glass.Line;
import nl.grauw.glass.Scope;
import nl.grauw.glass.Source;
import nl.grauw.glass.directives.If;
import z80core.MemIoOps;
public class SourceMap {
Source source;
MemIoOps memIoOps;
int address;
int entryAddress;
public static class LineEntry {
public final Line line;
public final int lineNumber;
public final int address;
public final byte[] code;
public LineEntry(int lineNumber, int address, Line line) {
this.line = line;
this.address = address;
this.lineNumber = lineNumber;
Scope scope = line.getScope();
if (line.getDirective() instanceof If) {
this.code = new byte[0];
}
else if (scope.isAddressSet()) {
this.code = line.getBytes();
}
else {
this.code = new byte[0];
}
}
}
Map<Integer, LineEntry> map;
List<LineEntry> list;
public SourceMap(Source source, MemIoOps memIoOps) {
this.source = source;
this.memIoOps = memIoOps;
}
public void build() {
address = 0;
entryAddress = -1;
list = new ArrayList<LineEntry>();
map = new HashMap<Integer, LineEntry>();
build(source, 0);
}
int build(Source source, int lineNumber) {
for (Line line : source.getLines()) {
try {
if (line.getScope().isAddressSet()) {
address = line.getScope().getAddress();
}
LineEntry lineEntry = new LineEntry(lineNumber++, address, line);
if (lineEntry.code.length != 0) {
if (entryAddress == -1) {
entryAddress = address;
}
System.arraycopy(lineEntry.code, 0, memIoOps.getRam(), lineEntry.address, lineEntry.code.length);
map.put(lineEntry.address, lineEntry);
}
list.add(lineEntry);
if (line.getDirective() instanceof If) {
if (line.getInstructionObject() != null) {
nl.grauw.glass.instructions.If ins = (nl.grauw.glass.instructions.If) line.getInstruction();
lineNumber = build(ins.getThenSource(), lineNumber);
if (ins.getElseSource() != null) {
lineNumber = build(ins.getElseSource(), lineNumber);
}
}
else {
If ins = (If) line.getDirective();
lineNumber = build(ins.getThenSource(), lineNumber);
if (ins.getElseSource() != null) {
lineNumber = build(ins.getElseSource(), lineNumber);
}
}
}
} catch (AssemblyException e) {
e.addContext(line);
throw e;
} catch (Exception e) {
e.printStackTrace();
}
}
return lineNumber;
}
public int getEntryAddress() {
return entryAddress;
}
public LineEntry getLineAtAddress(int address) {
return map.get(address);
}
public List<LineEntry> getLines() {
return list;
}
public LineEntry getLine(int lineNumber) {
return list.get(lineNumber);
}
}

Wyświetl plik

@ -38,15 +38,13 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import com.maccasoft.tools.SourceMap.LineEntry;
import com.maccasoft.tools.editor.EditorUtil;
import com.maccasoft.tools.editor.LineNumbersRuler;
import com.maccasoft.tools.editor.Token;
import com.maccasoft.tools.editor.TokenId;
import com.maccasoft.tools.editor.TokenMarker;
import nl.grauw.glass.Line;
import nl.grauw.glass.Source;
public class SourceViewer {
Composite container;
@ -62,7 +60,7 @@ public class SourceViewer {
private Font fontBold;
private Map<TokenId, TextStyle> styleMap = new HashMap<TokenId, TextStyle>();
Source source;
SourceMap sourceMap;
boolean showLineNumbers = true;
@ -183,21 +181,21 @@ public class SourceViewer {
return text;
}
public Source getSource() {
return source;
public SourceMap getSourceMap() {
return sourceMap;
}
public void setSource(Source source) {
this.source = source;
public void setSourceMap(SourceMap sourceMap) {
this.sourceMap = sourceMap;
StringBuilder sb = new StringBuilder();
for (Line line : source.getLines()) {
sb.append(line.getSourceText());
for (LineEntry lineEntry : sourceMap.getLines()) {
sb.append(lineEntry.line.getSourceText());
sb.append("\r\n");
}
String text = sb.toString();
codeRuler.setSource(source);
codeRuler.setSourceMap(sourceMap);
currentLine = 0;
this.text.setText(text);