Remove support for lua2java within luaj.

This commit is contained in:
James Roseborough
2012-09-08 04:15:06 +00:00
parent f2d1106fe5
commit f224957b87
11 changed files with 19 additions and 1748 deletions

View File

@@ -117,16 +117,6 @@ in comparison with the standard C distribution.
<td>11.274</td> <td>11.274</td>
<td>Java</td> <td>Java</td>
<td>java -cp luaj-jse-3.0-alpha1.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr> <td>java -cp luaj-jse-3.0-alpha1.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
<tr valign="top">
<td></td>
<td></td>
<td>-j (lua2java)</td>
<td>4.463</td>
<td>5.884</td>
<td>16.701</td>
<td>13.789</td>
<td></td>
<td>java -cp luaj-jse-3.0-alpha1.jar lua <b>-j</b> fannkuch.lua 10</td></tr>
<tr valign="top"> <tr valign="top">
<td></td> <td></td>
<td></td> <td></td>
@@ -179,8 +169,8 @@ in comparison with the standard C distribution.
<td></td></tr> <td></td></tr>
</table></td></tr></table> </table></td></tr></table>
Luaj in interpreted mode performs well for the benchmarks, and even better when source-to-source (lua2java) Luaj in interpreted mode performs well for the benchmarks, and even better when
or bytecode-to-bytecode (luajc) compilers are used, the lua-to-java-bytecode (luajc) compiler is used,
and actually executes <em>faster</em> than C-based lua in some cases. and actually executes <em>faster</em> than C-based lua in some cases.
It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for all benchmarks tested. It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for all benchmarks tested.
@@ -220,29 +210,8 @@ From the main distribution directory line type:
<p> <p>
The compiled output "luac.out" is lua bytecode and should run and produce the same result. The compiled output "luac.out" is lua bytecode and should run and produce the same result.
<h2>Compile lua source to java source</h2>
<p> <h2>Compile lua source or bytecode to java bytecode</h2>
Luaj can compile to lua source code to Java source code:
<pre>
java -cp lib/luaj-jse-3.0-alpha1.jar lua2java -s examples/lua -d . hello.lua
javac -cp lib/luaj-jse-3.0-alpha1.jar hello.java
java -cp &quot;lib/luaj-jse-3.0-alpha1.jar;.&quot; lua -l hello
</pre>
<p>
The output <em>hello.java</em> is Java source, that implements the logic in hello.lua directly.
Once <em>hello.java</em> is compiled into <em>hello.class</em> it can be required and used in place of the original lua script, but with better performance.
There are no additional dependencies for compiling or running source-to-source compiled lua.
<p>
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-j</em></b> option when run in JDK 1.5 or higher:
<pre>
java -cp lib/luaj-jse-3.0-alpha1.jar lua -j examples/lua/hello.lua
</pre>
<h2>Compile lua bytecode to java bytecode</h2>
<p> <p>
Luaj can compile lua sources or binaries directly to java bytecode if the bcel library is on the class path. From the main distribution directory line type: Luaj can compile lua sources or binaries directly to java bytecode if the bcel library is on the class path. From the main distribution directory line type:
@@ -372,19 +341,6 @@ that are needed and omitting the line:
</pre> </pre>
<h2>Including the Lua2Java lua-source-to-Java-source compiler</h2>
<p>
To compile from lua sources to Java sources for all lua loaded at runtime,
install the Lua2Java compiler <em>after</em> globals have been created using:
<pre>
org.luaj.vm2.jse.lua2java.Lua2Java.install();
</pre>
This uses the system Java compiler to compile from Java source to Java bytecode,
and cannot compile lua binary files containing lua bytecode at runtime.
<h2>Including the LuaJC lua-bytecode-to-Java-bytecode compiler</h2> <h2>Including the LuaJC lua-bytecode-to-Java-bytecode compiler</h2>
<p> <p>
@@ -774,6 +730,7 @@ and LuaForge:
<li>Fix load(func) when mutiple string fragments are supplied by calls to func </li> <li>Fix load(func) when mutiple string fragments are supplied by calls to func </li>
<li>Allow access to public members of private inner classes where possible </li> <li>Allow access to public members of private inner classes where possible </li>
<li>Add line and column info to org.luaj.vm2.ast parse tree elements generated using LuaParser </li> <li>Add line and column info to org.luaj.vm2.ast parse tree elements generated using LuaParser </li>
<li>Drop support for lua source to java surce (lua2java) in favor of direct java bytecode output (luajc) </li>
</ul></td></tr> </ul></td></tr>
</table></td></tr></table> </table></td></tr></table>

View File

@@ -132,7 +132,6 @@ public class LuaClosure extends LuaFunction {
public final LuaValue call() { public final LuaValue call() {
LuaValue[] stack = new LuaValue[p.maxstacksize]; LuaValue[] stack = new LuaValue[p.maxstacksize];
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
return execute(stack,NONE).arg1(); return execute(stack,NONE).arg1();
} }
@@ -313,12 +312,13 @@ public class LuaClosure extends LuaFunction {
case Lua.OP_JMP: /* sBx pc+=sBx */ case Lua.OP_JMP: /* sBx pc+=sBx */
pc += (i>>>14)-0x1ffff; pc += (i>>>14)-0x1ffff;
if (a > 0) if (a > 0) {
for (int j = 0; j < openups.length; ++j) for (--a, b = openups.length; --b>=0; )
if (openups[j] != null && openups[j].index == a) { if (openups[b] != null && openups[b].index >= a) {
openups[j].close(); openups[b].close();
openups[j] = null; openups[b] = null;
} }
}
continue; continue;
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
@@ -466,7 +466,7 @@ public class LuaClosure extends LuaFunction {
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */ case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
{ {
Prototype newp = p.p[i>>>14]; Prototype newp = p.p[i>>>14];
LuaClosure ncl = new LuaClosure(newp); LuaClosure ncl = new LuaClosure(newp, null);
Upvaldesc[] uv = newp.upvalues; Upvaldesc[] uv = newp.upvalues;
for ( int j=0, nup=uv.length; j<nup; ++j ) { for ( int j=0, nup=uv.length; j<nup; ++j ) {
if (uv[j].instack) /* upvalue refes to local variable? */ if (uv[j].instack) /* upvalue refes to local variable? */

View File

@@ -41,6 +41,10 @@ public final class UpValue {
this.array = stack; this.array = stack;
this.index = index; this.index = index;
} }
public String toString() {
return index + "/" + array.length + " " + array[index];
}
/** /**
* Convert this upvalue to a Java String * Convert this upvalue to a Java String
@@ -71,7 +75,9 @@ public final class UpValue {
* Close this upvalue so it is no longer on the stack * Close this upvalue so it is no longer on the stack
*/ */
public final void close() { public final void close() {
array = new LuaValue[] { array[index] }; LuaValue[] old = array;
array = new LuaValue[] { old[index] };
old[index] = null;
index = 0; index = 0;
} }
} }

View File

@@ -38,7 +38,6 @@ import org.luaj.vm2.Print;
import org.luaj.vm2.Varargs; import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.DebugLib; import org.luaj.vm2.lib.DebugLib;
import org.luaj.vm2.lib.jse.JsePlatform; import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.lua2java.Lua2Java;
import org.luaj.vm2.luajc.LuaJC; import org.luaj.vm2.luajc.LuaJC;
@@ -55,7 +54,6 @@ public class lua {
" -l name require library 'name'\n" + " -l name require library 'name'\n" +
" -i enter interactive mode after executing 'script'\n" + " -i enter interactive mode after executing 'script'\n" +
" -v show version information\n" + " -v show version information\n" +
" -j use lua2java source-to-source compiler\n" +
" -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" + " -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
" -n nodebug - do not load debug library by default\n" + " -n nodebug - do not load debug library by default\n" +
" -p pretty-print the prototype\n" + " -p pretty-print the prototype\n" +
@@ -78,7 +76,6 @@ public class lua {
boolean nodebug = false; boolean nodebug = false;
boolean print = false; boolean print = false;
boolean luajc = false; boolean luajc = false;
boolean lua2java = false;
Vector libs = null; Vector libs = null;
try { try {
// stateful argument processing // stateful argument processing
@@ -99,9 +96,6 @@ public class lua {
case 'b': case 'b':
luajc = true; luajc = true;
break; break;
case 'j':
lua2java = true;
break;
case 'l': case 'l':
if ( ++i >= args.length ) if ( ++i >= args.length )
usageExit(); usageExit();
@@ -139,7 +133,6 @@ public class lua {
// new lua state // new lua state
_G = nodebug? JsePlatform.standardGlobals(): JsePlatform.debugGlobals(); _G = nodebug? JsePlatform.standardGlobals(): JsePlatform.debugGlobals();
if ( luajc ) LuaJC.install(); if ( luajc ) LuaJC.install();
if ( lua2java) Lua2Java.install();
for ( int i=0, n=libs!=null? libs.size(): 0; i<n; i++ ) for ( int i=0, n=libs!=null? libs.size(): 0; i<n; i++ )
loadLibrary( (String) libs.elementAt(i) ); loadLibrary( (String) libs.elementAt(i) );

View File

@@ -1,213 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import org.luaj.vm2.Lua;
import org.luaj.vm2.ast.Chunk;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.lua2java.JavaCodeGen;
import org.luaj.vm2.parser.LuaParser;
/**
* Compile lua sources into java sources.
*/
public class lua2java {
private static final String version = Lua._VERSION + "Copyright (C) 2010 luaj.org";
private static final String usage =
"usage: java -cp luaj-jse.jar lua2java [options] fileordir [, fileordir ...]\n" +
"Available options are:\n" +
" - process stdin\n" +
" -s src source directory\n" +
" -d dir destination directory\n" +
" -p pkg package prefix to apply to all classes\n" +
" -e enc override default character encoding\n" +
" -r recursively compile all\n" +
" -v verbose\n";
private static void usageExit() {
System.out.println(usage);
System.exit(-1);
}
private String srcdir = null;
private String destdir = null;
private String pkgprefix = null;
private String encoding = "ISO8859-1";
private boolean recurse = false;
private boolean verbose = false;
private List files = new ArrayList();
public static void main( String[] args ) throws IOException {
new lua2java( args );
}
private lua2java( String[] args ) throws IOException {
// process args
try {
List seeds = new ArrayList ();
// get stateful args
for ( int i=0; i<args.length; i++ ) {
if ( ! args[i].startsWith("-") ) {
seeds.add(args[i]);
} else {
switch ( args[i].charAt(1) ) {
case 's':
if ( ++i >= args.length )
usageExit();
srcdir = args[i];
break;
case 'd':
if ( ++i >= args.length )
usageExit();
destdir = args[i];
break;
case 'p':
if ( ++i >= args.length )
usageExit();
pkgprefix = args[i];
break;
case 'e':
if ( ++i >= args.length )
usageExit();
encoding = args[i];
break;
case 'r':
recurse = true;
break;
case 'v':
verbose = true;
break;
default:
usageExit();
break;
}
}
}
// echo version
if ( verbose ) {
System.out.println(version);
System.out.println("srcdir: "+srcdir);
System.out.println("destdir: "+destdir);
System.out.println("files: "+seeds);
System.out.println("encoding: "+encoding);
System.out.println("recurse: "+recurse);
}
// need at least one seed
if ( seeds.size() <= 0 ) {
System.err.println(usage);
System.exit(-1);
}
// collect up files to process
for ( int i=0; i<seeds.size(); i++ )
collectFiles( srcdir+"/"+seeds.get(i) );
// check for at least one file
if ( files.size() <= 0 ) {
System.err.println("no files found in "+seeds);
System.exit(-1);
}
// process input files
JsePlatform.standardGlobals();
for ( int i=0,n=files.size(); i<n; i++ )
processFile( (InputFile) files.get(i) );
} catch ( Exception ioe ) {
System.err.println( ioe.toString() );
System.exit(-2);
}
}
private void collectFiles(String path) {
File f = new File(path);
if ( f.isDirectory() && recurse )
scandir(f,pkgprefix);
else if ( f.isFile() ) {
File dir = f.getAbsoluteFile().getParentFile();
if ( dir != null )
scanfile( dir, f, pkgprefix );
}
}
private void scandir(File dir, String javapackage) {
File[] f = dir.listFiles();
for ( int i=0; i<f.length; i++ )
scanfile( dir, f[i], javapackage );
}
private void scanfile(File dir, File f, String javapackage) {
if ( f.exists() ) {
if ( f.isDirectory() && recurse )
scandir( f, (javapackage!=null? javapackage+"."+f.getName(): f.getName()) );
else if ( f.isFile() && f.getName().endsWith(".lua") )
files.add( new InputFile(dir,f,javapackage) );
}
}
class InputFile {
public File infile;
public File outdir;
public File outfile;
public String javapackage;
public String javaclassname;
public InputFile(File dir, File f, String javapackage) {
String outdirpath = javapackage!=null? destdir+"/"+javapackage.replace('.', '/'): destdir;
this.javaclassname = f.getName().substring(0,f.getName().lastIndexOf('.'));
this.javapackage = javapackage;
this.infile = f;
this.outdir = new File(outdirpath);
this.outfile = new File(outdirpath+"/"+this.javaclassname+".java");
}
}
private void processFile( InputFile inf ) {
inf.outdir.mkdirs();
try {
if ( verbose )
System.out.println(
"pkg="+inf.javapackage+" file="+inf.javaclassname+".java dest="+inf.outfile+" src="+inf.infile);
FileInputStream in = new FileInputStream(inf.infile);
FileOutputStream out = new FileOutputStream(inf.outfile);
PrintWriter pw = new PrintWriter(out);
LuaParser parser = new LuaParser(in,encoding);
Chunk chunk = parser.Chunk();
new JavaCodeGen(chunk,pw,inf.javapackage,inf.javaclassname);
pw.close();
out.close();
in.close();
} catch ( Exception e ) {
e.printStackTrace( System.err );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,189 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.lua2java;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.luaj.vm2.Lua;
import org.luaj.vm2.ast.Block;
import org.luaj.vm2.ast.Chunk;
import org.luaj.vm2.ast.FuncBody;
import org.luaj.vm2.ast.NameScope;
import org.luaj.vm2.ast.Variable;
import org.luaj.vm2.ast.Visitor;
import org.luaj.vm2.ast.Exp.BinopExp;
import org.luaj.vm2.ast.Exp.VarargsExp;
import org.luaj.vm2.ast.Stat.Return;
import org.luaj.vm2.lib.LibFunction;
public class JavaScope extends NameScope {
private static final int MAX_CONSTNAME_LEN = 8;
public static final Set<String> SPECIALS = new HashSet<String>();
private static final String[] specials = {
// keywords used by our code generator
"name", "opcode", "env", // "arg",
// java keywords
"abstract", "continue", "for", "new", "switch",
"assert", "default", "goto", "package", "synchronized",
"boolean", "do", "if", "private", "this",
"break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws",
"case", "enum", "instanceof", "return", "transient",
"catch", "extends", "int", "short", "try",
"char", "final", "interface", "static", "void",
"class", "finally", "long", "strictfp", "volatile",
"const", "float", "native", "super", "while",
// java literals
"false", "null", "true",
};
static {
for ( int i=0; i<specials.length; i++ )
SPECIALS.add(specials[i]);
java.lang.reflect.Field[] fields = LibFunction.class.getFields();
for ( int i=0, n=fields.length; i<n; i++ )
SPECIALS.add(fields[i].getName());
java.lang.reflect.Method[] methods = LibFunction.class.getMethods();
for ( int i=0, n=methods.length; i<n; i++ )
SPECIALS.add(methods[i].getName());
}
public int nreturns;
public boolean needsbinoptmp;
public boolean usesvarargs;
final Set<String> staticnames;
final Set<String> javanames = new HashSet<String>();
final Map<Object,String> astele2javaname = new HashMap<Object,String>();
private JavaScope(Set<String> staticnames, JavaScope outerScope) {
super(outerScope);
this.staticnames = staticnames;
}
public static JavaScope newJavaScope(Chunk chunk) {
return new JavaScope(new HashSet<String>(), null).initialize(chunk.block, -1);
}
public JavaScope pushJavaScope(FuncBody body) {
return new JavaScope(staticnames, this).initialize(body.block, 0);
}
public JavaScope popJavaScope() {
return (JavaScope) outerScope;
}
final String getJavaName(Variable nv) {
for ( JavaScope s = this; s != null; s = (JavaScope) s.outerScope )
if ( s.astele2javaname.containsKey(nv) )
return (String) s.astele2javaname.get(nv);
return allocateJavaName( nv, nv.name );
}
final private String allocateJavaName(Object astele, String proposal) {
for ( int i=0; true; i++ ) {
String jname = proposal+(i==0? "": "$"+i);
if ( ! isJavanameInScope(jname) && ! SPECIALS.contains(jname) && !staticnames.contains(jname) ) {
javanames.add(jname);
astele2javaname.put(astele,jname);
return jname;
}
}
}
public void setJavaName(Variable astele, String javaname) {
javanames.add(javaname);
astele2javaname.put(astele,javaname);
}
private boolean isJavanameInScope(String javaname) {
for ( JavaScope s = this; s != null; s = (JavaScope) s.outerScope )
if ( s.javanames.contains(javaname) )
return true;
return false;
}
public String createConstantName(String proposal) {
proposal = toLegalJavaName(proposal);
for ( int i=0; true; i++ ) {
String jname = proposal+(i==0? "": "$"+i);
if ( ! isJavanameInScope(jname) && ! SPECIALS.contains(jname) && !staticnames.contains(jname) ) {
javanames.add(jname);
staticnames.add(jname);
return jname;
}
}
}
public static String toLegalJavaName(String string) {
String better = string.replaceAll("[^\\w]", "_");
if ( better.length() > MAX_CONSTNAME_LEN )
better = better.substring(0,MAX_CONSTNAME_LEN);
if ( better.length() == 0 || !Character.isJavaIdentifierStart( better.charAt(0) ) )
better = "_"+better;
return better;
}
private JavaScope initialize(Block block, int nreturns) {
NewScopeVisitor v = new NewScopeVisitor(nreturns);
block.accept( v );
this.nreturns = v.nreturns;
this.needsbinoptmp = v.needsbinoptmp;
this.usesvarargs = v.usesvarargs;
return this;
}
class NewScopeVisitor extends Visitor {
int nreturns = 0;
boolean needsbinoptmp = false;
boolean usesvarargs = false;
NewScopeVisitor(int nreturns) {
this.nreturns = nreturns;
}
public void visit(FuncBody body) {}
public void visit(Return s) {
int n = s.nreturns();
nreturns = (nreturns<0||n<0? -1: Math.max(n,nreturns));
super.visit(s);
}
public void visit(BinopExp exp) {
switch ( exp.op ) {
case Lua.OP_AND: case Lua.OP_OR:
needsbinoptmp = true;
break;
}
super.visit(exp);
}
public void visit(VarargsExp exp) {
usesvarargs = true;
}
}
}

View File

@@ -1,165 +0,0 @@
package org.luaj.vm2.lua2java;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.LoadState.LuaCompiler;
import org.luaj.vm2.ast.Chunk;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.parser.LuaParser;
public class Lua2Java implements LuaCompiler {
public static final Lua2Java instance = new Lua2Java();
public static final void install() {
LoadState.compiler = instance;
}
private Lua2Java() {
}
public LuaFunction load(InputStream stream, String filename, LuaValue env) throws IOException {
// get first byte
if ( ! stream.markSupported() )
stream = new BufferedInputStream( stream );
stream.mark( 1 );
int firstByte = stream.read();
stream.reset();
// we can only sompile sources
if ( firstByte != '\033' ) {
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null)
LuaValue.error("no java compiler");
// break into package and class
if ( filename.endsWith( ".lua") )
filename = filename.substring(0, filename.length()-4);
String s = filename.replace('\\', '/').replace('/','.').replaceAll("[^\\w]", "_");
int p = s.lastIndexOf('.');
final String packageName = p>=0? s.substring(0,p): null;
final String className = toClassname( s.substring(p+1) );
// open output file
final String pkgSubdir = (packageName!=null? packageName.replace('.','/'): "");
final String srcDirRoot = "lua2java/src";
final String binDirRoot = "lua2java/classes";
final String srcDirname = srcDirRoot+"/"+pkgSubdir;
final String binDirname = binDirRoot+"/"+pkgSubdir;
final String srcFilename = srcDirname + "/" + className + ".java";
// make directories
new File(srcDirname).mkdirs();
new File(binDirname).mkdirs();
// generate java source
try {
LuaParser parser = new LuaParser(stream,"ISO8859-1");
Chunk chunk = parser.Chunk();
File source = new File(srcFilename);
Writer writer = new OutputStreamWriter( new FileOutputStream(source) );
new JavaCodeGen(chunk,writer,packageName,className);
writer.close();
// set up output location
StandardJavaFileManager fm = compiler.getStandardFileManager( null, null, null);
fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File[] { new File(binDirRoot) }));
// compile the file
CompilationTask task = compiler.getTask(null, fm, null, null, null, fm.getJavaFileObjects(source));
boolean success = task.call().booleanValue();
// instantiate, config and return
if (success) {
// create instance
ClassLoader cl = new ClassLoader() {
public Class findClass(String classname) throws ClassNotFoundException {
if ( classname.startsWith(className) ) {
File f = new File( binDirname+"/"+classname+".class");
long n = f.length();
byte[] b = new byte[(int) n];
try {
DataInputStream dis = new DataInputStream( new FileInputStream(f) );
dis.readFully(b);
} catch ( Exception e ) {
throw new RuntimeException("failed to read class bytes: "+e );
}
return defineClass(classname, b, 0, b.length);
}
return super.findClass(classname);
}
};
Class clazz = cl.loadClass(className);
Object instance = clazz.newInstance();
LuaFunction value = (LuaFunction) instance;
return value;
} else {
}
} catch ( Exception e ) {
LuaValue.error("compile task failed: "+e);
}
// report compilation error
LuaValue.error("compile task failed:");
return null;
}
// fall back to plain compiler
return LuaC.instance.load( stream, filename, env);
}
/** Convert lua filename to valid class name */
public static final String toClassname( String filename ) {
int n=filename.length();
int j=n;
if ( filename.endsWith(".lua") )
j -= 4;
for ( int k=0; k<j; k++ ) {
char c = filename.charAt(k);
if ( (!isClassnamePart(c)) || (c=='/') || (c=='\\') ) {
StringBuffer sb = new StringBuffer(j);
for ( int i=0; i<j; i++ ) {
c = filename.charAt(i);
sb.append(
(isClassnamePart(c))? c:
((c=='/') || (c=='\\'))? '.': '_' );
}
return sb.toString();
}
}
return n==j? filename: filename.substring(0,j);
}
private static final boolean isClassnamePart(char c) {
if ( (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') )
return true;
switch ( c ) {
case '.':
case '$':
case '_':
return true;
default:
return false;
}
}
}

View File

@@ -23,7 +23,6 @@ package org.luaj.vm2;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.luaj.vm2.lua2java.Lua2Java;
import org.luaj.vm2.luajc.LuaJC; import org.luaj.vm2.luajc.LuaJC;
/** /**
@@ -80,21 +79,9 @@ public class CompatibiltyTest extends TestSuite {
suite.addTest( new TestSuite( JseCompatibilityTest.class, "JSE Tests" ) ); suite.addTest( new TestSuite( JseCompatibilityTest.class, "JSE Tests" ) );
suite.addTest( new TestSuite( JmeCompatibilityTest.class, "JME Tests" ) ); suite.addTest( new TestSuite( JmeCompatibilityTest.class, "JME Tests" ) );
suite.addTest( new TestSuite( LuaJCTest.class, "JSE Bytecode Tests" ) ); suite.addTest( new TestSuite( LuaJCTest.class, "JSE Bytecode Tests" ) );
suite.addTest( new TestSuite( Lua2JavaTest.class, "Lua2Java Tests" ) );
return suite; return suite;
} }
public static class Lua2JavaTest extends CompatibiltyTestSuite {
public Lua2JavaTest() {
super(ScriptDrivenTest.PlatformType.LUA2JAVA);
}
protected void setUp() throws Exception {
super.setUp();
System.setProperty("JME", "false");
Lua2Java.install();
}
}
public static class JmeCompatibilityTest extends CompatibiltyTestSuite { public static class JmeCompatibilityTest extends CompatibiltyTestSuite {
public JmeCompatibilityTest() { public JmeCompatibilityTest() {
super(ScriptDrivenTest.PlatformType.JME); super(ScriptDrivenTest.PlatformType.JME);

View File

@@ -28,7 +28,6 @@ import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.luaj.vm2.compiler.LuaC; import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lua2java.Lua2Java;
import org.luaj.vm2.luajc.LuaJC; import org.luaj.vm2.luajc.LuaJC;
/** /**
@@ -40,7 +39,6 @@ public class FragmentsTest extends TestSuite {
static final int TEST_TYPE_LUAC = 0; static final int TEST_TYPE_LUAC = 0;
static final int TEST_TYPE_LUAJC = 1; static final int TEST_TYPE_LUAJC = 1;
static final int TEST_TYPE_LUA2JAVA = 2;
public static class JseFragmentsTest extends FragmentsTestCase { public static class JseFragmentsTest extends FragmentsTestCase {
public JseFragmentsTest() { super( TEST_TYPE_LUAC ); } public JseFragmentsTest() { super( TEST_TYPE_LUAC ); }
@@ -48,15 +46,10 @@ public class FragmentsTest extends TestSuite {
public static class LuaJCFragmentsTest extends FragmentsTestCase { public static class LuaJCFragmentsTest extends FragmentsTestCase {
public LuaJCFragmentsTest() { super( TEST_TYPE_LUAJC ); } public LuaJCFragmentsTest() { super( TEST_TYPE_LUAJC ); }
} }
public static class Lua2JavaFragmentsTest extends FragmentsTestCase {
public Lua2JavaFragmentsTest() { super( TEST_TYPE_LUA2JAVA ); }
}
public static TestSuite suite() { public static TestSuite suite() {
TestSuite suite = new TestSuite("Compiler Fragments Tests"); TestSuite suite = new TestSuite("Compiler Fragments Tests");
suite.addTest( new TestSuite( JseFragmentsTest.class, "JSE Fragments Tests" ) ); suite.addTest( new TestSuite( JseFragmentsTest.class, "JSE Fragments Tests" ) );
suite.addTest( new TestSuite( LuaJCFragmentsTest.class, "LuaJC Fragments Tests" ) ); suite.addTest( new TestSuite( LuaJCFragmentsTest.class, "LuaJC Fragments Tests" ) );
suite.addTest( new TestSuite( Lua2JavaFragmentsTest.class, "Lua2Java Fragments Tests" ) );
return suite; return suite;
} }
@@ -75,9 +68,6 @@ public class FragmentsTest extends TestSuite {
InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8")); InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8"));
LuaValue chunk ; LuaValue chunk ;
switch ( TEST_TYPE ) { switch ( TEST_TYPE ) {
case TEST_TYPE_LUA2JAVA:
chunk = Lua2Java.instance.load(is,name,LuaValue._G);
break;
case TEST_TYPE_LUAJC: case TEST_TYPE_LUAJC:
chunk = LuaJC.getInstance().load(is,name,LuaValue._G); chunk = LuaJC.getInstance().load(is,name,LuaValue._G);
break; break;

View File

@@ -41,7 +41,7 @@ public class ScriptDrivenTest extends TestCase {
public static final boolean nocompile = "true".equals(System.getProperty("nocompile")); public static final boolean nocompile = "true".equals(System.getProperty("nocompile"));
public enum PlatformType { public enum PlatformType {
JME, JSE, LUAJIT, LUA2JAVA, JME, JSE, LUAJIT,
} }
private final PlatformType platform; private final PlatformType platform;
@@ -59,7 +59,6 @@ public class ScriptDrivenTest extends TestCase {
default: default:
case JSE: case JSE:
case LUAJIT: case LUAJIT:
case LUA2JAVA:
_G = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals(); _G = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals();
break; break;
case JME: case JME: