LuaJ 3 Final. I'm not sure this is a good idea, but nothing seems to break (immediately).

This commit is contained in:
Florian Nücke 2014-07-07 04:37:19 +02:00
parent e8384b67e0
commit caacec21bd
3 changed files with 118 additions and 36 deletions

View File

@ -231,7 +231,7 @@ public class Globals extends LuaTable {
if (undumper == null) if (undumper == null)
error("No undumper."); error("No undumper.");
if (!is.markSupported()) if (!is.markSupported())
is = new MarkStream(is); is = new BufferedStream(is);
is.mark(4); is.mark(4);
final Prototype p = undumper.undump(is, chunkname); final Prototype p = undumper.undump(is, chunkname);
if (p != null) if (p != null)
@ -277,7 +277,8 @@ public class Globals extends LuaTable {
/** Reader implementation to read chars from a String in JME or JSE. */ /** Reader implementation to read chars from a String in JME or JSE. */
static class StrReader extends Reader { static class StrReader extends Reader {
final String s; final String s;
int i = 0, n; int i = 0;
final int n;
StrReader(String s) { StrReader(String s) {
this.s = s; this.s = s;
n = s.length(); n = s.length();
@ -285,6 +286,9 @@ public class Globals extends LuaTable {
public void close() throws IOException { public void close() throws IOException {
i = n; i = n;
} }
public int read() throws IOException {
return i < n ? s.charAt(i++) : -1;
}
public int read(char[] cbuf, int off, int len) throws IOException { public int read(char[] cbuf, int off, int len) throws IOException {
int j = 0; int j = 0;
for (; j < len && i < n; ++j, ++i) for (; j < len && i < n; ++j, ++i)
@ -293,54 +297,115 @@ public class Globals extends LuaTable {
} }
} }
/** Simple converter from Reader to InputStream using UTF8 encoding that will work /* Abstract base class to provide basic buffered input storage and delivery.
* on both JME and JSE. * This class may be moved to its own package in the future.
*/ */
static class UTF8Stream extends InputStream { abstract static class AbstractBufferedStream extends InputStream {
final char[] c = new char[32]; protected byte[] b;
final byte[] b = new byte[96]; protected int i = 0, j = 0;
int i = 0, j = 0; protected AbstractBufferedStream(int buflen) {
final Reader r; this.b = new byte[buflen];
UTF8Stream(Reader r) {
this.r = r;
} }
abstract protected int avail() throws IOException;
public int read() throws IOException { public int read() throws IOException {
if (i < j) int a = avail();
return c[i++]; return (a <= 0 ? -1 : 0xff & b[i++]);
int n = r.read(c); }
if (n < 0) public int read(byte[] b) throws IOException {
return -1; return read(b, 0, b.length);
j = LuaString.encodeToUtf8(c, n, b, i = 0); }
return b[i++]; public int read(byte[] b, int i0, int n) throws IOException {
int a = avail();
if (a <= 0) return -1;
final int n_read = Math.min(a, n);
System.arraycopy(this.b, i, b, i0, n_read);
i += n_read;
return n_read;
}
public long skip(long n) throws IOException {
final long k = Math.min(n, j - i);
i += k;
return k;
}
public int available() throws IOException {
return j - i;
} }
} }
/** Simple InputStream that supports mark. /** Simple converter from Reader to InputStream using UTF8 encoding that will work
* Used to examine an InputStream for a 4-byte binary lua signature, * on both JME and JSE.
* and fall back to text input when the signature is not found. * This class may be moved to its own package in the future.
*/ */
static class MarkStream extends InputStream { static class UTF8Stream extends AbstractBufferedStream {
private int[] b; private final char[] c = new char[32];
private int i = 0, j = 0; private final Reader r;
UTF8Stream(Reader r) {
super(96);
this.r = r;
}
protected int avail() throws IOException {
if (i < j) return j - i;
int n = r.read(c);
if (n < 0)
return -1;
if (n == 0) {
int u = r.read();
if (u < 0)
return -1;
c[0] = (char) u;
n = 1;
}
j = LuaString.encodeToUtf8(c, n, b, i = 0);
return j;
}
public void close() throws IOException {
r.close();
}
}
/** Simple buffered InputStream that supports mark.
* Used to examine an InputStream for a 4-byte binary lua signature,
* and fall back to text input when the signature is not found,
* as well as speed up normal compilation and reading of lua scripts.
* This class may be moved to its own package in the future.
*/
static class BufferedStream extends AbstractBufferedStream {
private final InputStream s; private final InputStream s;
MarkStream(InputStream s) { public BufferedStream(InputStream s) {
this(128, s);
}
BufferedStream(int buflen, InputStream s) {
super(buflen);
this.s = s; this.s = s;
} }
public int read() throws IOException { protected int avail() throws IOException {
if (i < j) if (i < j) return j - i;
return b[i++]; if (j >= b.length) i = j = 0;
final int c = s.read(); // leave previous bytes in place to implement mark()/reset().
if (c < 0) int n = s.read(b, j, b.length - j);
if (n < 0)
return -1; return -1;
if (j < b.length) { if (n == 0) {
b[j++] = c; int u = s.read();
i = j; if (u < 0)
return -1;
b[j] = (byte) u;
n = 1;
} }
return c; j += n;
return n;
}
public void close() throws IOException {
s.close();
} }
public synchronized void mark(int n) { public synchronized void mark(int n) {
b = new int[n]; if (i > 0 || n > b.length) {
i = j = 0; byte[] dest = n > b.length ? new byte[n] : b;
System.arraycopy(b, i, dest, 0, j - i);
j -= i;
i = 0;
b = dest;
}
} }
public boolean markSupported() { public boolean markSupported() {
return true; return true;
@ -349,5 +414,4 @@ public class Globals extends LuaTable {
i = 0; i = 0;
} }
} }
} }

View File

@ -195,12 +195,12 @@ public class LuaClosure extends LuaFunction {
// process instructions // process instructions
try { try {
while ( true ) { for (; true; ++pc) {
if (globals != null && globals.debuglib != null) if (globals != null && globals.debuglib != null)
globals.debuglib.onInstruction( pc, v, top ); globals.debuglib.onInstruction( pc, v, top );
// pull out instruction // pull out instruction
i = code[pc++]; i = code[pc];
a = ((i>>6) & 0xff); a = ((i>>6) & 0xff);
// process the op code // process the op code
@ -217,7 +217,7 @@ public class LuaClosure extends LuaFunction {
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */ case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE; stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
if ((i&(0x1ff<<14)) != 0) if ((i&(0x1ff<<14)) != 0)
pc++; /* skip next instruction (if C) */ ++pc; /* skip next instruction (if C) */
continue; continue;
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */ case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */
@ -444,7 +444,7 @@ public class LuaClosure extends LuaFunction {
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */ case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
{ {
if ( (c=(i>>14)&0x1ff) == 0 ) if ( (c=(i>>14)&0x1ff) == 0 )
c = code[pc++]; c = code[++pc];
int offset = (c-1) * Lua.LFIELDS_PER_FLUSH; int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
o = stack[a]; o = stack[a];
if ( (b=i>>>23) == 0 ) { if ( (b=i>>>23) == 0 ) {

View File

@ -99,6 +99,16 @@ public class CoerceJavaToLua {
return LuaString.valueOf( javaValue.toString() ); return LuaString.valueOf( javaValue.toString() );
} }
} ; } ;
Coercion bytesCoercion = new Coercion() {
public LuaValue coerce( Object javaValue ) {
return LuaValue.valueOf((byte[]) javaValue);
}
} ;
Coercion classCoercion = new Coercion() {
public LuaValue coerce( Object javaValue ) {
return JavaClass.forClass((Class) javaValue);
}
} ;
COERCIONS.put( Boolean.class, boolCoercion ); COERCIONS.put( Boolean.class, boolCoercion );
COERCIONS.put( Byte.class, intCoercion ); COERCIONS.put( Byte.class, intCoercion );
COERCIONS.put( Character.class, charCoercion ); COERCIONS.put( Character.class, charCoercion );
@ -108,6 +118,8 @@ public class CoerceJavaToLua {
COERCIONS.put( Float.class, doubleCoercion ); COERCIONS.put( Float.class, doubleCoercion );
COERCIONS.put( Double.class, doubleCoercion ); COERCIONS.put( Double.class, doubleCoercion );
COERCIONS.put( String.class, stringCoercion ); COERCIONS.put( String.class, stringCoercion );
COERCIONS.put( byte[].class, bytesCoercion );
COERCIONS.put( Class.class, classCoercion );
} }
/** /**
@ -117,6 +129,7 @@ public class CoerceJavaToLua {
* will become {@link LuaInteger}; * will become {@link LuaInteger};
* {@code long}, {@code float}, and {@code double} will become {@link LuaDouble}; * {@code long}, {@code float}, and {@code double} will become {@link LuaDouble};
* {@code String} and {@code byte[]} will become {@link LuaString}; * {@code String} and {@code byte[]} will become {@link LuaString};
* types inheriting from {@link LuaValue} will be returned without coercion;
* other types will become {@link LuaUserdata}. * other types will become {@link LuaUserdata}.
* @param o Java object needing conversion * @param o Java object needing conversion
* @return {@link LuaValue} corresponding to the supplied Java value. * @return {@link LuaValue} corresponding to the supplied Java value.
@ -129,12 +142,11 @@ public class CoerceJavaToLua {
public static LuaValue coerce(Object o) { public static LuaValue coerce(Object o) {
if ( o == null ) if ( o == null )
return LuaValue.NIL; return LuaValue.NIL;
if (o instanceof Class)
return JavaClass.forClass((Class) o);
Class clazz = o.getClass(); Class clazz = o.getClass();
Coercion c = (Coercion) COERCIONS.get( clazz ); Coercion c = (Coercion) COERCIONS.get( clazz );
if ( c == null ) { if ( c == null ) {
c = clazz.isArray()? arrayCoercion: c = clazz.isArray()? arrayCoercion:
o instanceof LuaValue ? luaCoercion:
instanceCoercion; instanceCoercion;
COERCIONS.put( clazz, c ); COERCIONS.put( clazz, c );
} }
@ -153,4 +165,10 @@ public class CoerceJavaToLua {
return new JavaArray(javaValue); return new JavaArray(javaValue);
} }
}; };
static final Coercion luaCoercion = new Coercion() {
public LuaValue coerce( Object javaValue ) {
return (LuaValue) javaValue;
}
} ;
} }