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>Implement formatting with os.date(), and table argument for os.time().</li>
|
||||||
<li>Refactor APIs related to compiling and loading scripts.</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>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>
|
</ul></td></tr>
|
||||||
</table></td></tr></table>
|
</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 */
|
/** The DebugLib instance loaded into this Globals, or null if debugging is not enabled */
|
||||||
public DebugLib debuglib;
|
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. */
|
/** Interface for module that converts a Prototype into a LuaFunction with an environment. */
|
||||||
public interface Loader {
|
public interface Loader {
|
||||||
/** Convert the prototype into a LuaFunction with the supplied environment. */
|
/** 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.
|
* @param msg the message to use in error hook processing.
|
||||||
* */
|
* */
|
||||||
String errorHook(String msg) {
|
String errorHook(String msg) {
|
||||||
if (globals == null || globals.errorfunc == null)
|
if (globals == null ) return msg;
|
||||||
return msg;
|
final LuaThread running = globals.running;
|
||||||
LuaValue errfunc = globals.errorfunc;
|
if (running == null) return msg;
|
||||||
globals.errorfunc = null;
|
final LuaValue errfunc = running.errorfunc;
|
||||||
|
if (errfunc == null) return msg;
|
||||||
|
running.errorfunc = null;
|
||||||
try {
|
try {
|
||||||
return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
|
return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
|
||||||
} catch ( Throwable t ) {
|
} catch ( Throwable t ) {
|
||||||
return "error in error handling";
|
return "error in error handling";
|
||||||
} finally {
|
} finally {
|
||||||
globals.errorfunc = errfunc;
|
running.errorfunc = errfunc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,8 +538,6 @@ public class LuaClosure extends LuaFunction {
|
|||||||
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
||||||
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
|
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
|
||||||
le.traceback = errorHook(le.getMessage());
|
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) {
|
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)
|
for (int i = 0; i < n; ++i)
|
||||||
if (openups[i] == null)
|
if (openups[i] == null)
|
||||||
return openups[i] = new UpValue(stack, idx);
|
return openups[i] = new UpValue(stack, idx);
|
||||||
this.error("No space for upvalue");
|
error("No space for upvalue");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,8 +93,12 @@ public class LuaThread extends LuaValue {
|
|||||||
|
|
||||||
public final Globals globals;
|
public final Globals globals;
|
||||||
|
|
||||||
// Hook function control state used by debug lib.
|
/** Hook function control state used by debug lib. */
|
||||||
public LuaValue hookfunc;
|
public LuaValue hookfunc;
|
||||||
|
|
||||||
|
/** Error message handler for this thread, if any. */
|
||||||
|
public LuaValue errorfunc;
|
||||||
|
|
||||||
public boolean hookline;
|
public boolean hookline;
|
||||||
public boolean hookcall;
|
public boolean hookcall;
|
||||||
public boolean hookrtrn;
|
public boolean hookrtrn;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.luaj.vm2.Lua;
|
|||||||
import org.luaj.vm2.LuaError;
|
import org.luaj.vm2.LuaError;
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
|
import org.luaj.vm2.LuaThread;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Varargs;
|
import org.luaj.vm2.Varargs;
|
||||||
|
|
||||||
@@ -213,7 +214,13 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
if (globals != null && globals.debuglib != null)
|
if (globals != null && globals.debuglib != null)
|
||||||
globals.debuglib.onCall(this);
|
globals.debuglib.onCall(this);
|
||||||
try {
|
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 {
|
} finally {
|
||||||
if (globals != null && globals.debuglib != null)
|
if (globals != null && globals.debuglib != null)
|
||||||
globals.debuglib.onReturn();
|
globals.debuglib.onReturn();
|
||||||
@@ -353,13 +360,26 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
// "xpcall", // (f, err) -> result1, ...
|
// "xpcall", // (f, err) -> result1, ...
|
||||||
final class xpcall extends VarArgFunction {
|
final class xpcall extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
if (globals != null && globals.debuglib != null)
|
final LuaThread t = globals.running;
|
||||||
globals.debuglib.onCall(this);
|
final LuaValue preverror = t.errorfunc;
|
||||||
|
t.errorfunc = args.checkvalue(2);
|
||||||
try {
|
try {
|
||||||
return pcall(args.arg1(),args.subargs(3),args.checkvalue(2));
|
|
||||||
} finally {
|
|
||||||
if (globals != null && globals.debuglib != null)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,24 +417,6 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
* Load from a named file, returning the chunk or nil,error of can't load
|
||||||
* @param env
|
* @param env
|
||||||
|
|||||||
Reference in New Issue
Block a user