Improve compatibility with lua 5.2.

This commit is contained in:
James Roseborough
2012-09-21 14:32:07 +00:00
parent be4a320bf9
commit 0c93edfd56
6 changed files with 125 additions and 111 deletions

View File

@@ -340,5 +340,22 @@ public class Lua {
/* number of list items to accumulate before a SETLIST instruction */
public static final int LFIELDS_PER_FLUSH = 50;
private static final int MAXSRC = 80;
public static String chunkid( String source ) {
if ( source.startsWith("=") )
return source.substring(1);
String end = "";
if ( source.startsWith("@") ) {
source = source.substring(1);
} else {
source = "[string \""+source;
end = "\"]";
}
int n = source.length() + end.length();
if ( n > MAXSRC )
source = source.substring(0,MAXSRC-end.length()-3) + "...";
return source + end;
}
}

View File

@@ -71,11 +71,18 @@ public class LuaFunction extends LuaValue {
}
public String tojstring() {
String s = getClass().getName();
return "function: " + s.substring(Math.max(s.lastIndexOf('.'),s.lastIndexOf('$'))+1);
return "function: " + classnamestub();
}
public LuaString strvalue() {
return valueOf(tojstring());
}
/** Return the last part of the class name, to be used as a function name in tojstring and elsewhere.
* @return String naming the last part of the class name after the last dot (.) or dollar sign ($).
*/
public String classnamestub() {
String s = getClass().getName();
return s.substring(Math.max(s.lastIndexOf('.'),s.lastIndexOf('$'))+1);
}
}

View File

@@ -61,7 +61,6 @@ public class LexState {
}
private static final int EOZ = (-1);
private static final int MAXSRC = 80;
private static final int MAX_INT = Integer.MAX_VALUE-2;
private static final int UCHAR_MAX = 255; // TODO, convert to unicode CHAR_MAX?
private static final int LUAI_MAXCCALLS = 200;
@@ -260,29 +259,13 @@ public class LexState {
}
void lexerror( String msg, int token ) {
String cid = chunkid( source.tojstring() ); // TODO: get source name from source
String cid = Lua.chunkid( source.tojstring() );
L.pushfstring( cid+":"+linenumber+": "+msg );
if ( token != 0 )
L.pushfstring( "syntax error: "+msg+" near "+txtToken(token) );
throw new LuaError(cid+":"+linenumber+": "+msg);
}
String chunkid( String source ) {
if ( source.startsWith("=") )
return source.substring(1);
String end = "";
if ( source.startsWith("@") ) {
source = source.substring(1);
} else {
source = "[string \""+source;
end = "\"]";
}
int n = source.length() + end.length();
if ( n > MAXSRC )
source = source.substring(0,MAXSRC-end.length()-3) + "...";
return source + end;
}
void syntaxerror( String msg ) {
lexerror( msg, t.token );
}

View File

@@ -37,6 +37,7 @@ import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.DebugLib.CallFrame;
/**
* Subclass of {@link LibFunction} which implements the lua standard {@code debug}
@@ -207,13 +208,13 @@ public class DebugLib extends OneArgFunction {
}
if (what.indexOf('n') >= 0) {
if (frame != null) {
LuaString[] kind = getfuncname(frame);
info.set(NAME, kind!=null? kind[0]: QMARK);
info.set(NAMEWHAT, kind!=null? kind[1]: EMPTYSTRING);
DebugInfo ar = frame.getinfo("n");
info.set(NAME, LuaValue.valueOf(ar.name));
info.set(NAMEWHAT, LuaValue.valueOf(ar.namewhat));
}
}
if (what.indexOf('t') >= 0) {
info.set(ISTAILCALL, frame != null && frame.istailcall()? ONE: ZERO);
info.set(ISTAILCALL, ZERO);
}
if (what.indexOf('L') >= 0) {
LuaTable lines = new LuaTable();
@@ -505,6 +506,8 @@ public class DebugLib extends OneArgFunction {
for (int i = frame.length; i < n; ++i)
f[i] = new CallFrame();
frame = f;
for (int i = 1; i < n; ++i)
f[i].previous = f[i-1];
}
return frame[calls++];
}
@@ -534,24 +537,30 @@ public class DebugLib extends OneArgFunction {
String traceback(int level) {
StringBuffer sb = new StringBuffer();
sb.append( "stack traceback:" );
for (DebugLib.CallFrame c, prev = null; (c = getCallFrame(level++)) != null; prev = c ) {
DebugInfo ar = c.getinfo("Slnt", prev);
prev = c;
for (DebugLib.CallFrame c; (c = getCallFrame(level++)) != null; ) {
sb.append("\n\t");
sb.append( c.shortsource() );
sb.append( ':' );
if (c.currentline() > 0)
sb.append( c.currentline()+":" );
sb.append( " in " );
sb.append( c.tracename() );
if (c.istailcall())
sb.append("\n\t(...tail calls...)");
DebugInfo ar = c.getinfo("n");
if (c.linedefined() == 0)
sb.append("main chunk");
else if ( ar.name != null ) {
sb.append( "function '" );
sb.append( ar.name );
sb.append( '\'' );
} else {
sb.append( "function <"+c.shortsource()+":"+c.linedefined()+">" );
}
}
sb.append("\n\t[Java]: in ?");
return sb.toString();
}
DebugLib.CallFrame getCallFrame(int level) {
if (level < 1 || level >= calls)
if (level < 1 || level > calls)
return null;
return frame[calls-level];
}
@@ -570,12 +579,11 @@ public class DebugLib extends OneArgFunction {
int top;
Varargs v;
LuaValue[] stack;
boolean tail;
CallFrame previous;
void set(LuaClosure function, Varargs varargs, LuaValue[] stack) {
this.f = function;
this.v = varargs;
this.stack = stack;
this.tail = false;
}
public String shortsource() {
return f.isclosure()? DebugLib.shortsource(f.checkclosure().p): "[Java]";
@@ -592,8 +600,6 @@ public class DebugLib extends OneArgFunction {
this.pc = pc;
this.v = v;
this.top = top;
if (f.checkclosure().p.code[pc] == Lua.OP_TAILCALL)
this.tail = true;
if (TRACE)
Print.printState(f.checkclosure(), pc, stack, top, v);
}
@@ -620,20 +626,7 @@ public class DebugLib extends OneArgFunction {
}
String sourceline() {
if ( !f.isclosure() ) return f.tojstring();
String s = f.checkclosure().p.source.tojstring();
int line = currentline();
return (s.startsWith("@")||s.startsWith("=")? s.substring(1): s) + ":" + line;
}
String tracename() {
LuaString[] kind = getfuncname(this);
if (kind[0] == null)
return "function "+kind[1].tojstring();
// if (kind[0] == M)
// return "main chunk";
if (kind[0] == JAVA)
return "function "+kind[1].tojstring();
return "function <"+shortsource()+":"+linedefined()+">";
return DebugLib.shortsource(f.checkclosure().p) + ":" + currentline();
}
private int linedefined() {
return f.isclosure()? f.checkclosure().p.linedefined: -1;
@@ -642,14 +635,7 @@ public class DebugLib extends OneArgFunction {
if ( !f.isclosure() ) return null;
return f.checkclosure().p.getlocalname(index, pc);
}
String tojstring() {
return tracename()+" "+sourceline();
}
boolean istailcall() {
return tail;
}
DebugInfo getinfo(String what, CallFrame previous) {
DebugInfo getinfo(String what) {
DebugInfo ar = new DebugInfo();
for (int i = 0, n = what.length(); i < n; ++i) {
switch (what.charAt(i)) {
@@ -660,13 +646,14 @@ public class DebugLib extends OneArgFunction {
ar.linedefined = p.linedefined;
ar.lastlinedefined = p.lastlinedefined;
ar.what = (ar.linedefined == 0) ? "main" : "Lua";
ar.short_src = DebugLib.shortsource(p);
} else {
ar.source = "=[Java]";
ar.linedefined = -1;
ar.lastlinedefined = -1;
ar.what = "Java";
ar.source = "=[Java]";
ar.linedefined = -1;
ar.lastlinedefined = -1;
ar.what = "Java";
ar.short_src = f.classnamestub();
}
ar.short_src = chunkid(ar.source);
break;
case 'l':
ar.currentline = currentline();
@@ -684,47 +671,33 @@ public class DebugLib extends OneArgFunction {
}
break;
case 't':
ar.istailcall = this.tail;
ar.istailcall = false;
break;
case 'n': {
/* calling function is a known Lua function? */
if (!tail && (previous != null && previous.f.isclosure())) {
LuaString[] kind = getfuncname(previous);
ar.name = String.valueOf(kind[0]);
ar.namewhat = String.valueOf(kind[1]);
}
else
ar.namewhat = null;
if (ar.namewhat == null) {
ar.namewhat = ""; /* not found */
ar.name = null;
}
break;
/* calling function is a known Lua function? */
if (previous != null && previous.f.isclosure()) {
NameWhat nw = getfuncname(previous);
if (nw != null) {
ar.name = nw.name;
ar.namewhat = nw.namewhat;
}
}
else
ar.namewhat = null;
if (ar.namewhat == null) {
ar.namewhat = ""; /* not found */
ar.name = null;
}
break;
}
default:
break;
}
}
return null;
return ar;
}
}
static String chunkid( String source ) {
if ( source.startsWith("=") )
return source.substring(1);
String end = "";
if ( source.startsWith("@") ) {
source = source.substring(1);
} else {
source = "[string \""+source;
end = "\"]";
}
int n = source.length() + end.length();
if ( n > 50 )
source = source.substring(0,50-end.length()-3) + "...";
return source + end;
}
static LuaString findupvalue(LuaClosure c, int up) {
if ( c.upValues != null && up > 0 && up <= c.upValues.length ) {
if ( c.p.upvalues != null && up <= c.p.upvalues.length )
@@ -748,9 +721,19 @@ public class DebugLib extends OneArgFunction {
if (!x) throw new RuntimeException("lua_assert failed");
}
public static LuaString[] getfuncname(DebugLib.CallFrame frame) {
static class NameWhat {
final String name;
final String namewhat;
NameWhat(String name, String namewhat) {
this.name = name;
this.namewhat = namewhat;
}
}
// Return the name info if found, or null if no useful information could be found.
static NameWhat getfuncname(DebugLib.CallFrame frame) {
if (!frame.f.isclosure())
return new LuaString[] { frame.f.strvalue(), JAVA };
return new NameWhat(frame.f.classnamestub(), "Java");
Prototype p = frame.f.checkclosure().p;
int pc = frame.pc;
int i = p.code[pc]; /* calling instruction */
@@ -760,7 +743,7 @@ public class DebugLib extends OneArgFunction {
case Lua.OP_TAILCALL: /* get function name */
return getobjname(p, pc, Lua.GETARG_A(i));
case Lua.OP_TFORCALL: /* for iterator */
return new LuaString[] { FOR_ITERATOR, FOR_ITERATOR};
return new NameWhat("(for iterator)", "(for iterator");
/* all other instructions can call only through metamethods */
case Lua.OP_SELF:
case Lua.OP_GETTABUP:
@@ -782,15 +765,15 @@ public class DebugLib extends OneArgFunction {
default:
return null; /* else no useful name can be found */
}
return new LuaString[] { tm, METAMETHOD };
return new NameWhat( tm.tojstring(), "metamethod" );
}
// return StrValue[] { name, namewhat } if found, null if not
public static LuaString[] getobjname(Prototype p, int lastpc, int reg) {
// return NameWhat if found, null if not
public static NameWhat getobjname(Prototype p, int lastpc, int reg) {
int pc = lastpc; // currentpc(L, ci);
LuaString name = p.getlocalname(reg + 1, pc);
if (name != null) /* is a local? */
return new LuaString[] { name, LOCAL };
return new NameWhat( name.tojstring(), "local" );
/* else try symbolic execution */
pc = findsetreg(p, lastpc, reg);
@@ -812,12 +795,12 @@ public class DebugLib extends OneArgFunction {
? p.getlocalname(t + 1, pc)
: (t < p.upvalues.length ? p.upvalues[t].name : QMARK);
name = kname(p, k);
return new LuaString[] { name, vn != null && vn.eq_b(ENV)? GLOBAL: FIELD };
return new NameWhat( name.tojstring(), vn != null && vn.eq_b(ENV)? "global": "field" );
}
case Lua.OP_GETUPVAL: {
int u = Lua.GETARG_B(i); /* upvalue index */
name = u < p.upvalues.length ? p.upvalues[u].name : QMARK;
return new LuaString[] { name, UPVALUE };
return new NameWhat( name.tojstring(), "upvalue" );
}
case Lua.OP_LOADK:
case Lua.OP_LOADKX: {
@@ -825,14 +808,14 @@ public class DebugLib extends OneArgFunction {
: Lua.GETARG_Ax(p.code[pc + 1]);
if (p.k[b].isstring()) {
name = p.k[b].strvalue();
return new LuaString[] { name, CONSTANT };
return new NameWhat( name.tojstring(), "constant" );
}
break;
}
case Lua.OP_SELF: {
int k = Lua.GETARG_C(i); /* key index */
name = kname(p, k);
return new LuaString[] { name, METHOD };
return new NameWhat( name.tojstring(), "method" );
}
default:
break;