Loading pom.xml +5 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ <artifactId>json</artifactId> <version>20230618</version> </dependency> <dependency> <groupId>com.formdev</groupId> <artifactId>flatlaf</artifactId> <version>3.4.1</version> </dependency> </dependencies> <build> Loading src/main/java/jetklee/ExecutionState.java +54 −32 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ import java.util.Map; public class ExecutionState { public static final int BYTES_INDENT = 12; public static final int OBJS_INDENT = 4; public int nodeID; public record Location(String file, int line, int column, int assemblyLine) { @Override Loading Loading @@ -86,7 +87,7 @@ public class ExecutionState { } public record Object(int objID, int segment, String name, String size, boolean isLocal, boolean isGlobal, boolean isFixed, boolean isUserSpecified, boolean isLazy, String symAddress) { boolean isFixed, boolean isUserSpec, boolean isLazy, String symAddress) { @Override public String toString() { return String.format( Loading @@ -97,31 +98,31 @@ public class ExecutionState { "isLocal: %s, " + "isGlobal: %s, " + "isFixed: %s, " + "isUserSpecified: %s, " + "isUserSpec: %s, " + "isLazy: %s, " + "symAddress: %s", objID, segment, name, size, isLocal, isGlobal, isFixed, isUserSpecified, isLazy, symAddress objID, segment, name, size, isLocal, isGlobal, isFixed, isUserSpec, isLazy, symAddress ); } } public record Byte(int id, boolean concrete, boolean knownSym, boolean unflushed, String value) { public record ByteGroup (boolean concrete, boolean knownSym, boolean unflushed, String value, ArrayList<Integer> indices) { @Override public String toString() { return String.format( "id: %d, " + "concrete: %s, " + "knownSym: %s, " + "unflushed: %s, " + "value: %s", id, concrete, knownSym, unflushed, value "value: %s, " + "indices: %s", concrete, knownSym, unflushed, value, indices.toString() ); } } public record Plane(Type type, int memoryObjectID, String rootObject, int sizeBound, boolean initialized, boolean symbolic, int initialValue, Diff<Byte> bytes, LinkedHashMap<Integer, String> updates) { Diff<ByteGroup> bytes, LinkedHashMap<Integer, String> updates) { public enum Type { SEGMENT, OFFSET; Loading Loading @@ -220,9 +221,9 @@ public class ExecutionState { objectJSON.getInt("isLocal") == 1, objectJSON.getInt("isGlobal") == 1, objectJSON.getInt("isFixed") == 1, objectJSON.getInt("isUserSpecified") == 1, objectJSON.getInt("isLazyInitialized") == 1, objectJSON.getString("symbolicAddress") objectJSON.getInt("isUserSpec") == 1, objectJSON.getInt("isLazy") == 1, objectJSON.getString("symAddress") ); objects.add(object); } Loading Loading @@ -259,6 +260,7 @@ public class ExecutionState { } private Context parseContext(JSONObject data) { nodeID = data.getInt("nodeID"); Location location = getLocation(data, "location"); Location nextLocation = getLocation(data, "nextLocation"); Loading @@ -275,6 +277,7 @@ public class ExecutionState { stack.add(stackLocation); } return new Context( data.getInt("nodeID"), data.getInt("stateID"), Loading Loading @@ -303,25 +306,34 @@ public class ExecutionState { return constraints; } private ArrayList<Byte> parseByte(JSONArray bytesJSON) { ArrayList<Byte> bytes = new ArrayList<>(); private ArrayList<ByteGroup> parseByte(JSONArray bytesJSON) { ArrayList<ByteGroup> bytes = new ArrayList<>(); for (int i = 0; i < bytesJSON.length(); i++) { JSONObject byteJSON = bytesJSON.getJSONObject(i); Byte b = new Byte( byteJSON.getInt("byteID"), byteJSON.getInt("concrete") == 1, byteJSON.getInt("knownSym") == 1, byteJSON.getInt("unflushed") == 1, byteJSON.getString("value") JSONArray byteJSON = bytesJSON.getJSONArray(i); ArrayList<Integer> indices = new ArrayList<>(); JSONArray indicesJSON = byteJSON.getJSONArray(3); // skip first element (value) for (int j = 1; j < indicesJSON.length(); ++j) { indices.add(indicesJSON.getInt(j)); } ByteGroup b = new ByteGroup( byteJSON.getInt(0) == 1, // concrete byteJSON.getInt(1) == 1, // knownSym byteJSON.getInt(2) == 1, // unflushed byteJSON.getJSONArray(3).getString(0), //value indices ); bytes.add(b); } return bytes; } private Diff<Byte> parseBytes(JSONObject bytes) { ArrayList<Byte> additions = new ArrayList<>(); ArrayList<Byte> deletions = new ArrayList<>(); private Diff<ByteGroup> parseBytes(JSONObject bytes) { ArrayList<ByteGroup> additions = new ArrayList<>(); ArrayList<ByteGroup> deletions = new ArrayList<>(); if (bytes.has("add")) { JSONArray additionsJSON = bytes.getJSONArray("add"); Loading @@ -331,7 +343,6 @@ public class ExecutionState { JSONArray additionsJSON = bytes.getJSONArray("del"); deletions = parseByte(additionsJSON); } return new Diff<>(additions, deletions, BYTES_INDENT); } Loading @@ -339,17 +350,24 @@ public class ExecutionState { JSONObject planeJSON = data.getJSONObject(Plane.Type.toString(type)); if (planeJSON.isEmpty()) return null; Diff<ByteGroup> bytes = new Diff<>(new ArrayList<>(), new ArrayList<>(), BYTES_INDENT); if (planeJSON.has("bytes")) { JSONObject bytesJSON = planeJSON.getJSONObject("bytes"); Diff<Byte> bytes = parseBytes(bytesJSON); bytes = parseBytes(bytesJSON); } JSONArray updatesJSON = planeJSON.getJSONArray("updates"); LinkedHashMap<Integer, String> updates = new LinkedHashMap<>(); if (planeJSON.has("updates")) { JSONArray updatesJSON = planeJSON.getJSONArray("updates"); for (int i = 0; i < updatesJSON.length(); ++i) { JSONObject updateJSON = updatesJSON.getJSONObject(i); String key = updateJSON.keys().next(); String value = updateJSON.getString(key); updates.put(Integer.parseInt(key), value); } } return new Plane( type, Loading @@ -363,4 +381,8 @@ public class ExecutionState { updates ); } public void getCompleteMemory() { } } src/main/java/jetklee/MemoryViewer.java +26 −0 Original line number Diff line number Diff line package jetklee; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Panel that displays memory of selected execution state */ public class MemoryViewer extends TextViewerBase { public JButton showAllButton; private ExecutionState currentState = null; public MemoryViewer() { super(); // showAllButton = new JButton("Show All"); // showAllButton.setPreferredSize(new Dimension(75, 25)); // // showAllButton.addActionListener(new ActionListener() { // @Override // public void actionPerformed(ActionEvent e) { // showAllButton.setText("Hide"); // System.out.println("Button was clicked!"); // // if (currentState != null){ // currentState.getCompleteMemory(); // displayMemory(currentState); // } // } // }); // // this.add(showAllButton, BorderLayout.NORTH); } public void displayMemory(ExecutionState executionState) { currentState = executionState; textArea.setText(""); textArea.append("Objects:\n"); textArea.append(executionState.objectsDiff.toString()); Loading src/main/java/jetklee/Node.java +4 −0 Original line number Diff line number Diff line Loading @@ -33,4 +33,8 @@ public class Node { right = null; viewProps = new ViewProps(); } public boolean isRoot() { return parent == null; } } src/main/java/jetklee/ProgressExplorer.java +17 −4 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.*; import java.nio.file.Paths; import java.util.Collections; import com.formdev.flatlaf.FlatLightLaf; import com.formdev.flatlaf.FlatDarkLaf; /** * Represents whole application. Initializes and updates UI components. Loading Loading @@ -97,7 +101,16 @@ public class ProgressExplorer implements ListSelectionListener, MouseWheelListen * command line argument. */ public void run() { // double startTime = System.currentTimeMillis(); double startTime = System.currentTimeMillis(); UIManager.put( "TabbedPane.selectedBackground", Color.white ); FlatLightLaf.setGlobalExtraDefaults( Collections.singletonMap( "@accentColor", "#228b22" ) ); try { UIManager.setLookAndFeel( new FlatLightLaf() ); } catch( Exception ex ) { System.err.println( "Failed to initialize LaF" ); } JFrame frame = new JFrame("JetKlee: ProgressExplorer"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setPreferredSize(new Dimension(800, 600)); Loading @@ -112,9 +125,9 @@ public class ProgressExplorer implements ListSelectionListener, MouseWheelListen frame.setVisible(true); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // double totalTime = (System.currentTimeMillis() - startTime) / 1000.0f; // String formattedTime = String.format("%.2f", totalTime); // System.out.println(formattedTime); double totalTime = (System.currentTimeMillis() - startTime) / 1000.0f; String formattedTime = String.format("%.2f", totalTime); System.out.println(formattedTime); // System.exit(0); } }); Loading Loading
pom.xml +5 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ <artifactId>json</artifactId> <version>20230618</version> </dependency> <dependency> <groupId>com.formdev</groupId> <artifactId>flatlaf</artifactId> <version>3.4.1</version> </dependency> </dependencies> <build> Loading
src/main/java/jetklee/ExecutionState.java +54 −32 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ import java.util.Map; public class ExecutionState { public static final int BYTES_INDENT = 12; public static final int OBJS_INDENT = 4; public int nodeID; public record Location(String file, int line, int column, int assemblyLine) { @Override Loading Loading @@ -86,7 +87,7 @@ public class ExecutionState { } public record Object(int objID, int segment, String name, String size, boolean isLocal, boolean isGlobal, boolean isFixed, boolean isUserSpecified, boolean isLazy, String symAddress) { boolean isFixed, boolean isUserSpec, boolean isLazy, String symAddress) { @Override public String toString() { return String.format( Loading @@ -97,31 +98,31 @@ public class ExecutionState { "isLocal: %s, " + "isGlobal: %s, " + "isFixed: %s, " + "isUserSpecified: %s, " + "isUserSpec: %s, " + "isLazy: %s, " + "symAddress: %s", objID, segment, name, size, isLocal, isGlobal, isFixed, isUserSpecified, isLazy, symAddress objID, segment, name, size, isLocal, isGlobal, isFixed, isUserSpec, isLazy, symAddress ); } } public record Byte(int id, boolean concrete, boolean knownSym, boolean unflushed, String value) { public record ByteGroup (boolean concrete, boolean knownSym, boolean unflushed, String value, ArrayList<Integer> indices) { @Override public String toString() { return String.format( "id: %d, " + "concrete: %s, " + "knownSym: %s, " + "unflushed: %s, " + "value: %s", id, concrete, knownSym, unflushed, value "value: %s, " + "indices: %s", concrete, knownSym, unflushed, value, indices.toString() ); } } public record Plane(Type type, int memoryObjectID, String rootObject, int sizeBound, boolean initialized, boolean symbolic, int initialValue, Diff<Byte> bytes, LinkedHashMap<Integer, String> updates) { Diff<ByteGroup> bytes, LinkedHashMap<Integer, String> updates) { public enum Type { SEGMENT, OFFSET; Loading Loading @@ -220,9 +221,9 @@ public class ExecutionState { objectJSON.getInt("isLocal") == 1, objectJSON.getInt("isGlobal") == 1, objectJSON.getInt("isFixed") == 1, objectJSON.getInt("isUserSpecified") == 1, objectJSON.getInt("isLazyInitialized") == 1, objectJSON.getString("symbolicAddress") objectJSON.getInt("isUserSpec") == 1, objectJSON.getInt("isLazy") == 1, objectJSON.getString("symAddress") ); objects.add(object); } Loading Loading @@ -259,6 +260,7 @@ public class ExecutionState { } private Context parseContext(JSONObject data) { nodeID = data.getInt("nodeID"); Location location = getLocation(data, "location"); Location nextLocation = getLocation(data, "nextLocation"); Loading @@ -275,6 +277,7 @@ public class ExecutionState { stack.add(stackLocation); } return new Context( data.getInt("nodeID"), data.getInt("stateID"), Loading Loading @@ -303,25 +306,34 @@ public class ExecutionState { return constraints; } private ArrayList<Byte> parseByte(JSONArray bytesJSON) { ArrayList<Byte> bytes = new ArrayList<>(); private ArrayList<ByteGroup> parseByte(JSONArray bytesJSON) { ArrayList<ByteGroup> bytes = new ArrayList<>(); for (int i = 0; i < bytesJSON.length(); i++) { JSONObject byteJSON = bytesJSON.getJSONObject(i); Byte b = new Byte( byteJSON.getInt("byteID"), byteJSON.getInt("concrete") == 1, byteJSON.getInt("knownSym") == 1, byteJSON.getInt("unflushed") == 1, byteJSON.getString("value") JSONArray byteJSON = bytesJSON.getJSONArray(i); ArrayList<Integer> indices = new ArrayList<>(); JSONArray indicesJSON = byteJSON.getJSONArray(3); // skip first element (value) for (int j = 1; j < indicesJSON.length(); ++j) { indices.add(indicesJSON.getInt(j)); } ByteGroup b = new ByteGroup( byteJSON.getInt(0) == 1, // concrete byteJSON.getInt(1) == 1, // knownSym byteJSON.getInt(2) == 1, // unflushed byteJSON.getJSONArray(3).getString(0), //value indices ); bytes.add(b); } return bytes; } private Diff<Byte> parseBytes(JSONObject bytes) { ArrayList<Byte> additions = new ArrayList<>(); ArrayList<Byte> deletions = new ArrayList<>(); private Diff<ByteGroup> parseBytes(JSONObject bytes) { ArrayList<ByteGroup> additions = new ArrayList<>(); ArrayList<ByteGroup> deletions = new ArrayList<>(); if (bytes.has("add")) { JSONArray additionsJSON = bytes.getJSONArray("add"); Loading @@ -331,7 +343,6 @@ public class ExecutionState { JSONArray additionsJSON = bytes.getJSONArray("del"); deletions = parseByte(additionsJSON); } return new Diff<>(additions, deletions, BYTES_INDENT); } Loading @@ -339,17 +350,24 @@ public class ExecutionState { JSONObject planeJSON = data.getJSONObject(Plane.Type.toString(type)); if (planeJSON.isEmpty()) return null; Diff<ByteGroup> bytes = new Diff<>(new ArrayList<>(), new ArrayList<>(), BYTES_INDENT); if (planeJSON.has("bytes")) { JSONObject bytesJSON = planeJSON.getJSONObject("bytes"); Diff<Byte> bytes = parseBytes(bytesJSON); bytes = parseBytes(bytesJSON); } JSONArray updatesJSON = planeJSON.getJSONArray("updates"); LinkedHashMap<Integer, String> updates = new LinkedHashMap<>(); if (planeJSON.has("updates")) { JSONArray updatesJSON = planeJSON.getJSONArray("updates"); for (int i = 0; i < updatesJSON.length(); ++i) { JSONObject updateJSON = updatesJSON.getJSONObject(i); String key = updateJSON.keys().next(); String value = updateJSON.getString(key); updates.put(Integer.parseInt(key), value); } } return new Plane( type, Loading @@ -363,4 +381,8 @@ public class ExecutionState { updates ); } public void getCompleteMemory() { } }
src/main/java/jetklee/MemoryViewer.java +26 −0 Original line number Diff line number Diff line package jetklee; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Panel that displays memory of selected execution state */ public class MemoryViewer extends TextViewerBase { public JButton showAllButton; private ExecutionState currentState = null; public MemoryViewer() { super(); // showAllButton = new JButton("Show All"); // showAllButton.setPreferredSize(new Dimension(75, 25)); // // showAllButton.addActionListener(new ActionListener() { // @Override // public void actionPerformed(ActionEvent e) { // showAllButton.setText("Hide"); // System.out.println("Button was clicked!"); // // if (currentState != null){ // currentState.getCompleteMemory(); // displayMemory(currentState); // } // } // }); // // this.add(showAllButton, BorderLayout.NORTH); } public void displayMemory(ExecutionState executionState) { currentState = executionState; textArea.setText(""); textArea.append("Objects:\n"); textArea.append(executionState.objectsDiff.toString()); Loading
src/main/java/jetklee/Node.java +4 −0 Original line number Diff line number Diff line Loading @@ -33,4 +33,8 @@ public class Node { right = null; viewProps = new ViewProps(); } public boolean isRoot() { return parent == null; } }
src/main/java/jetklee/ProgressExplorer.java +17 −4 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.*; import java.nio.file.Paths; import java.util.Collections; import com.formdev.flatlaf.FlatLightLaf; import com.formdev.flatlaf.FlatDarkLaf; /** * Represents whole application. Initializes and updates UI components. Loading Loading @@ -97,7 +101,16 @@ public class ProgressExplorer implements ListSelectionListener, MouseWheelListen * command line argument. */ public void run() { // double startTime = System.currentTimeMillis(); double startTime = System.currentTimeMillis(); UIManager.put( "TabbedPane.selectedBackground", Color.white ); FlatLightLaf.setGlobalExtraDefaults( Collections.singletonMap( "@accentColor", "#228b22" ) ); try { UIManager.setLookAndFeel( new FlatLightLaf() ); } catch( Exception ex ) { System.err.println( "Failed to initialize LaF" ); } JFrame frame = new JFrame("JetKlee: ProgressExplorer"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setPreferredSize(new Dimension(800, 600)); Loading @@ -112,9 +125,9 @@ public class ProgressExplorer implements ListSelectionListener, MouseWheelListen frame.setVisible(true); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // double totalTime = (System.currentTimeMillis() - startTime) / 1000.0f; // String formattedTime = String.format("%.2f", totalTime); // System.out.println(formattedTime); double totalTime = (System.currentTimeMillis() - startTime) / 1000.0f; String formattedTime = String.format("%.2f", totalTime); System.out.println(formattedTime); // System.exit(0); } }); Loading