Commit ceac1a5f authored by Vinicius Jarina's avatar Vinicius Jarina
Browse files

Move call to `lua_error` to the same level of the delegate callback

* Lua.Error() will call setjmp and this can cause a crash with CLR on Linux, it seems that calling the setjmp longjmp twice will crash on *nix systems.
This should make this issue work a bit better: https://github.com/NLua/NLua/issues/344
parent 09837ff0
...@@ -367,7 +367,7 @@ namespace NLua ...@@ -367,7 +367,7 @@ namespace NLua
return 0; return 0;
_translator.ThrowError(_luaState, caughtExcept); _translator.ThrowError(_luaState, caughtExcept);
_luaState.PushNil(); //_luaState.PushNil();
return 1; return 1;
} }
......
...@@ -17,6 +17,7 @@ using NLua.Extensions; ...@@ -17,6 +17,7 @@ using NLua.Extensions;
using LuaState = KeraLua.Lua; using LuaState = KeraLua.Lua;
using LuaNativeFunction = KeraLua.LuaFunction; using LuaNativeFunction = KeraLua.LuaFunction;
using NLua.Exceptions;
namespace NLua namespace NLua
{ {
...@@ -84,8 +85,13 @@ namespace NLua ...@@ -84,8 +85,13 @@ namespace NLua
var translator = ObjectTranslatorPool.Instance.Find(state); var translator = ObjectTranslatorPool.Instance.Find(state);
var func = (LuaNativeFunction)translator.GetRawNetObject(state, 1); var func = (LuaNativeFunction)translator.GetRawNetObject(state, 1);
state.Remove(1); state.Remove(1);
return func(luaState); int result = func(luaState);
} var exception = translator.GetObject(state, -1) as LuaScriptException;
if (exception != null)
return state.Error();
return result;
}
/* /*
* __gc metafunction of CLR objects. * __gc metafunction of CLR objects.
...@@ -221,7 +227,7 @@ namespace NLua ...@@ -221,7 +227,7 @@ namespace NLua
if (obj1 == null) if (obj1 == null)
{ {
translator.ThrowError(luaState, "Cannot negate a nil object"); translator.ThrowError(luaState, "Cannot negate a nil object");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -231,7 +237,7 @@ namespace NLua ...@@ -231,7 +237,7 @@ namespace NLua
if (opUnaryNegation == null) if (opUnaryNegation == null)
{ {
translator.ThrowError(luaState, "Cannot negate object (" + type.Name + " does not overload the operator -)"); translator.ThrowError(luaState, "Cannot negate object (" + type.Name + " does not overload the operator -)");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
obj1 = opUnaryNegation.Invoke(obj1, new [] { obj1 }); obj1 = opUnaryNegation.Invoke(obj1, new [] { obj1 });
...@@ -331,7 +337,7 @@ namespace NLua ...@@ -331,7 +337,7 @@ namespace NLua
if (obj == null) if (obj == null)
{ {
_translator.ThrowError(luaState, "Trying to index an invalid object reference"); _translator.ThrowError(luaState, "Trying to index an invalid object reference");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -546,7 +552,7 @@ namespace NLua ...@@ -546,7 +552,7 @@ namespace NLua
if (!found) if (!found)
{ {
_translator.ThrowError(luaState, "key not found: " + index); _translator.ThrowError(luaState, "key not found: " + index);
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -561,7 +567,7 @@ namespace NLua ...@@ -561,7 +567,7 @@ namespace NLua
else else
_translator.ThrowError(luaState, "exception indexing '" + index + "' " + e.Message); _translator.ThrowError(luaState, "exception indexing '" + index + "' " + e.Message);
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
} }
...@@ -608,7 +614,7 @@ namespace NLua ...@@ -608,7 +614,7 @@ namespace NLua
else else
_translator.ThrowError(luaState, "exception indexing '" + index + "' " + e.Message); _translator.ThrowError(luaState, "exception indexing '" + index + "' " + e.Message);
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
} }
...@@ -637,8 +643,8 @@ namespace NLua ...@@ -637,8 +643,8 @@ namespace NLua
if (obj == null) if (obj == null)
{ {
_translator.ThrowError(luaState, "Trying to index an invalid object reference"); _translator.ThrowError(luaState, "Trying to index an invalid object reference");
luaState.PushNil(); //luaState.PushNil();
luaState.PushBoolean(false); //luaState.PushBoolean(false);
return 2; return 2;
} }
...@@ -845,7 +851,7 @@ namespace NLua ...@@ -845,7 +851,7 @@ namespace NLua
{ {
// If we reach this point we found a static method, but can't use it in this context because the user passed in an instance // If we reach this point we found a static method, but can't use it in this context because the user passed in an instance
_translator.ThrowError(luaState, "Can't pass instance to static method " + methodName); _translator.ThrowError(luaState, "Can't pass instance to static method " + methodName);
luaState.PushNil(); //luaState.PushNil();
} }
} }
else else
...@@ -857,7 +863,8 @@ namespace NLua ...@@ -857,7 +863,8 @@ namespace NLua
// is not sufficient. valid data members may return nil and therefore there must be some // is not sufficient. valid data members may return nil and therefore there must be some
// way to know the member just doesn't exist. // way to know the member just doesn't exist.
_translator.ThrowError(luaState, "Unknown member name " + methodName); _translator.ThrowError(luaState, "Unknown member name " + methodName);
luaState.PushNil(); //luaState.PushNil();
return 1;
} }
// Push false because we are NOT returning a function (see luaIndexFunction) // Push false because we are NOT returning a function (see luaIndexFunction)
...@@ -1128,7 +1135,7 @@ namespace NLua ...@@ -1128,7 +1135,7 @@ namespace NLua
if (klass == null) if (klass == null)
{ {
_translator.ThrowError(luaState, "Trying to index an invalid type reference"); _translator.ThrowError(luaState, "Trying to index an invalid type reference");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -1170,7 +1177,7 @@ namespace NLua ...@@ -1170,7 +1177,7 @@ namespace NLua
if (target == null) if (target == null)
{ {
_translator.ThrowError(luaState, "trying to index an invalid type reference"); _translator.ThrowError(luaState, "trying to index an invalid type reference");
return 0; return 1;
} }
return SetMember(luaState, target, null, BindingFlags.Static); return SetMember(luaState, target, null, BindingFlags.Static);
...@@ -1187,7 +1194,13 @@ namespace NLua ...@@ -1187,7 +1194,13 @@ namespace NLua
var luaState = LuaState.FromIntPtr(state); var luaState = LuaState.FromIntPtr(state);
var translator = ObjectTranslatorPool.Instance.Find(luaState); var translator = ObjectTranslatorPool.Instance.Find(luaState);
var instance = translator.MetaFunctionsInstance; var instance = translator.MetaFunctionsInstance;
return instance.CallDelegateInternal(luaState); int result = instance.CallDelegateInternal(luaState);
var exception = translator.GetObject(luaState, -1) as LuaScriptException;
if (exception != null)
return luaState.Error();
return result;
} }
/* /*
...@@ -1201,7 +1214,7 @@ namespace NLua ...@@ -1201,7 +1214,7 @@ namespace NLua
var luaState = LuaState.FromIntPtr(state); var luaState = LuaState.FromIntPtr(state);
var translator = ObjectTranslatorPool.Instance.Find(luaState); var translator = ObjectTranslatorPool.Instance.Find(luaState);
translator.ThrowError(luaState, "Trying to invoke invalid method or an access an invalid index"); translator.ThrowError(luaState, "Trying to invoke invalid method or an access an invalid index");
luaState.PushNil(); luaState.Error();
return 1; return 1;
} }
...@@ -1236,7 +1249,7 @@ namespace NLua ...@@ -1236,7 +1249,7 @@ namespace NLua
} }
_translator.ThrowError(luaState, "Cannot invoke delegate (invalid arguments for " + methodDelegate.Name + ")"); _translator.ThrowError(luaState, "Cannot invoke delegate (invalid arguments for " + methodDelegate.Name + ")");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -1347,7 +1360,7 @@ namespace NLua ...@@ -1347,7 +1360,7 @@ namespace NLua
if (target == null) if (target == null)
{ {
translator.ThrowError(luaState, "Cannot call " + operation + " on a nil object"); translator.ThrowError(luaState, "Cannot call " + operation + " on a nil object");
luaState.PushNil(); // luaState.PushNil();
return 1; return 1;
} }
......
...@@ -220,7 +220,7 @@ namespace NLua.Method ...@@ -220,7 +220,7 @@ namespace NLua.Method
{ {
_translator.ThrowError(luaState, _translator.ThrowError(luaState,
string.Format("instance method '{0}' requires a non null target object", _methodName)); string.Format("instance method '{0}' requires a non null target object", _methodName));
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -251,7 +251,7 @@ namespace NLua.Method ...@@ -251,7 +251,7 @@ namespace NLua.Method
? "Invalid arguments to method call" ? "Invalid arguments to method call"
: ("Invalid arguments to method: " + candidateName); : ("Invalid arguments to method: " + candidateName);
_translator.ThrowError(luaState, msg); _translator.ThrowError(luaState, msg);
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
...@@ -317,7 +317,7 @@ namespace NLua.Method ...@@ -317,7 +317,7 @@ namespace NLua.Method
if (!_translator.MatchParameters(luaState, methodToCall, _lastCalledMethod, 0)) if (!_translator.MatchParameters(luaState, methodToCall, _lastCalledMethod, 0))
{ {
_translator.ThrowError(luaState, "Invalid arguments to method call"); _translator.ThrowError(luaState, "Invalid arguments to method call");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
} }
...@@ -327,7 +327,7 @@ namespace NLua.Method ...@@ -327,7 +327,7 @@ namespace NLua.Method
{ {
_translator.ThrowError(luaState, _translator.ThrowError(luaState,
"Unable to invoke method on generic class as the current method is an open generic method"); "Unable to invoke method on generic class as the current method is an open generic method");
luaState.PushNil(); //luaState.PushNil();
return 1; return 1;
} }
......
...@@ -239,7 +239,7 @@ namespace NLua ...@@ -239,7 +239,7 @@ namespace NLua
} }
Push(luaState, e); Push(luaState, e);
luaState.Error(); //luaState.Error();
} }
/* /*
......
...@@ -2711,6 +2711,77 @@ namespace NLuaTest ...@@ -2711,6 +2711,77 @@ namespace NLuaTest
Assert.AreNotEqual(15, result, "#1"); Assert.AreNotEqual(15, result, "#1");
} }
[Test]
public void ThrowMultipleExceptions()
{
using (Lua lua = new Lua())
{
lua.DoString("luanet.load_assembly('mscorlib')");
lua.DoString("luanet.load_assembly('NLuaTest', 'NLuaTest.TestTypes')");
lua.DoString("TestClass = luanet.import_type('NLuaTest.TestTypes.TestClass')");
lua.DoString("test = TestClass()");
lua.DoString("err,errMsg = pcall(test.exceptionMethod,test)");
bool err = (bool)lua["err"];
var errMsg = (Exception)lua["errMsg"];
Assert.AreEqual(false, err);
Assert.AreNotEqual(null, errMsg.InnerException);
Assert.AreEqual("exception test", errMsg.InnerException.Message);
lua.DoString("err2,errMsg2 = pcall(test.exceptionMethod,test)");
err = (bool)lua["err2"];
errMsg = (Exception)lua["errMsg2"];
Assert.AreEqual(false, err);
Assert.AreNotEqual(null, errMsg.InnerException);
Assert.AreEqual("exception test", errMsg.InnerException.Message);
}
}
/*
* Tests capturing multiple exceptions in LuaFunction call
*/
[Test]
public void ThrowMultipleExceptionsInScript()
{
string script1 =
"function run()\n" +
" function callMethod() " +
" test:exceptionMethod() " +
" test:exceptionMethod() " +
" end" +
" err1, errMsg1 = pcall(callMethod);\n" +
// " err2, errMsg2 = pcall(callMethod);\n" +
"end ";
//string script2 = " err, errMsg = pcall(test.exceptionMethod,test);\n";
TestClass test = new TestClass();
using (Lua lua = new Lua())
{
lua["test"] = test;
//lua.DoString(script2);
//bool err = (bool)lua["err"];
//var errMsg = (Exception)lua["errMsg"];
//Assert.AreEqual(false, err);
//Assert.AreNotEqual(null, errMsg.InnerException);
//Assert.AreEqual("exception test", errMsg.InnerException.Message);
lua.DoString(script1);
(lua["run"] as LuaFunction).Call();
(lua["run"] as LuaFunction).Call();
bool err = (bool)lua["err1"];
var errMsg = (Exception)lua["errMsg1"];
Assert.AreEqual(false, err);
Assert.AreNotEqual(null, errMsg.InnerException);
Assert.AreEqual("exception test", errMsg.InnerException.Message);
}
}
static Lua m_lua; static Lua m_lua;
} }
......
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