Remove support for lua2java within luaj.
This commit is contained in:
51
README.html
51
README.html
@@ -117,16 +117,6 @@ in comparison with the standard C distribution.
|
||||
<td>11.274</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>
|
||||
<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">
|
||||
<td></td>
|
||||
<td></td>
|
||||
@@ -179,8 +169,8 @@ in comparison with the standard C distribution.
|
||||
<td></td></tr>
|
||||
</table></td></tr></table>
|
||||
|
||||
Luaj in interpreted mode performs well for the benchmarks, and even better when source-to-source (lua2java)
|
||||
or bytecode-to-bytecode (luajc) compilers are used,
|
||||
Luaj in interpreted mode performs well for the benchmarks, and even better when
|
||||
the lua-to-java-bytecode (luajc) compiler is used,
|
||||
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.
|
||||
|
||||
@@ -220,29 +210,8 @@ From the main distribution directory line type:
|
||||
<p>
|
||||
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>
|
||||
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 "lib/luaj-jse-3.0-alpha1.jar;." 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>
|
||||
<h2>Compile lua source or bytecode to java bytecode</h2>
|
||||
|
||||
<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:
|
||||
@@ -372,19 +341,6 @@ that are needed and omitting the line:
|
||||
</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>
|
||||
|
||||
<p>
|
||||
@@ -774,6 +730,7 @@ and LuaForge:
|
||||
<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>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>
|
||||
</table></td></tr></table>
|
||||
|
||||
|
||||
@@ -132,7 +132,6 @@ public class LuaClosure extends LuaFunction {
|
||||
|
||||
public final LuaValue call() {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
return execute(stack,NONE).arg1();
|
||||
}
|
||||
|
||||
@@ -313,12 +312,13 @@ public class LuaClosure extends LuaFunction {
|
||||
|
||||
case Lua.OP_JMP: /* sBx pc+=sBx */
|
||||
pc += (i>>>14)-0x1ffff;
|
||||
if (a > 0)
|
||||
for (int j = 0; j < openups.length; ++j)
|
||||
if (openups[j] != null && openups[j].index == a) {
|
||||
openups[j].close();
|
||||
openups[j] = null;
|
||||
if (a > 0) {
|
||||
for (--a, b = openups.length; --b>=0; )
|
||||
if (openups[b] != null && openups[b].index >= a) {
|
||||
openups[b].close();
|
||||
openups[b] = null;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
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]) */
|
||||
{
|
||||
Prototype newp = p.p[i>>>14];
|
||||
LuaClosure ncl = new LuaClosure(newp);
|
||||
LuaClosure ncl = new LuaClosure(newp, null);
|
||||
Upvaldesc[] uv = newp.upvalues;
|
||||
for ( int j=0, nup=uv.length; j<nup; ++j ) {
|
||||
if (uv[j].instack) /* upvalue refes to local variable? */
|
||||
|
||||
@@ -42,6 +42,10 @@ public final class UpValue {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return index + "/" + array.length + " " + array[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this upvalue to a Java String
|
||||
* @return the Java String for this upvalue.
|
||||
@@ -71,7 +75,9 @@ public final class UpValue {
|
||||
* Close this upvalue so it is no longer on the stack
|
||||
*/
|
||||
public final void close() {
|
||||
array = new LuaValue[] { array[index] };
|
||||
LuaValue[] old = array;
|
||||
array = new LuaValue[] { old[index] };
|
||||
old[index] = null;
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.luaj.vm2.Print;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import org.luaj.vm2.lua2java.Lua2Java;
|
||||
import org.luaj.vm2.luajc.LuaJC;
|
||||
|
||||
|
||||
@@ -55,7 +54,6 @@ public class lua {
|
||||
" -l name require library 'name'\n" +
|
||||
" -i enter interactive mode after executing 'script'\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" +
|
||||
" -n nodebug - do not load debug library by default\n" +
|
||||
" -p pretty-print the prototype\n" +
|
||||
@@ -78,7 +76,6 @@ public class lua {
|
||||
boolean nodebug = false;
|
||||
boolean print = false;
|
||||
boolean luajc = false;
|
||||
boolean lua2java = false;
|
||||
Vector libs = null;
|
||||
try {
|
||||
// stateful argument processing
|
||||
@@ -99,9 +96,6 @@ public class lua {
|
||||
case 'b':
|
||||
luajc = true;
|
||||
break;
|
||||
case 'j':
|
||||
lua2java = true;
|
||||
break;
|
||||
case 'l':
|
||||
if ( ++i >= args.length )
|
||||
usageExit();
|
||||
@@ -139,7 +133,6 @@ public class lua {
|
||||
// new lua state
|
||||
_G = nodebug? JsePlatform.standardGlobals(): JsePlatform.debugGlobals();
|
||||
if ( luajc ) LuaJC.install();
|
||||
if ( lua2java) Lua2Java.install();
|
||||
for ( int i=0, n=libs!=null? libs.size(): 0; i<n; i++ )
|
||||
loadLibrary( (String) libs.elementAt(i) );
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ package org.luaj.vm2;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.lua2java.Lua2Java;
|
||||
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( JmeCompatibilityTest.class, "JME Tests" ) );
|
||||
suite.addTest( new TestSuite( LuaJCTest.class, "JSE Bytecode Tests" ) );
|
||||
suite.addTest( new TestSuite( Lua2JavaTest.class, "Lua2Java Tests" ) );
|
||||
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 JmeCompatibilityTest() {
|
||||
super(ScriptDrivenTest.PlatformType.JME);
|
||||
|
||||
@@ -28,7 +28,6 @@ import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lua2java.Lua2Java;
|
||||
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_LUAJC = 1;
|
||||
static final int TEST_TYPE_LUA2JAVA = 2;
|
||||
|
||||
public static class JseFragmentsTest extends FragmentsTestCase {
|
||||
public JseFragmentsTest() { super( TEST_TYPE_LUAC ); }
|
||||
@@ -48,15 +46,10 @@ public class FragmentsTest extends TestSuite {
|
||||
public static class LuaJCFragmentsTest extends FragmentsTestCase {
|
||||
public LuaJCFragmentsTest() { super( TEST_TYPE_LUAJC ); }
|
||||
}
|
||||
public static class Lua2JavaFragmentsTest extends FragmentsTestCase {
|
||||
public Lua2JavaFragmentsTest() { super( TEST_TYPE_LUA2JAVA ); }
|
||||
}
|
||||
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite("Compiler Fragments Tests");
|
||||
suite.addTest( new TestSuite( JseFragmentsTest.class, "JSE Fragments Tests" ) );
|
||||
suite.addTest( new TestSuite( LuaJCFragmentsTest.class, "LuaJC Fragments Tests" ) );
|
||||
suite.addTest( new TestSuite( Lua2JavaFragmentsTest.class, "Lua2Java Fragments Tests" ) );
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -75,9 +68,6 @@ public class FragmentsTest extends TestSuite {
|
||||
InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8"));
|
||||
LuaValue chunk ;
|
||||
switch ( TEST_TYPE ) {
|
||||
case TEST_TYPE_LUA2JAVA:
|
||||
chunk = Lua2Java.instance.load(is,name,LuaValue._G);
|
||||
break;
|
||||
case TEST_TYPE_LUAJC:
|
||||
chunk = LuaJC.getInstance().load(is,name,LuaValue._G);
|
||||
break;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ScriptDrivenTest extends TestCase {
|
||||
public static final boolean nocompile = "true".equals(System.getProperty("nocompile"));
|
||||
|
||||
public enum PlatformType {
|
||||
JME, JSE, LUAJIT, LUA2JAVA,
|
||||
JME, JSE, LUAJIT,
|
||||
}
|
||||
|
||||
private final PlatformType platform;
|
||||
@@ -59,7 +59,6 @@ public class ScriptDrivenTest extends TestCase {
|
||||
default:
|
||||
case JSE:
|
||||
case LUAJIT:
|
||||
case LUA2JAVA:
|
||||
_G = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals();
|
||||
break;
|
||||
case JME:
|
||||
|
||||
Reference in New Issue
Block a user