Skip to content

Commit

Permalink
[#344] Refactoring of API
Browse files Browse the repository at this point in the history
  • Loading branch information
vbmacher committed Apr 23, 2023
1 parent aba98d4 commit 8da09dc
Show file tree
Hide file tree
Showing 180 changed files with 3,146 additions and 2,886 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
package net.emustudio.application.emulation;

import net.emustudio.application.gui.dialogs.AutoDialog;
import net.emustudio.application.internal.Unchecked;
import net.emustudio.application.settings.AppSettings;
import net.emustudio.application.virtualcomputer.VirtualComputer;
import net.emustudio.emulib.plugins.compiler.Compiler;
import net.emustudio.emulib.plugins.compiler.CompilerListener;
import net.emustudio.emulib.plugins.compiler.CompilerMessage;
import net.emustudio.emulib.plugins.cpu.CPU;
import net.emustudio.emulib.plugins.device.Device;
import net.emustudio.emulib.runtime.helpers.Unchecked;
import net.emustudio.emulib.runtime.interaction.Dialogs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -35,6 +35,7 @@
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
* This class manages the emuStudio automation process. In the process
Expand Down Expand Up @@ -97,7 +98,6 @@ public void run() {
computer.getCPU().ifPresent(cpu -> LOGGER.info("CPU: " + cpu.getTitle() + ", version " + cpu.getVersion()));
computer.getMemory().ifPresent(memory -> {
LOGGER.info("Memory: " + memory.getTitle() + ", version " + memory.getVersion());
LOGGER.info("Memory size: {}", memory.getSize());
});
computer.getDevices().forEach(
device -> LOGGER.info("Device: " + device.getTitle() + ", version " + device.getVersion())
Expand Down Expand Up @@ -139,6 +139,7 @@ private void autoCompile(Compiler compiler) throws AutomationException {
return;
}
setProgress("Compiling input file: " + inputFile, false);
AtomicInteger errors = new AtomicInteger();
CompilerListener reporter = new CompilerListener() {
@Override
public void onStart() {
Expand All @@ -150,6 +151,7 @@ public void onMessage(CompilerMessage message) {

switch (message.getMessageType()) {
case TYPE_ERROR:
errors.incrementAndGet();
LOGGER.error(message.getFormattedMessage());
break;
case TYPE_WARNING:
Expand All @@ -169,10 +171,10 @@ public void onFinish() {

// Initialize compiler
compiler.addCompilerListener(reporter);
compiler.compile(inputFile.toPath(), Optional.empty());

String fileName = inputFile.getAbsolutePath();
if (!compiler.compile(fileName)) {
throw new AutomationException("Compile failed. Automation cannot continue.");
if (errors.get() > 0) {
throw new AutomationException("Compilation failed. Automation cannot continue.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

public class CompileAction extends AbstractAction {
Expand Down Expand Up @@ -71,7 +72,7 @@ public void onStart() {
@Override
public void onMessage(CompilerMessage message) {
compilerOutput.append(message.getFormattedMessage() + "\n");
editor.setPosition(message.getLine(), message.getColumn());
message.getPosition().ifPresent(editor::setPosition);
}

@Override
Expand All @@ -94,7 +95,7 @@ public void actionPerformed(ActionEvent actionEvent) {

try {
computer.getMemory().ifPresent(Memory::reset);
compiler.compile(file.getAbsolutePath());
compiler.compile(file.toPath(), Optional.empty());
computer.getCPU().ifPresent(Plugin::reset);
} catch (Exception e) {
compilerOutput.append("Could not compile file: " + e + "\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package net.emustudio.application.gui.actions.emulator;

import net.emustudio.application.virtualcomputer.VirtualComputer;
import net.emustudio.emulib.plugins.memory.Memory;
import net.emustudio.emulib.runtime.interaction.Dialogs;

import javax.swing.*;
Expand Down Expand Up @@ -48,9 +47,7 @@ public void actionPerformed(ActionEvent actionEvent) {
.readInteger("Memory address:", "Jump to address", 0)
.ifPresent(address -> {
if (!cpu.setInstructionLocation(address)) {
int memorySize = computer.getMemory().map(Memory::getSize).orElse(0);
String maxSizeMessage = (memorySize == 0) ? "" : "(probably accepts range from 0 to " + memorySize + ")";
dialogs.showError("Invalid memory address" + maxSizeMessage);
dialogs.showError("Invalid memory address (please check memory size)");
} else {
refreshDebugTable.run();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

import net.emustudio.application.gui.dialogs.SchemaEditorDialog;
import net.emustudio.application.gui.schema.Schema;
import net.emustudio.application.internal.Unchecked;
import net.emustudio.application.settings.AppSettings;
import net.emustudio.application.settings.ComputerConfig;
import net.emustudio.emulib.runtime.helpers.Unchecked;
import net.emustudio.emulib.runtime.interaction.Dialogs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@
import java.util.*;
import java.util.function.Consumer;

/**
* Call flow.
* <p>
* Directed set of graphs, possibly with cycles.
*/
@ThreadSafe
class CallFlow {
private final static Logger LOGGER = LoggerFactory.getLogger(CallFlow.class);

private final Disassembler disassembler;
private final NavigableMap<Integer, Integer> flowGraph = new TreeMap<>();
private final NavigableMap<Integer, Integer> flowGraph = new TreeMap<>(); // location -> next location
private int longestInstructionSize = 1;

CallFlow(Disassembler disassembler) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,33 @@
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.Supplier;

/**
* Paginating disassembler
* <p>
* Disassembler which holds pages of disassembled instructions as they go sequentially from current CPU position
* onwards. One page is active at a time, which represents the content of a debug table. Debug table model reads instructions
* from the active page.
* <p>
* A page is specified by its min and max location in memory. These locations tries to bound a fixed number of
* instructions. A page is "filled" using "call flow" object, which can return disassembled instructions in given location
* range.
* <p>
* A first-time fill creates first "snapshot" of instructions in memory. But there are a few situations implying the
* need of refill of some pages. In such cases, all pages starting from changed location onwards are removed from cache.
* The situations are as follows:
* <p>
* - on memory change (can change instruction size)
* - on jump to a location which is not in the current call-flow path.
* <p>
* Call flow is the most important component of the paginating disassembler.
* It is basically a map of known instruction locations pointing to next instructions. In other words, it's a set of
* separate directed graphs. By using this graph map, one can build continuous "paths" from one location to another.
* <p>
* The complexity of a paginating disassembler lies in a requirement that all instructions in all pages must be reachable
* from the current CPU position - the following ones and also previous ones. It's tricky since between the current
* instruction and any other one can be data. The paginating disassembler doesn't know that, so if the data is "in the path"
* of filling up the page, it is not recognized - it's treated as instructions.
*/
@ThreadSafe
public class PaginatingDisassembler {
public final static int INSTR_PER_PAGE = 2 * 10 + 1;
Expand Down Expand Up @@ -61,10 +88,6 @@ int getCurrentInstructionRow() {
return currentInstrRow;
}

private int maxBytesPerPage() {
return instructionsPerPage * callFlow.getLongestInstructionSize();
}

int getPageIndex() {
return pageIndex;
}
Expand Down Expand Up @@ -96,7 +119,6 @@ void pagePrevious() {
void pageNext() {
int nextPageIndex = pageIndex + 1;
Page tmpPage = bytesPerPageCache.get(nextPageIndex);
int maxMemoryIndex = getMemorySize.get() - 1;

if (tmpPage == null) {
tmpPage = currentPage;
Expand All @@ -105,7 +127,7 @@ void pageNext() {
return;
}

if (!tmpPage.lastPage && tmpPage.maxLocation >= 0 && tmpPage.maxLocation + 1 < maxMemoryIndex) {
if (!tmpPage.lastPage && tmpPage.maxLocation >= 0) {
tmpPage = new Page(nextPageIndex, tmpPage.maxLocation, -1);
} else {
return;
Expand Down Expand Up @@ -204,6 +226,14 @@ int rowToLocation(int currentLocation, int row) {
}
}

void flushCache(int from, int to) {
callFlow.flushCache(from, to + 1);
}

private int maxBytesPerPage() {
return instructionsPerPage * callFlow.getLongestInstructionSize();
}

private int findCurrentLocationInPage(int currentLocation, Page tmpCurrentPage) {
if (tmpCurrentPage.index == 0) {
return currentLocation;
Expand Down Expand Up @@ -243,7 +273,7 @@ private int findIncreasing(int currentLocation, Page tmpPage, int currentPageInd

int maxBytesPP = maxBytesPerPage();
int longestInstr = callFlow.getLongestInstructionSize();
int guessUpTo = Math.min(getMemorySize.get() - 1, currentLocation + currentPageIndex * (maxBytesPP - longestInstr));
int guessUpTo = currentLocation + currentPageIndex * (maxBytesPP - longestInstr);

int result = callFlow.traverseUpTo(from, guessUpTo, instructions::add);
if (result == guessUpTo) {
Expand Down Expand Up @@ -307,7 +337,6 @@ private int findDecreasing(int currentLocation, Page tmpPage, int currentPageInd
return instructions.listIterator(instrCount - INSTR_PER_PAGE).next();
}


private int findLocationAboveHalf(int currentLocation, int row, int half, Page tmpCurrentPage) {
int lastMemoryIndex = getMemorySize.get() - 1;
if (lastMemoryIndex < 0) {
Expand Down Expand Up @@ -389,10 +418,6 @@ private int findLocationBelowHalf(int currentLocation, int row, int half, Page t
return rowLocation;
}

void flushCache(int from, int to) {
callFlow.flushCache(from, to + 1);
}

private static final class Page {
private final int index;
private volatile int minLocation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public class EmulatorPanel extends JPanel {
private final ShowDeviceGuiAction showDeviceGuiAction;

private final MemoryContext<?> memoryContext;
private final Memory.MemoryListener memoryListener;
private final MemoryContext.MemoryListener memoryListener;
private volatile CPU.RunState runState = CPU.RunState.STATE_STOPPED_BREAK;

public EmulatorPanel(JFrame parent, VirtualComputer computer, DebugTableModel debugTableModel, Dialogs dialogs,
Expand Down Expand Up @@ -221,10 +221,10 @@ public void mouseClicked(MouseEvent e) {
.addComponent(splitLeftRight, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
.addContainerGap());

this.memoryListener = new Memory.MemoryListener() {
this.memoryListener = new MemoryContext.MemoryListener() {
@Override
public void memoryChanged(int memoryPosition) {
debugTableModel.memoryChanged(memoryPosition, memoryPosition + 1);
public void memoryContentChanged(int fromLocatiom, int toLocation) {
debugTableModel.memoryChanged(fromLocatiom, toLocation + 1);
refreshDebugTable();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package net.emustudio.application.gui.editor;

import net.emustudio.emulib.plugins.compiler.SourceCodePosition;
import org.fife.rsta.ui.search.SearchListener;

import java.awt.*;
Expand Down Expand Up @@ -54,10 +55,9 @@ public interface Editor extends SearchListener {
/**
* Set caret position.
*
* @param line line (if -1 does nothing)
* @param column column (if -1 only sets the line)
* @param position position in the source code
*/
void setPosition(int line, int column);
void setPosition(SourceCodePosition position);


Optional<File> getCurrentFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.emustudio.application.Constants;
import net.emustudio.emulib.plugins.compiler.Compiler;
import net.emustudio.emulib.plugins.compiler.FileExtension;
import net.emustudio.emulib.plugins.compiler.SourceCodePosition;
import net.emustudio.emulib.runtime.interaction.Dialogs;
import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter;
import org.fife.io.UnicodeWriter;
Expand Down Expand Up @@ -144,14 +145,14 @@ public void grabFocus() {
}

@Override
public void setPosition(int line, int column) {
if (line >= 0) {
public void setPosition(SourceCodePosition position) {
if (position.line >= 0) {
try {
int position = textPane.getLineStartOffset(Math.max(0, line - 1));
if (column >= 0) {
position += column;
int offset = textPane.getLineStartOffset(Math.max(0, position.line - 1));
if (position.column >= 0) {
offset += position.column;
}
textPane.setCaretPosition(position);
textPane.setCaretPosition(offset);
} catch (BadLocationException ignored) {
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*/
package net.emustudio.application.virtualcomputer;

import net.emustudio.application.internal.Unchecked;
import net.emustudio.emulib.plugins.Plugin;
import net.emustudio.emulib.plugins.annotations.PluginRoot;
import net.emustudio.emulib.runtime.helpers.Unchecked;
import net.jcip.annotations.NotThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Loading

0 comments on commit 8da09dc

Please sign in to comment.