diff --git a/Source/Mosa.Packages/Mosa.Tools.Package.Qemu.nuspec b/Source/Mosa.Packages/Mosa.Tools.Package.Qemu.nuspec
index 7b8a0df42f..76a85d4643 100644
--- a/Source/Mosa.Packages/Mosa.Tools.Package.Qemu.nuspec
+++ b/Source/Mosa.Packages/Mosa.Tools.Package.Qemu.nuspec
@@ -49,5 +49,6 @@
+
diff --git a/Source/Mosa.Packages/Mosa.Tools.Package.nuspec b/Source/Mosa.Packages/Mosa.Tools.Package.nuspec
index 571982e6f5..383cf4d338 100644
--- a/Source/Mosa.Packages/Mosa.Tools.Package.nuspec
+++ b/Source/Mosa.Packages/Mosa.Tools.Package.nuspec
@@ -48,5 +48,6 @@
+
diff --git a/Source/Mosa.Templates/templates/Mosa.Starter.x86/Properties/launchSettings.json b/Source/Mosa.Templates/templates/Mosa.Starter.x86/Properties/launchSettings.json
index 91fc0a775e..272a6c4389 100644
--- a/Source/Mosa.Templates/templates/Mosa.Starter.x86/Properties/launchSettings.json
+++ b/Source/Mosa.Templates/templates/Mosa.Starter.x86/Properties/launchSettings.json
@@ -4,7 +4,7 @@
"commandName": "Executable",
"executablePath": "dotnet",
"commandLineArgs": "Tools/Mosa.Tool.Launcher.dll Mosa.Starter.x86.dll",
- "workingDirectory": "bin"
+ "workingDirectory": "$(ProjectDir)bin"
}
}
}
diff --git a/Source/Mosa.Tool.Debugger/Views/InstructionView.cs b/Source/Mosa.Tool.Debugger/Views/InstructionView.cs
index 10b7c73c8a..112a44176d 100644
--- a/Source/Mosa.Tool.Debugger/Views/InstructionView.cs
+++ b/Source/Mosa.Tool.Debugger/Views/InstructionView.cs
@@ -57,19 +57,20 @@ private void UpdateDisplay(ulong address, byte[] memory)
{
instructions.Clear();
- var disassembler = new Disassembler("x86");
- disassembler.SetMemory(memory, address);
+ var disassembler = new Disassembler("x86", memory, address);
+ var instruction = disassembler.DecodeNext();
- foreach (var instruction in disassembler.Decode())
+ while (instruction != null)
{
var entry = new InstructionEntry()
{
IP = instruction.Address,
- Length = instruction.Length,
+ Length = (int)instruction.Length,
Instruction = instruction.Instruction.ToString()
};
instructions.Add(entry);
+ instruction = disassembler.DecodeNext();
}
}
diff --git a/Source/Mosa.Tool.Debugger/Views/MethodView.cs b/Source/Mosa.Tool.Debugger/Views/MethodView.cs
index cc88d84e29..dc705c87f7 100644
--- a/Source/Mosa.Tool.Debugger/Views/MethodView.cs
+++ b/Source/Mosa.Tool.Debugger/Views/MethodView.cs
@@ -148,10 +148,10 @@ private void UpdateDisplay(ulong address, byte[] memory)
{
instructions.Clear();
- var disassembler = new Disassembler("x86");
- disassembler.SetMemory(memory, address);
+ var disassembler = new Disassembler("x86", memory, address);
+ var instruction = disassembler.DecodeNext();
- foreach (var instruction in disassembler.Decode())
+ while (instruction != null)
{
var addr = MainForm.ParseAddress(instruction.Instruction);
@@ -160,12 +160,13 @@ private void UpdateDisplay(ulong address, byte[] memory)
var entry = new MethodInstructionEntry()
{
IP = instruction.Address, // Offset?
- Length = instruction.Length,
+ Length = (int)instruction.Length,
Instruction = instruction.Instruction,
Info = info
};
instructions.Add(entry);
+ instruction = disassembler.DecodeNext();
}
}
diff --git a/Source/Mosa.Tool.Debugger/Views/StatusView.cs b/Source/Mosa.Tool.Debugger/Views/StatusView.cs
index 09329ce091..f60039afae 100644
--- a/Source/Mosa.Tool.Debugger/Views/StatusView.cs
+++ b/Source/Mosa.Tool.Debugger/Views/StatusView.cs
@@ -44,15 +44,15 @@ private void UpdateDisplay(ulong address, byte[] memory)
if (address != InstructionPointer)
return;
- var disassembler = new Disassembler("x86");
- disassembler.SetMemory(memory, address);
+ var disassembler = new Disassembler("x86", memory, address);
tbInstruction.Text = "Unable to decode!";
- foreach (var instruction in disassembler.Decode())
+ var instruction = disassembler.DecodeNext();
+ while (instruction != null)
{
tbInstruction.Text = instruction.Instruction;
- break;
+ instruction = disassembler.DecodeNext();
}
}
}
diff --git a/Source/Mosa.Tool.Debugger/Views/TraceView.cs b/Source/Mosa.Tool.Debugger/Views/TraceView.cs
index 236e1a3d8a..f746d5d0d7 100644
--- a/Source/Mosa.Tool.Debugger/Views/TraceView.cs
+++ b/Source/Mosa.Tool.Debugger/Views/TraceView.cs
@@ -68,13 +68,13 @@ private void UpdateDisplay(ulong address, byte[] memory)
if (address == InstructionPointer)
{
- var disassembler = new Disassembler("x86");
- disassembler.SetMemory(memory, address);
+ var disassembler = new Disassembler("x86", memory, address);
+ var instruction = disassembler.DecodeNext();
- foreach (var instruction in disassembler.Decode())
+ while (instruction != null)
{
opinstruction = instruction.Instruction;
- break;
+ instruction = disassembler.DecodeNext();
}
}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/CompilerData.cs b/Source/Mosa.Tool.Explorer.Avalonia/CompilerData.cs
index 0e053b325f..11daa34113 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/CompilerData.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/CompilerData.cs
@@ -38,9 +38,7 @@ public void UpdateLog(string section, List lines, bool dirty)
}
lock (log)
- {
log.AddRange(lines);
- }
DirtyLog = dirty;
}
@@ -59,9 +57,7 @@ private void UpdateLog(string section, string line)
}
lock (log)
- {
log.Add(line);
- }
DirtyLog = true;
}
@@ -70,9 +66,7 @@ private void UpdateLog(string section, string line)
public List GetLog(string section)
{
lock (Logs)
- {
return Logs.GetValueOrDefault(section);
- }
}
public void AddTraceEvent(CompilerEvent compilerEvent, string message, int threadID)
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/CompilerStage/ExplorerMethodCompileTimeStage.cs b/Source/Mosa.Tool.Explorer.Avalonia/CompilerStage/ExplorerMethodCompileTimeStage.cs
index 0bdbece160..404ef1139c 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/CompilerStage/ExplorerMethodCompileTimeStage.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/CompilerStage/ExplorerMethodCompileTimeStage.cs
@@ -17,7 +17,6 @@ protected override void Finalization()
var log = new TraceLog(TraceType.GlobalDebug, null, null, "Compiler Time");
log.Log("Ticks\tMilliseconds\tCompiler Count\tMethod");
-
foreach (var data in methods)
log.Log($"{data.ElapsedTicks}{'\t'}{data.ElapsedTicks / TimeSpan.TicksPerMillisecond}{'\t'}{data.Version}{'\t'}{data.Method.FullName}");
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/FormatInstructions.cs b/Source/Mosa.Tool.Explorer.Avalonia/FormatInstructions.cs
new file mode 100644
index 0000000000..8d60d9358d
--- /dev/null
+++ b/Source/Mosa.Tool.Explorer.Avalonia/FormatInstructions.cs
@@ -0,0 +1,193 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+using System.Text;
+
+namespace Mosa.Tool.Explorer.Avalonia;
+
+public static class FormatInstructions
+{
+ private const int Padding = 34;
+
+ public static string Format(List records, string blockLabel, bool strip, bool removeNop, bool lineBetweenBlocks)
+ {
+ var sb = new StringBuilder();
+ var blocks = new StringBuilder();
+
+ if (records == null || records.Count == 0)
+ return string.Empty;
+
+ var allLines = string.IsNullOrWhiteSpace(blockLabel);
+ var inBlock = allLines;
+
+ foreach (var record in records)
+ {
+ switch (record.Type)
+ {
+ case "M":
+ {
+ sb.AppendLine($"{record.MethodName} [v{record.Version}] @ {record.Stage}:");
+ sb.AppendLine();
+ break;
+ }
+ case "S":
+ {
+ inBlock = record.BlockLabel == blockLabel;
+
+ if (!inBlock && !allLines)
+ continue;
+
+ sb.Append($"{record.BlockLabel}:");
+
+ blocks.Clear();
+
+ // Previous Branch Targets
+ if (record.PreviousBlockCount != 0)
+ {
+ for (var i = 0; i < record.PreviousBlockCount; i++)
+ {
+ if (i != 0)
+ blocks.Append(' ');
+
+ var op = record.GetPreviousBlocks(i);
+
+ blocks.Append(op);
+ }
+
+ sb.Append("".PadRight(record.PreviousBlockCount == 1 ? Padding : Padding - 8));
+
+ sb.Append(blocks);
+ }
+
+ sb.AppendLine();
+ break;
+ }
+ case "I":
+ {
+ if (!inBlock && !allLines)
+ continue;
+
+ if (record.Instruction is "IR.BlockStart" or "IR.BlockEnd")
+ break;
+
+ if (removeNop && record.Instruction == "IR.Nop")
+ continue;
+
+ sb.Append(" ");
+
+ var instruction = record.Instruction;
+ var condition = !string.IsNullOrEmpty(record.Condition) ? " [" + record.Condition + "]" : string.Empty;
+
+ var both = $"{instruction}{condition}";
+
+ blocks.Clear();
+
+ // Branch Targets
+ if (record.BranchTargetCount != 0)
+ {
+ if (condition.Length != 0)
+ blocks.Append(' ');
+
+ for (var i = 0; i < record.BranchTargetCount; i++)
+ {
+ if (i != 0)
+ blocks.Append(' ');
+
+ var op = record.GetBranchTarget(i);
+
+ blocks.Append(op);
+ }
+ }
+
+ var count = Padding + 2 - both.Length - blocks.Length;
+ if (count < 0)
+ count = 1;
+
+ var padding = string.Empty.PadRight(count);
+
+ sb.Append($"{record.Label[..5]}:{record.Mark.PadLeft(1)}{both}{padding}{blocks} ");
+
+ // Result
+ for (var i = 0; i < record.ResultCount; i++)
+ {
+ if (i != 0)
+ sb.Append(", ");
+
+ var op = record.GetResult(i);
+
+ op = Simplify(op);
+
+ if (strip)
+ op = StripBracketData(op);
+
+ sb.Append(op);
+ }
+
+ if (record.ResultCount != 0 && record.OperandCount != 0)
+ sb.Append(" <= ");
+
+ // Operands
+ for (var i = 0; i < record.OperandCount; i++)
+ {
+ if (i != 0)
+ sb.Append(", ");
+
+ var op = record.GetOperand(i);
+
+ op = Simplify(op);
+
+ if (strip)
+ op = StripBracketData(op);
+
+ sb.Append(op);
+ }
+
+ // Phi Blocks
+ if (record.PhiBlockCount != 0)
+ {
+ sb.Append(" (");
+
+ for (var i = 0; i < record.PhiBlockCount; i++)
+ {
+ if (i != 0)
+ sb.Append(", ");
+
+ var op = record.GetPhilBlock(i);
+
+ sb.Append(op);
+ }
+
+ sb.Append(") ");
+ }
+
+ while (sb.Length > 0 && sb[^1] == ' ')
+ sb.Length--;
+
+ sb.AppendLine();
+ break;
+ }
+ case "E":
+ {
+ inBlock = false;
+
+ if (!inBlock && !allLines)
+ continue;
+
+ if (lineBetweenBlocks)
+ sb.AppendLine();
+
+ break;
+ }
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ private static string StripBracketData(string s)
+ {
+ var i = s.IndexOf('[');
+ return i <= 0 ? s : s[..(i - 1)].Trim();
+ }
+
+ private static string Simplify(string s) => s.Replace("const=", string.Empty);
+}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/InstructionRecord.cs b/Source/Mosa.Tool.Explorer.Avalonia/InstructionRecord.cs
new file mode 100644
index 0000000000..08fab30bdb
--- /dev/null
+++ b/Source/Mosa.Tool.Explorer.Avalonia/InstructionRecord.cs
@@ -0,0 +1,95 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+namespace Mosa.Tool.Explorer.Avalonia;
+
+public class InstructionRecord
+{
+ public readonly string Data;
+
+ public readonly string[] Parts;
+
+ public readonly string Type;
+
+ public readonly bool IsInstruction;
+
+ public readonly bool IsMethod;
+
+ public readonly bool IsStartBlock;
+
+ public readonly bool IsEndBlock;
+
+ public string Label => Parts[1];
+
+ // Block
+ public string BlockLabel => Parts[1];
+
+ // Start Block
+ public string BlockSequence => Parts[2];
+
+ public string BlockType => Parts[3];
+
+ public readonly int PreviousBlockCount;
+
+ public string GetPreviousBlocks(int index) => Parts[5 + index];
+
+ // End Block
+ public int NextBlockCount => Convert.ToInt32(Parts[2]);
+
+ // Instruction
+ public string Mark => Parts[2];
+
+ public string Instruction => Parts[3];
+
+ public string Condition => Parts[4];
+
+ public readonly int ResultCount = 0;
+
+ public readonly int OperandCount = 0;
+
+ public readonly int BranchTargetCount = 0;
+
+ public readonly int PhiBlockCount = 0;
+
+ public string GetResult(int index) => Parts[9 + index];
+
+ public string GetOperand(int index) => Parts[9 + ResultCount + index];
+
+ public string GetBranchTarget(int index) => Parts[9 + ResultCount + OperandCount + index];
+
+ public string GetPhilBlock(int index) => Parts[9 + ResultCount + OperandCount + BranchTargetCount + index];
+
+ // Method
+
+ public string MethodName => Parts[1];
+
+ public int Version => Convert.ToInt32(Parts[2]);
+
+ public string Stage => Parts[3];
+
+ public int Step => Convert.ToInt32(Parts[4]);
+
+ public InstructionRecord(string data)
+ {
+ Data = data;
+ Parts = data.Split('\t');
+
+ Type = Parts[0];
+
+ IsInstruction = Type == "I";
+ IsMethod = Type == "M";
+ IsStartBlock = Type == "S";
+ IsEndBlock = Type == "E";
+
+ if (IsInstruction)
+ {
+ ResultCount = Convert.ToInt32(Parts[5]);
+ OperandCount = Convert.ToInt32(Parts[6]);
+ BranchTargetCount = Convert.ToInt32(Parts[7]);
+ PhiBlockCount = Convert.ToInt32(Parts[8]);
+ }
+ else if (IsStartBlock)
+ {
+ PreviousBlockCount = Convert.ToInt32(Parts[4]);
+ }
+ }
+}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml b/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml
index 0b88995dac..41f204125a 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml
+++ b/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml
@@ -36,10 +36,10 @@
@@ -72,7 +72,7 @@
-
+
@@ -159,24 +159,17 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
+
-
-
-
-
+
+
@@ -193,24 +186,17 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
+
-
-
-
-
+
+
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml.cs b/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml.cs
index 4101c94c62..5a9b6eea16 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/MainWindow.axaml.cs
@@ -15,8 +15,6 @@
using Mosa.Tool.Explorer.Avalonia.CompilerStage;
using Mosa.Tool.Explorer.Avalonia.Stages;
using Mosa.Utility.Configuration;
-using DebugInfoStage = Mosa.Tool.Explorer.Avalonia.Stages.DebugInfoStage;
-using GraphVizStage = Mosa.Tool.Explorer.Avalonia.Stages.GraphVizStage;
using Timer = System.Timers.Timer;
namespace Mosa.Tool.Explorer.Avalonia;
@@ -31,7 +29,7 @@ public partial class MainWindow : Window
private readonly ObservableCollection counterCollection = new ObservableCollection();
private readonly ObservableCollection compilerCounterCollection = new ObservableCollection();
- private MosaSettings mosaSettings = new MosaSettings();
+ private readonly MosaSettings mosaSettings = new MosaSettings();
private MosaCompiler compiler;
private int completedMethods;
@@ -316,7 +314,15 @@ private void TreeView_OnSelectionChanged(object _, SelectionChangedEventArgs e)
return;
compilerData.Stopwatch.Reset();
- compiler.CompileSingleMethod(currentMethod);
+ ThreadPool.QueueUserWorkItem(_ => compiler.CompileSingleMethod(currentMethod));
+ }
+
+ private void TabControl_OnSelectionChanged(object _, SelectionChangedEventArgs e)
+ {
+ compilerData.DirtyLog = true;
+
+ if (TabControl != null)
+ RefreshCompilerLog();
}
private void InstructionsStage_OnSelectionChanged(object _, SelectionChangedEventArgs e) => UpdateInstructionStageSelection();
@@ -337,12 +343,12 @@ private void UpdateInstructionStageSelection()
private void UpdateInstructionBlocks()
{
- var lines = GetCurrentInstructionLines();
+ var records = GetCurrentInstructionLines();
InstructionsBlock.Items.Clear();
InstructionsBlock.Items.Add("All");
- var labels = ExtractLabels(lines);
+ var labels = ExtractLabels(records);
if (labels == null)
return;
@@ -350,20 +356,16 @@ private void UpdateInstructionBlocks()
InstructionsBlock.Items.Add(label);
}
- private static List ExtractLabels(List lines)
+ private static List ExtractLabels(List records)
{
- if (lines == null)
+ if (records == null)
return null;
var labels = new List();
- foreach (var line in lines)
- {
- if (!line.StartsWith("Block #"))
- continue;
-
- labels.Add(line[line.IndexOf("L_", StringComparison.Ordinal)..]);
- }
+ foreach (var record in records)
+ if (record.IsStartBlock)
+ labels.Add(record.BlockLabel);
return labels;
}
@@ -429,6 +431,18 @@ private void TransformsGrid_OnSelectionChanged(object _, SelectionChangedEventAr
private void CountersGridFilter_OnTextChanged(object _, TextChangedEventArgs e) => UpdateCounters();
+ private async void CopyCountersText_OnClick(object _, RoutedEventArgs e)
+ {
+ if (Clipboard == null)
+ {
+ SetStatus("Error: No Clipboard Detected.");
+ return;
+ }
+
+ await Clipboard.SetTextAsync(CreateText(currentMethodData.Counters));
+ SetStatus("Text Copied!");
+ }
+
private void CompilerLogsSection_OnSelectionChanged(object _, SelectionChangedEventArgs e)
{
var formatted = CompilerLogsSection.SelectionBoxItem?.ToString();
@@ -443,6 +457,22 @@ private void CompilerLogsSection_OnSelectionChanged(object _, SelectionChangedEv
private void CompilerCountersGridFilter_OnTextChanged(object _, TextChangedEventArgs e) => UpdateCompilerCounters();
+ private async void CopyCompilerCountersText_OnClick(object _, RoutedEventArgs e)
+ {
+ if (Clipboard == null)
+ {
+ SetStatus("Error: No Clipboard Detected.");
+ return;
+ }
+
+ var lines = compilerData.GetLog("Counters");
+ if (lines == null)
+ return;
+
+ await Clipboard.SetTextAsync(CreateText(lines));
+ SetStatus("Text Copied!");
+ }
+
private void SetTransformationStep(int step)
{
if (step <= 0)
@@ -529,7 +559,7 @@ private void PopulateTransformList()
entry = new TransformEntry
{
- ID = Convert.ToInt32(parts[0].Trim()) + 1,
+ ID = Convert.ToInt32(parts[0].Trim()),
Name = part1,
Pass = pass
};
@@ -542,7 +572,7 @@ private void PopulateTransformList()
private void UpdateTransformLabels()
{
- var lines = GetCurrentTransformLines();
+ var lines = GetCurrentTransformRecords();
TransformsBlock.Items.Clear();
TransformsBlock.Items.Add("All");
@@ -577,13 +607,7 @@ private List GetCurrentDebugLines()
return stage == null ? null : currentMethodData.DebugLogs[stage];
}
- private void UpdateGraphviz()
- {
- var graphviz = ShowGraphviz();
-
- DebugPanel.IsVisible = graphviz;
- Debug.IsVisible = !graphviz;
- }
+ private void UpdateGraphviz() => DebugPanel.IsVisible = ShowGraphviz();
private bool ShowGraphviz()
{
@@ -595,11 +619,11 @@ private bool ShowGraphviz()
if (DisplayGraphviz.IsChecked != null && !DisplayGraphviz.IsChecked.Value)
return false;
- if (string.IsNullOrEmpty(Debug.Text) || !Debug.Text.Contains("digraph blocks"))
+ if (string.IsNullOrEmpty(Debug.Text) || !Debug.Text.StartsWith("digraph blocks"))
return false;
var dot = Path.GetTempFileName();
- var bmp = Path.GetTempFileName();
+ var img = Path.GetTempFileName();
try
{
@@ -608,29 +632,27 @@ private bool ShowGraphviz()
var startInfo = new ProcessStartInfo
{
FileName = mosaSettings.GraphwizApp,
- Arguments = $"dot -Tbmp -o \"{bmp}\" \"{dot}\"",
+ Arguments = $"-Tpng -o \"{img}\" \"{dot}\"",
CreateNoWindow = true
};
var process = Process.Start(startInfo);
process?.WaitForExit();
- var file = File.ReadAllBytes(bmp);
-
- using var stream = new MemoryStream(file);
+ using var stream = File.OpenRead(img);
var bitmap = new Bitmap(stream);
- var picture = new Image
+ var image = new Image
{
Source = bitmap
};
- DebugPanel.Children.Add(picture);
+ DebugPanel.Children.Add(image);
}
finally
{
File.Delete(dot);
- File.Delete(bmp);
+ File.Delete(img);
}
return true;
@@ -671,12 +693,24 @@ private void ExtendMethodCompilerPipeline(Pipeline pipe
if (Dispatcher.UIThread.Invoke(() => DebugDiagnostic.IsChecked))
{
for (var i = 1; i < pipeline.Count; i += 2)
- pipeline.Insert(i, new GraphVizStage());
+ pipeline.Insert(i, new ControlFlowGraphStage());
}
else
{
- pipeline.InsertAfterLast(new GraphVizStage());
- pipeline.Add(new GraphVizStage());
+ if (mosaSettings.InlineMethods || mosaSettings.InlineExplicit)
+ {
+ pipeline.InsertBefore(new ControlFlowGraphStage());
+ pipeline.InsertAfterLast(new ControlFlowGraphStage());
+ }
+
+ if (mosaSettings.SSA)
+ {
+ pipeline.InsertBefore(new DominanceAnalysisStage());
+ pipeline.InsertBefore(new ControlFlowGraphStage());
+ }
+
+ pipeline.InsertAfterLast(new ControlFlowGraphStage());
+ pipeline.Add(new ControlFlowGraphStage());
}
}
@@ -780,19 +814,19 @@ private void UpdateInstructions()
if (currentMethod == null)
return;
- var lines = GetCurrentInstructionLines();
+ var records = GetCurrentInstructionLines();
var label = InstructionsBlock.SelectionBoxItem?.ToString();
SetStatus(currentMethod.FullName);
- if (lines == null)
+ if (records == null)
return;
if (string.IsNullOrWhiteSpace(label) || label == "All")
label = string.Empty;
- Instructions.Text = methodStore.GetStageInstructions(lines, label, !ShowOperandTypes.IsChecked,
- PadInstructions.IsChecked, RemoveIrNop.IsChecked);
+ Instructions.Text = FormatInstructions.Format(records, label, !ShowOperandTypes.IsChecked,
+ RemoveIrNop.IsChecked, LineBetweenBlocks.IsChecked);
}
private void UpdateTransforms()
@@ -802,20 +836,20 @@ private void UpdateTransforms()
if (currentMethod == null)
return;
- var lines = GetCurrentTransformLines();
+ var records = GetCurrentTransformRecords();
var label = TransformsBlock.SelectionBoxItem?.ToString();
- if (lines == null)
+ if (records == null)
return;
if (string.IsNullOrWhiteSpace(label) || label == "All")
label = string.Empty;
- Transforms.Text = methodStore.GetStageInstructions(lines, label, !ShowOperandTypes.IsChecked,
- PadInstructions.IsChecked, RemoveIrNop.IsChecked);
+ Transforms.Text = FormatInstructions.Format(records, label, !ShowOperandTypes.IsChecked,
+ RemoveIrNop.IsChecked, LineBetweenBlocks.IsChecked);
}
- private List GetCurrentTransformLines()
+ private List GetCurrentTransformRecords()
{
if (currentMethodData == null)
return null;
@@ -830,14 +864,13 @@ private List GetCurrentTransformLines()
return log;
}
- private List GetCurrentInstructionLines()
+ private List GetCurrentInstructionLines()
{
if (currentMethodData == null)
return null;
var stage = InstructionsStage.SelectionBoxItem?.ToString();
return stage == null ? null : currentMethodData.InstructionLogs[stage];
-
}
private void UpdateInstructionStages()
@@ -869,13 +902,9 @@ private void UpdateDebugStages()
private void UpdateCounters()
{
- Counters.Clear();
-
if (currentMethodData == null)
return;
- Counters.Text = CreateText(currentMethodData.Counters);
-
counterCollection.Clear();
var filter = CountersGridFilter.Text ?? string.Empty;
@@ -1074,10 +1103,17 @@ private void LoadAssembly()
UpdateSettings();
compiler = new MosaCompiler(mosaSettings, CreateCompilerHooks(), new ClrModuleLoader(), new ClrTypeResolver());
- compiler.Load();
- CreateTree();
- SetStatus("Assemblies Loaded!");
+ ThreadPool.QueueUserWorkItem(_ =>
+ {
+ Dispatcher.UIThread.Post(() => SetStatus("Loading Types..."));
+ compiler.Load();
+
+ Dispatcher.UIThread.Post(() => SetStatus("Building Type System Tree..."));
+ Dispatcher.UIThread.Post(CreateTree);
+
+ Dispatcher.UIThread.Post(() => SetStatus("Assemblies Loaded!"));
+ });
}
private void ClearAll()
@@ -1176,10 +1212,8 @@ private static string CreateText(List list)
var sb = new StringBuilder();
lock (list)
- {
foreach (var l in list)
sb.AppendLine(l);
- }
return sb.ToString();
}
@@ -1201,8 +1235,6 @@ private void UpdateCompilerCounters()
var entry = ExtractCounterData(line);
compilerCounterCollection.Add(entry);
}
-
- CompilerCounters.Text = CreateText(lines);
}
private static CounterEntry ExtractCounterData(string line)
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/MethodData.cs b/Source/Mosa.Tool.Explorer.Avalonia/MethodData.cs
index 4cbd5f0006..09a38d53a2 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/MethodData.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/MethodData.cs
@@ -13,10 +13,10 @@ public class MethodData
public readonly List OrderedTransformStageNames = new List();
- public readonly Dictionary> InstructionLogs = new Dictionary>();
+ public readonly Dictionary> InstructionLogs = new Dictionary>();
+ public readonly Dictionary>> TransformLogs = new Dictionary>>();
+
public readonly Dictionary> DebugLogs = new Dictionary>();
public List Counters = new List();
-
- public Dictionary>> TransformLogs = new Dictionary>>();
}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/MethodStore.cs b/Source/Mosa.Tool.Explorer.Avalonia/MethodStore.cs
index 8d8d79366f..a9a620d7e8 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/MethodStore.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/MethodStore.cs
@@ -1,6 +1,5 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.
-using System.Text;
using Mosa.Compiler.Common;
using Mosa.Compiler.MosaTypeSystem;
@@ -13,9 +12,7 @@ public class MethodStore
public void Clear()
{
lock (methodDataStore)
- {
methodDataStore.Clear();
- }
}
private static void ClearMethodDataOnNewVersion(int version, MethodData methodData)
@@ -49,6 +46,10 @@ public MethodData GetMethodData(MosaMethod method, bool create)
public void SetInstructionTraceInformation(MosaMethod method, string stage, List lines, int version)
{
var methodData = GetMethodData(method, true);
+ var records = new List();
+
+ foreach (var line in lines)
+ records.Add(new InstructionRecord(line));
lock (methodData)
{
@@ -56,13 +57,17 @@ public void SetInstructionTraceInformation(MosaMethod method, string stage, List
methodData.OrderedStageNames.AddIfNew(stage);
methodData.InstructionLogs.Remove(stage);
- methodData.InstructionLogs.Add(stage, lines);
+ methodData.InstructionLogs.Add(stage, records);
}
}
public void SetTransformTraceInformation(MosaMethod method, string stage, List lines, int version, int step)
{
var methodData = GetMethodData(method, true);
+ var records = new List();
+
+ foreach (var line in lines)
+ records.Add(new InstructionRecord(line));
lock (methodData)
{
@@ -70,13 +75,13 @@ public void SetTransformTraceInformation(MosaMethod method, string stage, List>();
- methodData.TransformLogs.Add(stage, directionary);
+ dictionary = new Dictionary>();
+ methodData.TransformLogs.Add(stage, dictionary);
}
- directionary.Add(step, lines);
+ dictionary.Add(step, records);
}
}
@@ -105,132 +110,4 @@ public void SetMethodCounterInformation(MosaMethod method, List lines, i
methodData.Counters = lines;
}
}
-
- public string GetStageInstructions(List lines, string blockLabel, bool strip, bool pad, bool removeNop)
- {
- var result = new StringBuilder();
-
- if (lines == null)
- return string.Empty;
-
- if (string.IsNullOrWhiteSpace(blockLabel))
- {
- foreach (var l in lines)
- {
- var line = l;
-
- if (line.Contains("IR.BlockStart") || line.Contains("IR.BlockEnd"))
- continue;
-
- if (removeNop && line.Contains("IR.Nop"))
- continue;
-
- if (strip)
- line = StripBracketContents(line);
-
- if (pad)
- line = PadInstruction(line);
-
- line = Simplify(line);
-
- result.Append(line);
- result.Append('\n');
- }
-
- return result.ToString();
- }
-
- var inBlock = false;
-
- foreach (var l in lines)
- {
- var line = l;
-
- if ((!inBlock) && line.StartsWith("Block #") && line.EndsWith(blockLabel))
- inBlock = true;
-
- if (!inBlock)
- continue;
-
- if (line.Contains("IR.BlockStart") || line.Contains("IR.BlockEnd"))
- continue;
-
- if (strip)
- line = StripBracketContents(line);
-
- if (pad)
- line = PadInstruction(line);
-
- line = Simplify(line);
-
- result.Append(line);
- result.Append('\n');
-
- if (line.StartsWith(" Next:"))
- return result.ToString();
- }
-
- return result.ToString();
- }
-
- private static string StripBracketContents(string s)
- {
- if (string.IsNullOrEmpty(s) || s.Length < 5)
- return s;
-
- if (!char.IsDigit(s[0]))
- return s;
-
- var at = 0;
- while (true)
- {
- var open = s.IndexOf(" [", at, StringComparison.Ordinal);
- if (open < 0)
- return s;
-
- var close = s.IndexOf(']', open);
- if (close < 0)
- return s;
-
- var part = s.Substring(open + 2, close - open - 2);
- if (part == "NULL" || char.IsSymbol(part[0]) || char.IsPunctuation(part[0]))
- {
- at = close;
- continue;
- }
-
- s = s.Remove(open, close - open + 1);
- at = open;
- }
- }
-
- private static string PadInstruction(string s)
- {
- const int padding = 30;
-
- if (string.IsNullOrEmpty(s) || s.Length < 5)
- return s;
-
- if (!char.IsDigit(s[0]))
- return s;
-
- var first = s.IndexOf(':');
- if (first is < 0 or > 15)
- return s;
-
- var second = s.IndexOf(' ', first + 2);
-
- switch (second)
- {
- case < 0: return s;
- case > padding: return s;
- default:
- {
- s = s.Insert(second, new string(' ', padding - second));
- return s;
- }
- }
- }
-
- private static string Simplify(string s) => s.Replace("const=", string.Empty);
}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/Mosa.Tool.Explorer.Avalonia.csproj b/Source/Mosa.Tool.Explorer.Avalonia/Mosa.Tool.Explorer.Avalonia.csproj
index b95bc0556d..0cf19b81e2 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/Mosa.Tool.Explorer.Avalonia.csproj
+++ b/Source/Mosa.Tool.Explorer.Avalonia/Mosa.Tool.Explorer.Avalonia.csproj
@@ -19,10 +19,10 @@
-
-
-
-
+
+
+
+
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/Stages/DebugInfoStage.cs b/Source/Mosa.Tool.Explorer.Avalonia/Stages/DebugInfoStage.cs
deleted file mode 100755
index 458e3135d4..0000000000
--- a/Source/Mosa.Tool.Explorer.Avalonia/Stages/DebugInfoStage.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) MOSA Project. Licensed under the New BSD License.
-
-using Mosa.Compiler.Framework;
-
-namespace Mosa.Tool.Explorer.Avalonia.Stages;
-
-public class DebugInfoStage : BaseMethodCompilerStage
-{
- protected override void Run()
- {
- DumpByInstructions();
- DumpRegions();
- DumpSourceInfo();
- }
-
- protected void DumpByInstructions()
- {
- var trace = CreateTraceLog("Instructions");
- if (trace == null)
- return;
-
- trace.Log("Label\tAddress\tLength\tStartLine\tEndLine\tStartColumn\tEndColumn\tInstruction\tDocument");
-
- foreach (var block in BasicBlocks)
- {
- for (var node = block.First; !node.IsBlockEndInstruction; node = node.Next)
- {
- if (node.IsEmpty)
- continue;
-
- if (node.Instruction.IgnoreDuringCodeGeneration)
- continue;
-
- var label = node.Label;
- var startLine = -1;
- var endLine = 0;
- var endColumn = 0;
- var startColumn = 0;
- var document = string.Empty;
-
- //var offset = node.Offset;
-
- var address = -1;
- var length = 0;
-
- foreach (var instruction in Method.Code)
- {
- if (instruction.Offset != label)
- continue;
-
- startLine = instruction.StartLine;
- endLine = instruction.EndLine;
- startColumn = instruction.StartColumn;
- endColumn = instruction.EndColumn;
- document = instruction.Document;
-
- break;
- }
-
- if (startLine == -1)
- continue;
-
- foreach (var region in MethodData.LabelRegions)
- {
- if (region.Label != label)
- continue;
-
- address = region.Start;
- length = region.Length;
- break;
- }
-
- if (address == -1)
- continue;
-
- trace.Log($"{label:X5}\t{address}\t{length}\t{startLine}\t{endLine}\t{startColumn}\t{endColumn}\t{node}\t{document}");
- }
- }
- }
-
- protected void DumpRegions()
- {
- var trace = CreateTraceLog("Regions");
-
- trace.Log("Label\tAddress\tLength");
-
- foreach (var region in MethodData.LabelRegions)
- {
- trace.Log($"{region.Label:X5}\t{region.Start}\t{region.Length}");
- }
- }
-
- protected void DumpSourceInfo()
- {
- var trace = CreateTraceLog("Source");
-
- trace.Log("Label\tStartLine\tEndLine\tStartColumn\tEndColumn\tDocument");
-
- foreach (var instruction in Method.Code)
- {
- trace.Log($"{instruction.Offset:X5}\t{instruction.StartLine}\t{instruction.EndLine}\t{instruction.StartColumn}\t{instruction.EndColumn}\t{instruction.Document}");
- }
- }
-}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/Stages/DisassemblyStage.cs b/Source/Mosa.Tool.Explorer.Avalonia/Stages/DisassemblyStage.cs
index d59150f209..da89e79ea6 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/Stages/DisassemblyStage.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/Stages/DisassemblyStage.cs
@@ -16,7 +16,7 @@ protected override void Run()
TracePatchRequests();
}
- protected void TraceDisassembly()
+ private void TraceDisassembly()
{
var trace = CreateTraceLog();
if (trace == null)
@@ -30,26 +30,26 @@ protected void TraceDisassembly()
var memory = new byte[length];
stream.Position = 0;
- stream.Read(memory, 0, length);
+ var read = stream.Read(memory, 0, length);
stream.Position = oldPosition;
- var disassembler = new Disassembler(Architecture.PlatformName);
- disassembler.SetMemory(memory, 0);
-
- var list = disassembler.Decode();
-
- if (list != null)
+ if (read != length)
{
- foreach (var instr in list)
- trace.Log(instr.Full);
+ trace.Log("Error: Couldn't read enough bytes to disassemble.");
+ return;
}
- else
+
+ var disassembler = new Disassembler(Architecture.PlatformName, memory, 0);
+ var instruction = disassembler.DecodeNext();
+
+ while (instruction != null)
{
- PostEvent(CompilerEvent.Error, $"Failed disassembly for method {MethodCompiler.Method}");
+ trace.Log(instruction.Full);
+ instruction = disassembler.DecodeNext();
}
}
- protected void TracePatchRequests()
+ private void TracePatchRequests()
{
var trace = CreateTraceLog("Patch-Requests");
if (trace == null)
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/Stages/GraphVizStage.cs b/Source/Mosa.Tool.Explorer.Avalonia/Stages/GraphVizStage.cs
deleted file mode 100755
index 2052ab2a57..0000000000
--- a/Source/Mosa.Tool.Explorer.Avalonia/Stages/GraphVizStage.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) MOSA Project. Licensed under the New BSD License.
-
-using Mosa.Compiler.Framework;
-
-namespace Mosa.Tool.Explorer.Avalonia.Stages;
-
-public class GraphVizStage : BaseMethodCompilerStage
-{
- private const int TraceLevel = 6;
-
- protected override void Run()
- {
- if (!IsTraceable(TraceLevel))
- return;
-
- var trace = CreateTraceLog();
- trace.Log("digraph blocks {");
-
- foreach (var block in BasicBlocks)
- {
- // trace.Log($"\t{block}");
-
- foreach (var next in block.NextBlocks)
- trace.Log($"\t{block} -> {next}");
- }
-
- trace.Log("}");
- }
-}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/TypeSystemTree.cs b/Source/Mosa.Tool.Explorer.Avalonia/TypeSystemTree.cs
index b689c8a75a..7f19e95f02 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/TypeSystemTree.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/TypeSystemTree.cs
@@ -296,7 +296,7 @@ private TreeViewItem GetOrCreateNode(MosaType type)
GetOrCreateNode(method);
}
- // Method Table
+ // Method Table
if (TypeLayout.GetMethodTable(type) != null)
{
var methodTableNode = new TreeViewItem { Header = "Method Table" };
@@ -306,11 +306,11 @@ private TreeViewItem GetOrCreateNode(MosaType type)
foreach (var method in methodList)
{
- if (included == null || included.Contains(method))
- {
- var methodNode = new TreeViewItem { Header = method.ShortName, Tag = method };
- methodTableNode.Items.Add(methodNode);
- }
+ if (included != null && !included.Contains(method))
+ continue;
+
+ var methodNode = new TreeViewItem { Header = method.ShortName, Tag = method };
+ methodTableNode.Items.Add(methodNode);
}
}
diff --git a/Source/Mosa.Tool.Explorer.Avalonia/Utils.cs b/Source/Mosa.Tool.Explorer.Avalonia/Utils.cs
index 1215ebfbf4..32082e2ea5 100755
--- a/Source/Mosa.Tool.Explorer.Avalonia/Utils.cs
+++ b/Source/Mosa.Tool.Explorer.Avalonia/Utils.cs
@@ -13,8 +13,12 @@ public static class Utils
public static readonly FilePickerOpenOptions LibraryOpenOptions = new FilePickerOpenOptions
{
+ Title = "Select a library to open in the explorer",
FileTypeFilter = new List { LibraryFileType }
};
- public static readonly FolderPickerOpenOptions FolderOpenOptions = new FolderPickerOpenOptions();
+ public static readonly FolderPickerOpenOptions FolderOpenOptions = new FolderPickerOpenOptions
+ {
+ Title = "Select a folder where to dump all method stages"
+ };
}
diff --git a/Source/Mosa.Tool.Explorer/Stages/DisassemblyStage.cs b/Source/Mosa.Tool.Explorer/Stages/DisassemblyStage.cs
index a83e83f25a..4571ab33b4 100644
--- a/Source/Mosa.Tool.Explorer/Stages/DisassemblyStage.cs
+++ b/Source/Mosa.Tool.Explorer/Stages/DisassemblyStage.cs
@@ -34,21 +34,13 @@ protected void TraceDisassembly()
stream.Read(memory, 0, length);
stream.Position = oldPosition;
- var disassembler = new Disassembler(Architecture.PlatformName);
- disassembler.SetMemory(memory, 0);
+ var disassembler = new Disassembler(Architecture.PlatformName, memory, 0);
+ var instruction = disassembler.DecodeNext();
- var list = disassembler.Decode();
-
- if (list != null)
- {
- foreach (var instr in list)
- {
- trace.Log(instr.Full);
- }
- }
- else
+ while (instruction != null)
{
- PostEvent(CompilerEvent.Error, $"Failed disassembly for method {MethodCompiler.Method}");
+ trace.Log(instruction.Full);
+ instruction = disassembler.DecodeNext();
}
}
diff --git a/Source/Mosa.Utility.Disassembler/DecodedInstruction.cs b/Source/Mosa.Utility.Disassembler/DecodedInstruction.cs
index 0dc54452d0..ce1f0102c3 100644
--- a/Source/Mosa.Utility.Disassembler/DecodedInstruction.cs
+++ b/Source/Mosa.Utility.Disassembler/DecodedInstruction.cs
@@ -2,13 +2,13 @@
namespace Mosa.Utility.Disassembler;
-public partial class DecodedInstruction
+public class DecodedInstruction
{
- public ulong Address { get; set; }
+ public ulong Address { get; init; }
- public int Length { get; set; }
+ public uint Length { get; init; }
- public string Instruction { get; set; }
+ public string Instruction { get; init; }
- public string Full { get; set; }
+ public string Full { get; init; }
}
diff --git a/Source/Mosa.Utility.Disassembler/Disassembler.cs b/Source/Mosa.Utility.Disassembler/Disassembler.cs
index 78d6b562e1..4b3c7223b9 100644
--- a/Source/Mosa.Utility.Disassembler/Disassembler.cs
+++ b/Source/Mosa.Utility.Disassembler/Disassembler.cs
@@ -5,127 +5,88 @@
using Reko.Arch.Arm;
using Reko.Arch.X86;
using Reko.Core;
+using Reko.Core.Machine;
using Reko.Core.Memory;
namespace Mosa.Utility.Disassembler;
-public partial class Disassembler
+public class Disassembler
{
- private byte[] memory;
-
public ulong Offset { get; set; }
- private readonly ProcessorArchitecture arch;
- private MemoryArea memoryArea;
+ private readonly byte[] memory;
+ private readonly IEnumerator instructions;
+ private readonly StringBuilder sb = new StringBuilder(100);
- public Disassembler(string platform)
+ public Disassembler(string platform, byte[] bytes, ulong address)
{
var services = new ServiceContainer();
var options = new Dictionary();
+ var memoryArea = new ByteMemoryArea(Address.Ptr32((uint)address), bytes);
- arch = platform.ToLowerInvariant() switch
+ ProcessorArchitecture arch = platform.ToLowerInvariant() switch
{
"arm32" => new Arm32Architecture(services, "arm32", options),
"arm64" => new Arm64Architecture(services, "arm64", options),
"x86" => new X86ArchitectureFlat32(services, "x86-protected-32", options),
"x64" => new X86ArchitectureFlat64(services, "x86-protected-64", options),
- _ => arch
+ _ => throw new PlatformNotSupportedException(platform)
};
- }
- public void SetMemory(byte[] memory, ulong address)
- {
- this.memory = memory;
- memoryArea = new ByteMemoryArea(Address.Ptr32((uint)address), memory);
+ memory = bytes;
+ instructions = arch.CreateDisassembler(memoryArea.CreateLeReader((long)Offset)).GetEnumerator();
}
- public List Decode(int count = int.MaxValue)
+ public DecodedInstruction DecodeNext()
{
- var decoded = new List();
-
- var sb = new StringBuilder(100);
-
- try
- {
- var dasm = arch.CreateDisassembler(memoryArea.CreateLeReader((long)Offset));
-
- foreach (var instr in dasm)
- {
- var len = instr.Length;
- var address = instr.Address.Offset;
- var instruction = instr.ToString().Replace('\t', ' ');
-
- // preference
- instruction = instruction.Replace(",", ", ");
-
- // fix up
- //instruction = ChangeHex(instruction);
-
- sb.AppendFormat("{0:x8}", address);
- sb.Append(' ');
- var bytes = BytesToHex(memory, (uint)Offset, len);
- sb.Append(bytes == null ? string.Empty : bytes.ToString());
- sb.Append(string.Empty.PadRight(41 - sb.Length, ' '));
- sb.Append(instruction);
-
- decoded.Add(new DecodedInstruction
- {
- Address = address,
- Length = len,
- Instruction = instruction,
- Full = sb.ToString()
- });
-
- sb.Clear();
+ if (!instructions.MoveNext())
+ return null;
- count--;
+ var machineInstruction = instructions.Current;
+ if (machineInstruction == null)
+ return null;
- if (count == 0)
- break;
+ var length = (uint)machineInstruction.Length;
+ var address = machineInstruction.Address.Offset;
+ var instruction = machineInstruction.ToString()
+ .Replace('\t', ' ')
+ .Replace(",", ", ");
- Offset += (uint)len;
- }
+ // FIXME
+ //instruction = ChangeHex(instruction);
- return decoded;
- }
- catch
+ sb.Append(address.ToString("x8"));
+ sb.Append(' ');
+ for (var i = 0U; i < length; i++)
{
- return decoded;
+ var b = memory[i + Offset];
+ sb.Append(b.ToString("x2"));
+ sb.Append(' ');
}
- }
-
- private static StringBuilder BytesToHex(byte[] memory, uint offset, int length)
- {
- if (length == 0)
- return null;
+ for (var i = sb.Length; i < 41; i++)
+ sb.Append(' ');
+ sb.Append(instruction);
- var sb = new StringBuilder();
-
- for (uint i = 0; i < length; i++)
+ var decodedInstruction = new DecodedInstruction
{
- var b = memory[i + offset];
+ Address = address,
+ Length = length,
+ Instruction = instruction,
+ Full = sb.ToString()
+ };
- sb.AppendFormat("{0:x2} ", b);
- }
+ sb.Clear();
- sb.Length--;
+ Offset += length;
- return sb;
+ return decodedInstruction;
}
- private static bool IsHex(char c)
+ private static bool IsHex(char c) => c switch
{
- if (c >= '0' && c <= '9')
- return true;
-
- if (c >= 'a' && c <= 'f')
- return true;
-
- if (c >= 'A' && c <= 'F')
- return true;
-
- return false;
- }
+ >= '0' and <= '9' or >= 'a' and <= 'f' or >= 'A' and <= 'F' => true,
+ _ => false
+ };
private static int IsNextWordHex(string s, int start)
{
@@ -150,7 +111,6 @@ private static string ChangeHex(string s)
for (var i = 0; i < s.Length; i++)
{
var c = s[i];
-
var l = IsNextWordHex(s, i);
if (l == 0)
@@ -158,17 +118,15 @@ private static string ChangeHex(string s)
sb.Append(c);
continue;
}
- else
- {
- var hex = s.Substring(i, l);
- var value = long.Parse(hex, System.Globalization.NumberStyles.HexNumber);
- var hex2 = Convert.ToString(value, 16).ToUpper();
- sb.Append("0x");
- sb.Append(hex2);
+ var hex = s.Substring(i, l);
+ var value = long.Parse(hex, System.Globalization.NumberStyles.HexNumber);
+ var hex2 = Convert.ToString(value, 16).ToUpper();
- i += l;
- }
+ sb.Append("0x");
+ sb.Append(hex2);
+
+ i += l;
}
return sb.ToString();
diff --git a/Source/Mosa.Utility.Launcher/Builder.cs b/Source/Mosa.Utility.Launcher/Builder.cs
index 6933287cb7..5857a10547 100644
--- a/Source/Mosa.Utility.Launcher/Builder.cs
+++ b/Source/Mosa.Utility.Launcher/Builder.cs
@@ -241,12 +241,12 @@ private void GenerateASMFile()
for (ulong i = fileOffset; i < (ulong)code2.Length; i++)
code[i - fileOffset] = code2[i];
- var disassembler = new Disassembler.Disassembler(MosaSettings.Platform);
- disassembler.SetMemory(code, startingAddress);
+ var disassembler = new Disassembler.Disassembler(MosaSettings.Platform, code, startingAddress);
using var dest = File.CreateText(MosaSettings.AsmFile);
- foreach (var instruction in disassembler.Decode())
+ var instruction = disassembler.DecodeNext();
+ while (instruction != null)
{
if (map.TryGetValue(instruction.Address, out List list))
foreach (var entry in list)
@@ -256,6 +256,8 @@ private void GenerateASMFile()
if (instruction.Address > startingAddress + length)
break;
+
+ instruction = disassembler.DecodeNext();
}
}
diff --git a/Source/Mosa.sln b/Source/Mosa.sln
index 96f56a44c5..8c5ee8e7c1 100644
--- a/Source/Mosa.sln
+++ b/Source/Mosa.sln
@@ -252,6 +252,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Template", "Template", "{A1
TemplateLibrary.txt = TemplateLibrary.txt
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mosa.Tool.Explorer.Avalonia", "Mosa.Tool.Explorer.Avalonia\Mosa.Tool.Explorer.Avalonia.csproj", "{763FDCF2-2501-4756-A7A1-62813D610B00}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1436,6 +1438,24 @@ Global
{26667157-E909-4F7A-9130-F8B5C15A1E4E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{26667157-E909-4F7A-9130-F8B5C15A1E4E}.Release|x86.ActiveCfg = Release|Any CPU
{26667157-E909-4F7A-9130-F8B5C15A1E4E}.Release|x86.Build.0 = Release|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Debug|x86.Build.0 = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Description|Any CPU.ActiveCfg = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Description|Any CPU.Build.0 = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Description|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Description|Mixed Platforms.Build.0 = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Description|x86.ActiveCfg = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Description|x86.Build.0 = Debug|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Release|Any CPU.Build.0 = Release|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Release|x86.ActiveCfg = Release|Any CPU
+ {763FDCF2-2501-4756-A7A1-62813D610B00}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1512,6 +1532,7 @@ Global
{E94607AB-584E-4D15-B0FA-68E086FE9E70} = {75BB6B40-C122-422F-8B40-F50A70A08E0D}
{26667157-E909-4F7A-9130-F8B5C15A1E4E} = {3A538FDC-0226-4971-A3C0-31570CDA340D}
{A1660856-2153-477F-BAAC-39E8BEB75971} = {F0EFF742-92D5-4219-939A-8F6F8DAB24E5}
+ {763FDCF2-2501-4756-A7A1-62813D610B00} = {D032B24A-CE3A-4881-BACE-CC4FE0AFD69D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C22A5C94-6B05-4B1B-845A-A2EA7615E093}