Make error message handler in xpcall per-thread instead of per-globals.
This commit is contained in:
@@ -910,6 +910,7 @@ Files are no longer hosted at LuaForge.
|
||||
<li>Implement formatting with os.date(), and table argument for os.time().</li>
|
||||
<li>Refactor APIs related to compiling and loading scripts.</li>
|
||||
<li>Let errors thrown in debug hooks bubble up to the running coroutine.</li>
|
||||
<li>Make error function in xpcall per-thread instead of per-globals.</li>
|
||||
|
||||
</ul></td></tr>
|
||||
</table></td></tr></table>
|
||||
|
||||
@@ -136,9 +136,6 @@ public class Globals extends LuaTable {
|
||||
/** The DebugLib instance loaded into this Globals, or null if debugging is not enabled */
|
||||
public DebugLib debuglib;
|
||||
|
||||
/** The current error handler for this Globals */
|
||||
public LuaValue errorfunc;
|
||||
|
||||
/** Interface for module that converts a Prototype into a LuaFunction with an environment. */
|
||||
public interface Loader {
|
||||
/** Convert the prototype into a LuaFunction with the supplied environment. */
|
||||
|
||||
@@ -519,16 +519,18 @@ public class LuaClosure extends LuaFunction {
|
||||
* @param msg the message to use in error hook processing.
|
||||
* */
|
||||
String errorHook(String msg) {
|
||||
if (globals == null || globals.errorfunc == null)
|
||||
return msg;
|
||||
LuaValue errfunc = globals.errorfunc;
|
||||
globals.errorfunc = null;
|
||||
if (globals == null ) return msg;
|
||||
final LuaThread running = globals.running;
|
||||
if (running == null) return msg;
|
||||
final LuaValue errfunc = running.errorfunc;
|
||||
if (errfunc == null) return msg;
|
||||
running.errorfunc = null;
|
||||
try {
|
||||
return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
|
||||
} catch ( Throwable t ) {
|
||||
return "error in error handling";
|
||||
} finally {
|
||||
globals.errorfunc = errfunc;
|
||||
running.errorfunc = errfunc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,8 +538,6 @@ public class LuaClosure extends LuaFunction {
|
||||
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
||||
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
|
||||
le.traceback = errorHook(le.getMessage());
|
||||
if (globals != null && globals.debuglib != null)
|
||||
le.traceback = le.traceback + "\n" + globals.debuglib.traceback(le.level);
|
||||
}
|
||||
|
||||
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
|
||||
@@ -548,7 +548,7 @@ public class LuaClosure extends LuaFunction {
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (openups[i] == null)
|
||||
return openups[i] = new UpValue(stack, idx);
|
||||
this.error("No space for upvalue");
|
||||
error("No space for upvalue");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,8 +93,12 @@ public class LuaThread extends LuaValue {
|
||||
|
||||
public final Globals globals;
|
||||
|
||||
// Hook function control state used by debug lib.
|
||||
/** Hook function control state used by debug lib. */
|
||||
public LuaValue hookfunc;
|
||||
|
||||
/** Error message handler for this thread, if any. */
|
||||
public LuaValue errorfunc;
|
||||
|
||||
public boolean hookline;
|
||||
public boolean hookcall;
|
||||
public boolean hookrtrn;
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaThread;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
|
||||
@@ -213,7 +214,13 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
if (globals != null && globals.debuglib != null)
|
||||
globals.debuglib.onCall(this);
|
||||
try {
|
||||
return pcall(func,args.subargs(2),null);
|
||||
return varargsOf(TRUE, func.invoke(args.subargs(2)));
|
||||
} catch ( LuaError le ) {
|
||||
final String m = le.getMessage();
|
||||
return varargsOf(FALSE, m!=null? valueOf(m): NIL);
|
||||
} catch ( Exception e ) {
|
||||
final String m = e.getMessage();
|
||||
return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
|
||||
} finally {
|
||||
if (globals != null && globals.debuglib != null)
|
||||
globals.debuglib.onReturn();
|
||||
@@ -353,13 +360,26 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
// "xpcall", // (f, err) -> result1, ...
|
||||
final class xpcall extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
if (globals != null && globals.debuglib != null)
|
||||
globals.debuglib.onCall(this);
|
||||
final LuaThread t = globals.running;
|
||||
final LuaValue preverror = t.errorfunc;
|
||||
t.errorfunc = args.checkvalue(2);
|
||||
try {
|
||||
return pcall(args.arg1(),args.subargs(3),args.checkvalue(2));
|
||||
} finally {
|
||||
if (globals != null && globals.debuglib != null)
|
||||
globals.debuglib.onReturn();
|
||||
globals.debuglib.onCall(this);
|
||||
try {
|
||||
return varargsOf(TRUE, args.arg1().invoke(args.subargs(3)));
|
||||
} catch ( LuaError le ) {
|
||||
final String m = le.getMessage();
|
||||
return varargsOf(FALSE, m!=null? valueOf(m): NIL);
|
||||
} catch ( Exception e ) {
|
||||
final String m = e.getMessage();
|
||||
return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
|
||||
} finally {
|
||||
if (globals != null && globals.debuglib != null)
|
||||
globals.debuglib.onReturn();
|
||||
}
|
||||
} finally {
|
||||
t.errorfunc = preverror;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,24 +416,6 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
return args.checktable(1).inext(args.arg(2));
|
||||
}
|
||||
}
|
||||
|
||||
public Varargs pcall(LuaValue func, Varargs args, LuaValue errorfunc) {
|
||||
try {
|
||||
LuaValue olderr = globals.errorfunc;
|
||||
globals.errorfunc = errorfunc;
|
||||
try {
|
||||
return varargsOf(LuaValue.TRUE, func.invoke(args));
|
||||
} finally {
|
||||
globals.errorfunc = olderr;
|
||||
}
|
||||
} catch ( LuaError le ) {
|
||||
String m = le.getMessage();
|
||||
return varargsOf(FALSE, m!=null? valueOf(m): NIL);
|
||||
} catch ( Exception e ) {
|
||||
String m = e.getMessage();
|
||||
return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from a named file, returning the chunk or nil,error of can't load
|
||||
|
||||
Reference in New Issue
Block a user