Skip to content

Commit

Permalink
Add Thread.IsAlive and CilVirtualMachine.DestroyThread.
Browse files Browse the repository at this point in the history
  • Loading branch information
Washi1337 committed Feb 14, 2024
1 parent fdf9222 commit 9f36202
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal CilThread(CilVirtualMachine machine, CallStack callStack)
{
Machine = machine;
CallStack = callStack;
IsAlive = true;
}

/// <summary>
Expand All @@ -43,6 +44,15 @@ public CallStack CallStack
get;
}

/// <summary>
/// Gets a value indicating whether the thread is alive and present in the parent machine.
/// </summary>
public bool IsAlive
{
get;
internal set;
}

/// <summary>
/// Runs the virtual machine until it halts.
/// </summary>
Expand Down Expand Up @@ -203,6 +213,9 @@ public void Step()

private void Step(CilExecutionContext context)
{
if (!IsAlive)
throw new CilEmulatorException("The thread is not alive.");

if (CallStack.Peek().IsRoot)
throw new CilEmulatorException("No method is currently being executed.");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using AsmResolver.DotNet;
using Echo.Memory;
using Echo.Platforms.AsmResolver.Emulation.Dispatch;
Expand All @@ -15,6 +17,16 @@ namespace Echo.Platforms.AsmResolver.Emulation
/// </summary>
public class CilVirtualMachine
{
/// <summary>
/// Fires when a new thread was created.
/// </summary>
public event EventHandler<CilThread>? ThreadCreated;

/// <summary>
/// Fires when a thread was destroyed.
/// </summary>
public event EventHandler<CilThread>? ThreadDestroyed;

private readonly List<CilThread> _threads = new();
private readonly CallStackMemory _callStackMemory;

Expand Down Expand Up @@ -167,7 +179,31 @@ public CilThread CreateThread(uint stackSize = 0x0010_0000)
var stack = _callStackMemory.Allocate(stackSize);
var thread = new CilThread(this, stack);
_threads.Add(thread);
ThreadCreated?.Invoke(this, thread);
return thread;
}

/// <summary>
/// Removes a thread and its stack from the machine.
/// </summary>
/// <param name="thread">The thread to remove.</param>
/// <remarks>
/// This does not gracefully terminate a thread. Any code that is still running will remain executing, and may
/// have unwanted side-effects. Therefore, be sure to only call this method only when it is certain that no code
/// is running.
/// </remarks>
public void DestroyThread(CilThread thread)
{
if (thread.Machine != this)
throw new ArgumentException("Cannot remove a thread from a different machine.");
if (!thread.IsAlive)
throw new ArgumentException("Cannot destroy a thread that is already destroyed.");

thread.IsAlive = false;
_threads.Remove(thread);
_callStackMemory.Free(thread.CallStack);

ThreadDestroyed?.Invoke(this, thread);
}
}
}

0 comments on commit 9f36202

Please sign in to comment.