Convert anonymous classes to inner classes (gradle build support).

This commit is contained in:
James Roseborough
2015-03-08 20:22:30 +00:00
parent c0e043403f
commit c5081c5de1
9 changed files with 259 additions and 155 deletions

View File

@@ -966,6 +966,7 @@ Files are no longer hosted at LuaForge.
<tr valign="top"><td>&nbsp;&nbsp;<b>3.0.1</b></td><td><ul> <tr valign="top"><td>&nbsp;&nbsp;<b>3.0.1</b></td><td><ul>
<li>Fix __len metatag processing for tables.</li> <li>Fix __len metatag processing for tables.</li>
<li>Add fallback to __lt when pocessing __le metatag.</li> <li>Add fallback to __lt when pocessing __le metatag.</li>
<li>Convert anonymous classes to inner classes (gradle build support).</li>
</ul></td></tr> </ul></td></tr>
</table></td></tr></table> </table></td></tr></table>

View File

@@ -85,12 +85,7 @@ import org.luaj.vm2.compiler.DumpState;
public class LoadState { public class LoadState {
/** Shared instance of Globals.Undumper to use loading prototypes from binary lua files */ /** Shared instance of Globals.Undumper to use loading prototypes from binary lua files */
public static final Globals.Undumper instance = new Globals.Undumper() { public static final Globals.Undumper instance = new GlobalsUndumper();
public Prototype undump(InputStream stream, String chunkname)
throws IOException {
return LoadState.undump(stream, chunkname);
}
};
/** format corresponding to non-number-patched lua, all numbers are floats or doubles */ /** format corresponding to non-number-patched lua, all numbers are floats or doubles */
public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0; public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0;
@@ -437,4 +432,10 @@ public class LoadState {
this.is = new DataInputStream( stream ); this.is = new DataInputStream( stream );
} }
private static final class GlobalsUndumper implements Globals.Undumper {
public Prototype undump(InputStream stream, String chunkname)
throws IOException {
return LoadState.undump(stream, chunkname);
}
}
} }

View File

@@ -180,6 +180,21 @@ public class luajc {
} }
} }
private static final class LocalClassLoader extends ClassLoader {
private final Hashtable t;
private LocalClassLoader(Hashtable t) {
this.t = t;
}
public Class findClass(String classname) throws ClassNotFoundException {
byte[] bytes = (byte[]) t.get(classname);
if ( bytes != null )
return defineClass(classname, bytes, 0, bytes.length);
return super.findClass(classname);
}
}
class InputFile { class InputFile {
public String luachunkname; public String luachunkname;
public String srcfilename; public String srcfilename;
@@ -230,14 +245,7 @@ public class luajc {
// try to load the files // try to load the files
if ( loadclasses ) { if ( loadclasses ) {
ClassLoader loader = new ClassLoader() { ClassLoader loader = new LocalClassLoader(t);
public Class findClass(String classname) throws ClassNotFoundException {
byte[] bytes = (byte[]) t.get(classname);
if ( bytes != null )
return defineClass(classname, bytes, 0, bytes.length);
return super.findClass(classname);
}
};
for ( Enumeration e = t.keys(); e.hasMoreElements(); ) { for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
String classname = (String) e.nextElement(); String classname = (String) e.nextElement();
try { try {

View File

@@ -62,53 +62,87 @@ import org.luaj.vm2.LuaValue;
* @see LuajavaLib * @see LuajavaLib
*/ */
public class CoerceJavaToLua { public class CoerceJavaToLua {
static interface Coercion { static interface Coercion {
public LuaValue coerce( Object javaValue ); public LuaValue coerce( Object javaValue );
}; };
private static final class BoolCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
Boolean b = (Boolean) javaValue;
return b.booleanValue()? LuaValue.TRUE: LuaValue.FALSE;
}
}
private static final class IntCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
Number n = (Number) javaValue;
return LuaInteger.valueOf( n.intValue() );
}
}
private static final class CharCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
Character c = (Character) javaValue;
return LuaInteger.valueOf( c.charValue() );
}
}
private static final class DoubleCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
Number n = (Number) javaValue;
return LuaDouble.valueOf( n.doubleValue() );
}
}
private static final class StringCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
return LuaString.valueOf( javaValue.toString() );
}
}
private static final class BytesCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
return LuaValue.valueOf((byte[]) javaValue);
}
}
private static final class ClassCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
return JavaClass.forClass((Class) javaValue);
}
}
private static final class InstanceCoercion implements Coercion {
public LuaValue coerce(Object javaValue) {
return new JavaInstance(javaValue);
}
}
private static final class ArrayCoercion implements Coercion {
public LuaValue coerce(Object javaValue) {
// should be userdata?
return new JavaArray(javaValue);
}
}
private static final class LuaCoercion implements Coercion {
public LuaValue coerce( Object javaValue ) {
return (LuaValue) javaValue;
}
}
static final Map COERCIONS = new HashMap(); static final Map COERCIONS = new HashMap();
static { static {
Coercion boolCoercion = new Coercion() { Coercion boolCoercion = new BoolCoercion() ;
public LuaValue coerce( Object javaValue ) { Coercion intCoercion = new IntCoercion() ;
Boolean b = (Boolean) javaValue; Coercion charCoercion = new CharCoercion() ;
return b.booleanValue()? LuaValue.TRUE: LuaValue.FALSE; Coercion doubleCoercion = new DoubleCoercion() ;
} Coercion stringCoercion = new StringCoercion() ;
} ; Coercion bytesCoercion = new BytesCoercion() ;
Coercion intCoercion = new Coercion() { Coercion classCoercion = new ClassCoercion() ;
public LuaValue coerce( Object javaValue ) {
Number n = (Number) javaValue;
return LuaInteger.valueOf( n.intValue() );
}
} ;
Coercion charCoercion = new Coercion() {
public LuaValue coerce( Object javaValue ) {
Character c = (Character) javaValue;
return LuaInteger.valueOf( c.charValue() );
}
} ;
Coercion doubleCoercion = new Coercion() {
public LuaValue coerce( Object javaValue ) {
Number n = (Number) javaValue;
return LuaDouble.valueOf( n.doubleValue() );
}
} ;
Coercion stringCoercion = new Coercion() {
public LuaValue coerce( Object javaValue ) {
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 );
@@ -153,22 +187,9 @@ public class CoerceJavaToLua {
return c.coerce(o); return c.coerce(o);
} }
static final Coercion instanceCoercion = new Coercion() { static final Coercion instanceCoercion = new InstanceCoercion();
public LuaValue coerce(Object javaValue) {
return new JavaInstance(javaValue);
}
};
// should be userdata? static final Coercion arrayCoercion = new ArrayCoercion();
static final Coercion arrayCoercion = new Coercion() {
public LuaValue coerce(Object javaValue) {
return new JavaArray(javaValue);
}
};
static final Coercion luaCoercion = new Coercion() { static final Coercion luaCoercion = new LuaCoercion() ;
public LuaValue coerce( Object javaValue ) {
return (LuaValue) javaValue;
}
} ;
} }

View File

@@ -41,16 +41,18 @@ import org.luaj.vm2.lib.OneArgFunction;
*/ */
class JavaArray extends LuaUserdata { class JavaArray extends LuaUserdata {
private static final class LenFunction extends OneArgFunction {
public LuaValue call(LuaValue u) {
return LuaValue.valueOf(Array.getLength(((LuaUserdata)u).m_instance));
}
}
static final LuaValue LENGTH = valueOf("length"); static final LuaValue LENGTH = valueOf("length");
static final LuaTable array_metatable; static final LuaTable array_metatable;
static { static {
array_metatable = new LuaTable(); array_metatable = new LuaTable();
array_metatable.rawset(LuaValue.LEN, new OneArgFunction() { array_metatable.rawset(LuaValue.LEN, new LenFunction());
public LuaValue call(LuaValue u) {
return LuaValue.valueOf(Array.getLength(((LuaUserdata)u).m_instance));
}
});
} }
JavaArray(Object instance) { JavaArray(Object instance) {

View File

@@ -90,27 +90,43 @@ public class JseProcess {
private Thread copyBytes(final InputStream input, private Thread copyBytes(final InputStream input,
final OutputStream output, final InputStream ownedInput, final OutputStream output, final InputStream ownedInput,
final OutputStream ownedOutput) { final OutputStream ownedOutput) {
Thread t = (new Thread() { Thread t = (new CopyThread(output, ownedOutput, ownedInput, input));
public void run() {
try {
byte[] buf = new byte[1024];
int r;
try {
while ((r = input.read(buf)) >= 0) {
output.write(buf, 0, r);
}
} finally {
if (ownedInput != null)
ownedInput.close();
if (ownedOutput != null)
ownedOutput.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start(); t.start();
return t; return t;
} }
private static final class CopyThread extends Thread {
private final OutputStream output;
private final OutputStream ownedOutput;
private final InputStream ownedInput;
private final InputStream input;
private CopyThread(OutputStream output, OutputStream ownedOutput,
InputStream ownedInput, InputStream input) {
this.output = output;
this.ownedOutput = ownedOutput;
this.ownedInput = ownedInput;
this.input = input;
}
public void run() {
try {
byte[] buf = new byte[1024];
int r;
try {
while ((r = input.read(buf)) >= 0) {
output.write(buf, 0, r);
}
} finally {
if (ownedInput != null)
ownedInput.close();
if (ownedOutput != null)
ownedOutput.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }

View File

@@ -81,7 +81,7 @@ import org.luaj.vm2.lib.VarArgFunction;
* @see <a href="http://www.keplerproject.org/luajava/manual.html#luareference">http://www.keplerproject.org/luajava/manual.html#luareference</a> * @see <a href="http://www.keplerproject.org/luajava/manual.html#luareference">http://www.keplerproject.org/luajava/manual.html#luareference</a>
*/ */
public class LuajavaLib extends VarArgFunction { public class LuajavaLib extends VarArgFunction {
static final int INIT = 0; static final int INIT = 0;
static final int BINDCLASS = 1; static final int BINDCLASS = 1;
static final int NEWINSTANCE = 2; static final int NEWINSTANCE = 2;
@@ -139,32 +139,7 @@ public class LuajavaLib extends VarArgFunction {
ifaces[i] = classForName(args.checkjstring(i+1)); ifaces[i] = classForName(args.checkjstring(i+1));
// create the invocation handler // create the invocation handler
InvocationHandler handler = new InvocationHandler() { InvocationHandler handler = new ProxyInvocationHandler(lobj);
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
LuaValue func = lobj.get(name);
if ( func.isnil() )
return null;
boolean isvarargs = ((method.getModifiers() & METHOD_MODIFIERS_VARARGS) != 0);
int n = args!=null? args.length: 0;
LuaValue[] v;
if ( isvarargs ) {
Object o = args[--n];
int m = Array.getLength( o );
v = new LuaValue[n+m];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
for ( int i=0; i<m; i++ )
v[i+n] = CoerceJavaToLua.coerce(Array.get(o,i));
} else {
v = new LuaValue[n];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
}
LuaValue result = func.invoke(v).arg1();
return CoerceLuaToJava.coerce(result, method.getReturnType());
}
};
// create the proxy object // create the proxy object
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler); Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);
@@ -202,4 +177,37 @@ public class LuajavaLib extends VarArgFunction {
return Class.forName(name, true, ClassLoader.getSystemClassLoader()); return Class.forName(name, true, ClassLoader.getSystemClassLoader());
} }
private static final class ProxyInvocationHandler implements InvocationHandler {
private final LuaValue lobj;
private ProxyInvocationHandler(LuaValue lobj) {
this.lobj = lobj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
LuaValue func = lobj.get(name);
if ( func.isnil() )
return null;
boolean isvarargs = ((method.getModifiers() & METHOD_MODIFIERS_VARARGS) != 0);
int n = args!=null? args.length: 0;
LuaValue[] v;
if ( isvarargs ) {
Object o = args[--n];
int m = Array.getLength( o );
v = new LuaValue[n+m];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
for ( int i=0; i<m; i++ )
v[i+n] = CoerceJavaToLua.coerce(Array.get(o,i));
} else {
v = new LuaValue[n];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
}
LuaValue result = func.invoke(v).arg1();
return CoerceLuaToJava.coerce(result, method.getReturnType());
}
}
} }

View File

@@ -48,15 +48,7 @@ public class BasicBlock {
final boolean[] isbeg = new boolean[n]; final boolean[] isbeg = new boolean[n];
final boolean[] isend = new boolean[n]; final boolean[] isend = new boolean[n];
isbeg[0] = true; isbeg[0] = true;
BranchVisitor bv = new BranchVisitor(isbeg) { BranchVisitor bv = new MarkAndMergeVisitor(isbeg, isend);
public void visitBranch(int pc0, int pc1) {
isend[pc0] = true;
isbeg[pc1] = true;
}
public void visitReturn(int pc) {
isend[pc] = true;
}
};
visitBranches(p, bv); // 1st time to mark branches visitBranches(p, bv); // 1st time to mark branches
visitBranches(p, bv); // 2nd time to catch merges visitBranches(p, bv); // 2nd time to catch merges
@@ -73,25 +65,68 @@ public class BasicBlock {
// count previous, next // count previous, next
final int[] nnext = new int[n]; final int[] nnext = new int[n];
final int[] nprev = new int[n]; final int[] nprev = new int[n];
visitBranches(p, new BranchVisitor(isbeg) { visitBranches(p, new CountPrevNextVistor(isbeg, nnext, nprev));
public void visitBranch(int pc0, int pc1) {
nnext[pc0]++;
nprev[pc1]++;
}
});
// allocate and cross-reference // allocate and cross-reference
visitBranches( p, new BranchVisitor(isbeg) { visitBranches( p, new AllocAndXRefVisitor(isbeg, nnext, nprev, blocks));
public void visitBranch(int pc0, int pc1) {
if ( blocks[pc0].next == null ) blocks[pc0].next = new BasicBlock[nnext[pc0]];
if ( blocks[pc1].prev == null ) blocks[pc1].prev = new BasicBlock[nprev[pc1]];
blocks[pc0].next[--nnext[pc0]] = blocks[pc1];
blocks[pc1].prev[--nprev[pc1]] = blocks[pc0];
}
});
return blocks; return blocks;
} }
private static final class AllocAndXRefVisitor extends BranchVisitor {
private final int[] nnext;
private final int[] nprev;
private final BasicBlock[] blocks;
private AllocAndXRefVisitor(boolean[] isbeg, int[] nnext, int[] nprev,
BasicBlock[] blocks) {
super(isbeg);
this.nnext = nnext;
this.nprev = nprev;
this.blocks = blocks;
}
public void visitBranch(int pc0, int pc1) {
if ( blocks[pc0].next == null ) blocks[pc0].next = new BasicBlock[nnext[pc0]];
if ( blocks[pc1].prev == null ) blocks[pc1].prev = new BasicBlock[nprev[pc1]];
blocks[pc0].next[--nnext[pc0]] = blocks[pc1];
blocks[pc1].prev[--nprev[pc1]] = blocks[pc0];
}
}
private static final class CountPrevNextVistor extends BranchVisitor {
private final int[] nnext;
private final int[] nprev;
private CountPrevNextVistor(boolean[] isbeg, int[] nnext, int[] nprev) {
super(isbeg);
this.nnext = nnext;
this.nprev = nprev;
}
public void visitBranch(int pc0, int pc1) {
nnext[pc0]++;
nprev[pc1]++;
}
}
private static final class MarkAndMergeVisitor extends BranchVisitor {
private final boolean[] isend;
private MarkAndMergeVisitor(boolean[] isbeg, boolean[] isend) {
super(isbeg);
this.isend = isend;
}
public void visitBranch(int pc0, int pc1) {
isend[pc0] = true;
isbeg[pc1] = true;
}
public void visitReturn(int pc) {
isend[pc] = true;
}
}
abstract public static class BranchVisitor { abstract public static class BranchVisitor {
final boolean[] isbeg; final boolean[] isbeg;
public BranchVisitor(boolean[] isbeg) { public BranchVisitor(boolean[] isbeg) {

View File

@@ -12,19 +12,11 @@ public class VarInfo {
public static VarInfo INVALID = new VarInfo(-1, -1); public static VarInfo INVALID = new VarInfo(-1, -1);
public static VarInfo PARAM(int slot) { public static VarInfo PARAM(int slot) {
return new VarInfo(slot, -1) { return new ParamVarInfo(slot, -1);
public String toString() {
return slot + ".p";
}
};
} }
public static VarInfo NIL(final int slot) { public static VarInfo NIL(final int slot) {
return new VarInfo(slot, -1) { return new NilVarInfo(slot, -1);
public String toString() {
return "nil";
}
};
} }
public static VarInfo PHI(final ProtoInfo pi, final int slot, final int pc) { public static VarInfo PHI(final ProtoInfo pi, final int slot, final int pc) {
@@ -67,6 +59,26 @@ public class VarInfo {
return false; return false;
} }
private static final class ParamVarInfo extends VarInfo {
private ParamVarInfo(int slot, int pc) {
super(slot, pc);
}
public String toString() {
return slot + ".p";
}
}
private static final class NilVarInfo extends VarInfo {
private NilVarInfo(int slot, int pc) {
super(slot, pc);
}
public String toString() {
return "nil";
}
}
private static final class PhiVarInfo extends VarInfo { private static final class PhiVarInfo extends VarInfo {
private final ProtoInfo pi; private final ProtoInfo pi;
VarInfo[] values; VarInfo[] values;