moonsharp
moonsharp copied to clipboard
System.IndexOutOfRangeException
I was writing a wrapper around NUnit's assert functions, I encountered a strange issue. When running the following code:
using System;
using MoonSharp.Interpreter;
using NUnit.Framework;
namespace Test {
class Test {
public class TestClass {
//simple wrapper around NUnit.Framework.Assert.Catch
public DynValue Catch(DynValue testDelegate, DynValue message) {
Exception e = Assert.Catch(() => testDelegate.Function.Call(), message.CastToString());
return DynValue.NewTuple(DynValue.NewString(e.GetType().Name), DynValue.NewString(e.Message));
}
}
public static void Main(string[] args) {
try {
UserData.RegisterType<TestClass>();
Script s = new Script();
s.Globals["Assert"] = UserData.Create(new TestClass());
s.DoString(@"
-- does not throw, because function argument throws
Assert:Catch(
-- AssertionException bubbles up
function()
-- throws AssertionException, because function argument does not throw
Assert:Catch(
-- does not throw
function()
end
)
end
)
");
} catch (InterpreterException e) {
Console.WriteLine(e.DecoratedMessage);
}
}
}
}
The following exception is produced:
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at MoonSharp.Interpreter.Execution.VM.Processor.AssignLocal(SymbolRef symref, DynValue value) in src\MoonSharp.Interpreter\Execution\VM\Processor\Processor_InstructionLoop.cs:line 358
at MoonSharp.Interpreter.Execution.VM.Processor.ExecStoreLcl(Instruction i) in src\MoonSharp.Interpreter\Execution\VM\Processor\Processor_InstructionLoop.cs:line 370
at MoonSharp.Interpreter.Execution.VM.Processor.Processing_Loop(Int32 instructionPtr) in src\MoonSharp.Interpreter\Execution\VM\Processor\Processor_InstructionLoop.cs:line 210
at MoonSharp.Interpreter.Execution.VM.Processor.Call(DynValue function, DynValue[] args) in src\MoonSharp.Interpreter\Execution\VM\Processor\Processor.cs:line 67
at MoonSharp.Interpreter.Script.Call(DynValue function, DynValue[] args) in src\MoonSharp.Interpreter\Script.cs:line 483
at MoonSharp.Interpreter.Script.Call(DynValue function) in src\MoonSharp.Interpreter\Script.cs:line 442
at MoonSharp.Interpreter.Script.DoString(String code, Table globalContext, String codeFriendlyName) in src\MoonSharp.Interpreter\Script.cs:line 331
at Test.Test.Main(String[] args) in Program.cs:line 29
When changing the Lua code to this, it works as expected:
Assert:Catch(function()
Assert:Catch(function()
end)
end)
or
return Assert:Catch(function()
Assert:Catch(function()
end)
end)
and accept return values from DoString, the results are as expected.
The issue isn't just NUnit. It happens when any exception but ScriptRuntimeException is thrown.
//this works
public DynValue Catch(DynValue testDelegate, DynValue message) {
Exception e = null;
try {
testDelegate.Function.Call();
} catch(Exception ex) {
e = ex;
}
if (e == null) {
throw new ScriptRuntimeException(message.CastToString());
}
return DynValue.NewTuple(DynValue.NewString(e.GetType().Name), DynValue.NewString(e.Message));
}
//this does not work
public DynValue Catch(DynValue testDelegate, DynValue message) {
Exception e = null;
try {
testDelegate.Function.Call();
} catch(Exception ex) {
e = ex;
}
if (e == null) {
throw new Exception(message.CastToString());
}
return DynValue.NewTuple(DynValue.NewString(e.GetType().Name), DynValue.NewString(e.Message));
}
I'm not sure what's going on here.