Skip to content

Commit

Permalink
Minor fixes and optimizations, make some VM exceptions recoverable.
Browse files Browse the repository at this point in the history
  • Loading branch information
vddCore committed May 25, 2024
1 parent e59d046 commit 2431bfe
Show file tree
Hide file tree
Showing 15 changed files with 145 additions and 76 deletions.
1 change: 1 addition & 0 deletions Core/EVIL.Lexical/Lexer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using System.Text;
using System.Threading.Tasks;

namespace EVIL.Lexical
{
Expand Down
4 changes: 3 additions & 1 deletion VirtualMachine/EVIL.Ceres.Runtime/EvilRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ public List<RuntimeModule> RegisterBuiltInModules()
public T RegisterModule<T>(out DynamicValue table) where T : RuntimeModule, new()
{
var module = new T();

table = module.AttachTo(Global);

module.Registered(this);

return module;
}

Expand Down
24 changes: 20 additions & 4 deletions VirtualMachine/EVIL.Ceres.Runtime/RuntimeModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace EVIL.Ceres.Runtime
{
public abstract class RuntimeModule : PropertyTable
{
public const string GlobalMergeKey = "<global>";

public abstract string FullyQualifiedName { get; }

public RuntimeModule()
Expand All @@ -24,14 +26,28 @@ public DynamicValue AttachTo(Table table)
{
var ret = this;

table.SetUsingPath<Table>(
FullyQualifiedName,
ret
);
if (FullyQualifiedName == GlobalMergeKey)
{
foreach (var (k, v) in this) table[k] = v;
}
else
{
table.SetUsingPath<Table>(
FullyQualifiedName,
ret
);
}

return ret;
}

internal void Registered(EvilRuntime runtime)
=> OnRegistered(runtime);

protected virtual void OnRegistered(EvilRuntime runtime)
{
}

private void RegisterNativeFunctions()
{
var validFunctions = GetType().GetMethods(
Expand Down
2 changes: 1 addition & 1 deletion VirtualMachine/EVIL.Ceres/EVIL.Ceres.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>

<Version>7.5.0</Version>
<Version>7.6.0</Version>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace EVIL.Ceres.ExecutionEngine
{
public class ArrayException : VirtualMachineException
public class ArrayException : RecoverableVirtualMachineException
{
internal ArrayException(string message, Exception innerException)
: base(message, innerException)
Expand Down

This file was deleted.

86 changes: 56 additions & 30 deletions VirtualMachine/EVIL.Ceres/ExecutionEngine/Concurrency/Fiber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using EVIL.Ceres.ExecutionEngine.Collections;
using EVIL.Ceres.ExecutionEngine.Diagnostics;
using EVIL.Ceres.ExecutionEngine.Diagnostics.Debugging;
using EVIL.Ceres.ExecutionEngine.TypeSystem;
Expand All @@ -12,7 +13,7 @@ namespace EVIL.Ceres.ExecutionEngine.Concurrency
{
public sealed class Fiber
{
private Queue<(Diagnostics.Chunk Chunk, DynamicValue[] Arguments)> _scheduledChunks;
private Queue<(Chunk Chunk, DynamicValue[] Arguments)> _scheduledChunks;
private HashSet<Fiber> _waitingFor;

private Stack<DynamicValue> _evaluationStack;
Expand All @@ -21,6 +22,7 @@ public sealed class Fiber

private ExecutionUnit _executionUnit;
private FiberCrashHandler? _crashHandler;
private FiberState _state;

internal ChunkInvokeHandler? OnChunkInvoke { get; private set; }
internal NativeFunctionInvokeHandler? OnNativeFunctionInvoke { get; private set; }
Expand All @@ -32,7 +34,8 @@ public sealed class Fiber

public CeresVM VirtualMachine { get; }

public FiberState State { get; private set; }
public FiberState State => _state;

public bool ImmuneToCollection { get; private set; }

public IReadOnlyCollection<DynamicValue> EvaluationStack
Expand Down Expand Up @@ -75,7 +78,7 @@ internal Fiber(CeresVM virtualMachine, Dictionary<string, ClosureContext>? closu
_callStack
);

State = FiberState.Fresh;
_state = FiberState.Fresh;
}

public void Schedule(Chunk chunk, params DynamicValue[] args)
Expand All @@ -96,17 +99,17 @@ public void Schedule(Chunk chunk, bool resumeImmediately, params DynamicValue[]

public void BlockUntilFinished()
{
while (State != FiberState.Finished &&
State != FiberState.Crashed)
while (_state != FiberState.Finished &&
_state != FiberState.Crashed)
{
Thread.Sleep(1);
}
}

public async Task BlockUntilFinishedAsync()
{
while (State != FiberState.Finished &&
State != FiberState.Crashed)
while (_state != FiberState.Finished &&
_state != FiberState.Crashed)
{
await Task.Delay(1);
}
Expand Down Expand Up @@ -150,7 +153,7 @@ public void Step()
{
try
{
if (State != FiberState.Running)
if (_state != FiberState.Running)
return;

lock (_callStack)
Expand All @@ -165,7 +168,7 @@ public void Step()
}
else
{
State = FiberState.Finished;
_state = FiberState.Finished;
return;
}
}
Expand All @@ -176,33 +179,57 @@ public void Step()
}
catch (Exception e)
{
EnterCrashState();
if (e is RecoverableVirtualMachineException rvme)
{
try
{
ThrowFromNative(
new Error(
new Table { { "native_exception", DynamicValue.FromObject(rvme) } },
rvme.Message
)
);
}
catch
{
EnterCrashState();

if (_crashHandler != null)
if (_crashHandler != null)
{
_crashHandler(this, e);
}
}
}
else
{
_crashHandler(this, e);
EnterCrashState();

if (_crashHandler != null)
{
_crashHandler(this, e);
}
}
}
}

public void Yield()
{
if (State != FiberState.Running)
if (_state != FiberState.Running)
{
return;
}

State = FiberState.Paused;
_state = FiberState.Paused;
}

public void Yield(Fiber to)
{
if (State != FiberState.Running)
if (_state != FiberState.Running)
{
return;
}

State = FiberState.Paused;
_state = FiberState.Paused;
to.Resume();
}

Expand All @@ -213,7 +240,7 @@ public void Await()
return;
}

State = FiberState.Awaiting;
_state = FiberState.Awaiting;
}

public void WaitFor(Fiber fiber)
Expand All @@ -223,7 +250,7 @@ public void WaitFor(Fiber fiber)
throw new FiberException("A fiber cannot wait for self.");
}

if (fiber.State == FiberState.Finished)
if (fiber._state == FiberState.Finished)
{
return;
}
Expand All @@ -236,11 +263,11 @@ public void StopWaitingFor(Fiber fiber)
{
_waitingFor.Remove(fiber);

if (State == FiberState.Awaiting)
if (_state == FiberState.Awaiting)
{
if (!_waitingFor.Any())
{
State = FiberState.Running;
_state = FiberState.Running;
}
}
}
Expand All @@ -256,7 +283,7 @@ public void WaitForAll(params Fiber[] fibers)
throw new FiberException("A fiber cannot wait for self.");
}

if (fiber.State == FiberState.Finished)
if (fiber._state == FiberState.Finished)
{
continue;
}
Expand All @@ -269,15 +296,15 @@ public void WaitForAll(params Fiber[] fibers)

public void Resume()
{
if (State == FiberState.Awaiting)
if (_state == FiberState.Awaiting)
{
if (_waitingFor.Any())
{
return;
}
}

State = FiberState.Running;
_state = FiberState.Running;
}

public void Stop()
Expand Down Expand Up @@ -307,7 +334,7 @@ public void Reset()
_waitingFor.Clear();
}

State = FiberState.Fresh;
_state = FiberState.Fresh;
}

public void Immunize()
Expand Down Expand Up @@ -389,9 +416,7 @@ public DynamicValue ThrowFromNative(DynamicValue value)
{
lock (_callStack)
lock (_evaluationStack)
{
var callStackCopy = _callStack.ToArray();

{
var frame = _callStack.Peek();
if (frame is NativeStackFrame nsf)
{
Expand All @@ -400,7 +425,8 @@ public DynamicValue ThrowFromNative(DynamicValue value)
}

_evaluationStack.Push(value);
UnwindTryHandle(callStackCopy);

UnwindTryHandle(_callStack.ToArray());
}

return DynamicValue.Nil;
Expand Down Expand Up @@ -438,12 +464,12 @@ internal void UnwindTryHandle(StackFrame[] callStackCopy)

internal void RemoveFinishedAwaitees()
{
_waitingFor.RemoveWhere(x => x.State == FiberState.Finished);
_waitingFor.RemoveWhere(x => x._state == FiberState.Finished);
}

private void EnterCrashState()
{
State = FiberState.Crashed;
_state = FiberState.Crashed;
}

private void Invoke(Chunk chunk, DynamicValue[] args)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace EVIL.Ceres.ExecutionEngine
{
public class DivisionByZeroException : VirtualMachineException
public class DivisionByZeroException : RecoverableVirtualMachineException
{
internal DivisionByZeroException()
: base("Attempt to divide by zero.")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace EVIL.Ceres.ExecutionEngine
{
public class RecoverableVirtualMachineException : VirtualMachineException
{
internal RecoverableVirtualMachineException(string message, Exception innerException)
: base(message, innerException)
{
}

internal RecoverableVirtualMachineException(string message)
: base(message)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace EVIL.Ceres.ExecutionEngine.TypeSystem
{
public class MalformedNumberException : VirtualMachineException
public class MalformedNumberException : RecoverableVirtualMachineException
{
internal MalformedNumberException(string message, Exception innerException)
: base(message, innerException)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace EVIL.Ceres.ExecutionEngine.TypeSystem
{
public sealed class UnsupportedDynamicValueOperationException : VirtualMachineException
public sealed class UnsupportedDynamicValueOperationException : RecoverableVirtualMachineException
{
internal UnsupportedDynamicValueOperationException(string message)
: base(message)
Expand Down
Loading

0 comments on commit 2431bfe

Please sign in to comment.