Commit bdcc2e93 authored by capresti's avatar capresti
Browse files

Further fixes from Bastian:

- Added IsExecuting variable to Lua
- Fix for error info inclusion of line number (Issue #4)


git-svn-id: http://luainterface.googlecode.com/svn/trunk@14 63eb109e-e254-0410-a61e-ed0b8f8614f5
parent 75f46254
......@@ -189,24 +189,19 @@ namespace LuaInterface
/// <summary>
/// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
/// </summary>
/// <exception cref="LuaScriptException">Thrown if the script caused an exception</exception>
void ThrowExceptionFromError(int oldTop)
{
object err = translator.getObject(luaState, -1);
LuaDLL.lua_settop(luaState, oldTop);
Exception ex = err as Exception;
// A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved)
LuaScriptException luaEx = err as LuaScriptException;
if (luaEx != null) throw luaEx;
// A true Lua error, best interpreted as a string - wrap it in a LuaException and rethrow.
if (ex == null)
{
if (err == null)
err = "Unknown Lua Error";
throw new LuaException(err.ToString());
}
// If the 'error' on the stack is an actual C# exception, wrap and rethrow it to preserve the stack trace
throw new LuaException(".NET exception occured", ex);
// A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it
if (err == null) err = "Unknown Lua Error";
throw new LuaScriptException(err.ToString(), "");
}
......@@ -231,6 +226,13 @@ namespace LuaInterface
return 0;
}
private bool executing;
/// <summary>
/// True while a script is being executed
/// </summary>
public bool IsExecuting { get { return executing; } }
/// <summary>
///
/// </summary>
......@@ -240,9 +242,15 @@ namespace LuaInterface
public LuaFunction LoadString(string chunk, string name)
{
int oldTop = LuaDLL.lua_gettop(luaState);
if (LuaDLL.luaL_loadbuffer(luaState, chunk, name) != 0)
ThrowExceptionFromError(oldTop);
executing = true;
try
{
if (LuaDLL.luaL_loadbuffer(luaState, chunk, name) != 0)
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
LuaFunction result = translator.getFunction(luaState, -1);
translator.popValues(luaState, oldTop);
......@@ -274,14 +282,19 @@ namespace LuaInterface
public object[] DoString(string chunk)
{
int oldTop=LuaDLL.lua_gettop(luaState);
if(LuaDLL.luaL_loadbuffer(luaState,chunk,"chunk")==0)
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
else
if (LuaDLL.luaL_loadbuffer(luaState, chunk, "chunk") == 0)
{
executing = true;
try
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
}
else
ThrowExceptionFromError(oldTop);
return null; // Never reached - keeps compiler happy
......@@ -296,12 +309,17 @@ namespace LuaInterface
public object[] DoString(string chunk, string chunkName)
{
int oldTop = LuaDLL.lua_gettop(luaState);
executing = true;
if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunkName) == 0)
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
try
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
}
else
ThrowExceptionFromError(oldTop);
......@@ -318,10 +336,15 @@ namespace LuaInterface
int oldTop=LuaDLL.lua_gettop(luaState);
if(LuaDLL.luaL_loadfile(luaState,fileName)==0)
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
executing = true;
try
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
}
else
ThrowExceptionFromError(oldTop);
......@@ -577,10 +600,15 @@ namespace LuaInterface
{
translator.push(luaState,args[i]);
}
}
int error = LuaDLL.lua_pcall(luaState, nArgs, -1, 0);
if (error != 0)
ThrowExceptionFromError(oldTop);
}
executing = true;
try
{
int error = LuaDLL.lua_pcall(luaState, nArgs, -1, 0);
if (error != 0)
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
if(returnTypes != null)
return translator.popValues(luaState,oldTop,returnTypes);
......@@ -659,7 +687,7 @@ namespace LuaInterface
/// <author>Reinhard Ostermeier</author>
private LuaHookFunction hookCallback = null;
/// <summary>
/// <summary>
/// Activates the debug hook
/// </summary>
/// <param name="mask">Mask</param>
......
......@@ -61,6 +61,7 @@
<Compile Include="LuaGlobalAttribute.cs" />
<Compile Include="LuaHideAttribute.cs" />
<Compile Include="LuaRegistrationHelper.cs" />
<Compile Include="LuaScriptException.cs" />
<Compile Include="LuaTable.cs" />
<Compile Include="LuaUserData.cs" />
<Compile Include="Metatables.cs" />
......
using System;
namespace LuaInterface
{
/// <summary>
/// Exceptions thrown by the Lua runtime because of errors in the script
/// </summary>
public class LuaScriptException : LuaException
{
/// <summary>
/// Returns true if the exception has occured as the result of a .NET exception in user code
/// </summary>
public bool IsNetException { get; private set; }
private readonly string source;
/// <summary>
/// The position in the script where the exception was triggered.
/// </summary>
public override string Source { get { return source; } }
/// <summary>
/// Creates a new Lua-only exception.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="source">The position in the script where the exception was triggered.</param>
public LuaScriptException(string message, string source) : base(message)
{
this.source = source;
}
/// <summary>
/// Creates a new .NET wrapping exception.
/// </summary>
/// <param name="innerException">The .NET exception triggered by user-code.</param>
/// <param name="source">The position in the script where the exception was triggered.</param>
public LuaScriptException(Exception innerException, string source)
: base("A .NET exception occured in user-code", innerException)
{
this.source = source;
this.IsNetException = true;
}
public override string ToString()
{
// Prepend the error source
return GetType().FullName + ": " + source + Message;
}
}
}
\ No newline at end of file
......@@ -158,27 +158,40 @@ namespace LuaInterface
/*
* Passes errors (argument e) to the Lua interpreter
*/
internal void throwError(IntPtr luaState,object e)
{
// If the argument is a mere string, we are free to add extra info to it (as opposed to some private C# exception object or somesuch, which we just pass up)
if (e is string)
{
// We use this to remove anything pushed by luaL_where
int oldTop = LuaDLL.lua_gettop(luaState);
internal void throwError(IntPtr luaState, object e)
{
// We use this to remove anything pushed by luaL_where
int oldTop = LuaDLL.lua_gettop(luaState);
// Stack frame #1 is our C# wrapper, so not very interesting to the user
// Stack frame #2 must be the lua code that called us, so that's what we want to use
LuaDLL.luaL_where(luaState, 2);
object[] curlev = popValues(luaState, oldTop);
// Debug.WriteLine(curlev);
// Stack frame #1 is our C# wrapper, so not very interesting to the user
// Stack frame #2 must be the lua code that called us, so that's what we want to use
LuaDLL.luaL_where(luaState, 1);
object[] curlev = popValues(luaState, oldTop);
if (curlev.Length > 0)
e = curlev[0].ToString() + e;
// Determine the position in the script where the exception was triggered
string errLocation = "";
if (curlev.Length > 0)
errLocation = curlev[0].ToString();
string message = e as string;
if (message != null)
{
// Wrap Lua error (just a string) and store the error location
e = new LuaScriptException(message, errLocation);
}
else
{
Exception ex = e as Exception;
if (ex != null)
{
// Wrap generic .NET exception as an InnerException and store the error location
e = new LuaScriptException(ex, errLocation);
}
}
push(luaState,e);
LuaDLL.lua_error(luaState);
}
push(luaState, e);
LuaDLL.lua_error(luaState);
}
/*
* Implementation of load_assembly. Throws an error
* if the assembly is not found.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment