diff --git a/README.html b/README.html index fe74cff1..6a7b1b5f 100644 --- a/README.html +++ b/README.html @@ -732,6 +732,7 @@ and LuaForge:
* This is an internal class not intended to be used directly.
diff --git a/src/core/org/luaj/vm2/lib/PackageLib.java b/src/core/org/luaj/vm2/lib/PackageLib.java
index 1755df36..6b1b299d 100644
--- a/src/core/org/luaj/vm2/lib/PackageLib.java
+++ b/src/core/org/luaj/vm2/lib/PackageLib.java
@@ -24,6 +24,7 @@ package org.luaj.vm2.lib;
import java.io.InputStream;
import org.luaj.vm2.Globals;
+import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
@@ -306,6 +307,8 @@ public class PackageLib extends OneArgFunction {
try {
c = Class.forName(classname);
v = (LuaValue) c.newInstance();
+ if (v.isfunction())
+ ((LuaFunction)v).initupvalue1(globals);
return v;
} catch ( ClassNotFoundException cnfe ) {
return valueOf("\n\tno class '"+classname+"'" );
diff --git a/src/core/org/luaj/vm2/lib/VarArgFunction.java b/src/core/org/luaj/vm2/lib/VarArgFunction.java
index 60e98424..f529376a 100644
--- a/src/core/org/luaj/vm2/lib/VarArgFunction.java
+++ b/src/core/org/luaj/vm2/lib/VarArgFunction.java
@@ -46,6 +46,7 @@ import org.luaj.vm2.Varargs;
* @see ThreeArgFunction
*/
abstract public class VarArgFunction extends LibFunction {
+
public VarArgFunction() {
}
diff --git a/src/jse/luajc.java b/src/jse/luajc.java
index 0d238274..5252af42 100644
--- a/src/jse/luajc.java
+++ b/src/jse/luajc.java
@@ -37,7 +37,7 @@ import org.luaj.vm2.luajc.LuaJC;
* Compiler for lua files to compile lua sources or lua binaries into java classes.
*/
public class luajc {
- private static final String version = Lua._VERSION + "Copyright (C) 2009 luaj.org";
+ private static final String version = Lua._VERSION + " Copyright (C) 2012 luaj.org";
private static final String usage =
"usage: java -cp luaj-jse.jar,bcel-5.2.jar luajc [options] fileordir [, fileordir ...]\n" +
@@ -46,6 +46,7 @@ public class luajc {
" -s src source directory\n" +
" -d dir destination directory\n" +
" -p pkg package prefix to apply to all classes\n" +
+ " -m generate main(String[]) function for JSE\n" +
" -r recursively compile all\n" +
" -l load classes to verify generated bytecode\n" +
" -v verbose\n";
@@ -57,6 +58,7 @@ public class luajc {
private String srcdir = null;
private String destdir = null;
+ private boolean genmain = false;
private boolean recurse = false;
private boolean verbose = false;
private boolean loadclasses = false;
@@ -96,6 +98,9 @@ public class luajc {
usageExit();
pkgprefix = args[i];
break;
+ case 'm':
+ genmain = true;
+ break;
case 'r':
recurse = true;
break;
@@ -113,7 +118,7 @@ public class luajc {
if ( verbose ) {
System.out.println(version);
System.out.println("srcdir: "+srcdir);
- System.out.println("destdir: "+srcdir);
+ System.out.println("destdir: "+destdir);
System.out.println("files: "+seeds);
System.out.println("recurse: "+recurse);
}
@@ -192,7 +197,7 @@ public class luajc {
// create the chunk
FileInputStream fis = new FileInputStream( inf.infile );
- final Hashtable t = LuaJC.getInstance().compileAll(fis, inf.luachunkname, inf.srcfilename);
+ final Hashtable t = LuaJC.getInstance().compileAll(fis, inf.luachunkname, inf.srcfilename, genmain);
fis.close();
// write out the chunk
diff --git a/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java b/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java
index f346ef9d..12ecbd74 100644
--- a/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java
+++ b/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java
@@ -25,6 +25,7 @@ import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue;
+import org.luaj.vm2.Varargs;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.Bit32Lib;
import org.luaj.vm2.lib.CoroutineLib;
@@ -120,4 +121,22 @@ public class JsePlatform {
_G.load(new DebugLib());
return _G;
}
+
+
+ /** Simple wrapper for invoking a lua function with command line arguments.
+ * The supplied function is first given a new Globals object,
+ * then the program is run with arguments.
+ */
+ public static void luaMain(LuaValue mainChunk, String[] args) {
+ Globals g = standardGlobals();
+ int n = args.length;
+ LuaValue[] vargs = new LuaValue[args.length];
+ for (int i = 0; i < n; ++i)
+ vargs[i] = LuaValue.valueOf(args[i]);
+ LuaTable arg = LuaValue.listOf(vargs);
+ arg.set("n", n);
+ g.set("arg", arg);
+ mainChunk.initupvalue1(g);
+ mainChunk.invoke(LuaValue.varargsOf(vargs));
+ }
}
diff --git a/src/jse/org/luaj/vm2/luajc/JavaBuilder.java b/src/jse/org/luaj/vm2/luajc/JavaBuilder.java
index 1cbd4b01..cd6cf132 100644
--- a/src/jse/org/luaj/vm2/luajc/JavaBuilder.java
+++ b/src/jse/org/luaj/vm2/luajc/JavaBuilder.java
@@ -77,6 +77,7 @@ public class JavaBuilder {
private static final String STR_LUATABLE = LuaTable.class.getName();
private static final String STR_BUFFER = Buffer.class.getName();
private static final String STR_STRING = String.class.getName();
+ private static final String STR_JSEPLATFORM = "org.luaj.vm2.lib.jse.JsePlatform";
private static final ObjectType TYPE_VARARGS = new ObjectType(STR_VARARGS);
private static final ObjectType TYPE_LUAVALUE = new ObjectType(STR_LUAVALUE);
@@ -86,10 +87,11 @@ public class JavaBuilder {
private static final ObjectType TYPE_LUABOOLEAN = new ObjectType(STR_LUABOOLEAN);
private static final ObjectType TYPE_LUATABLE = new ObjectType(STR_LUATABLE);
private static final ObjectType TYPE_BUFFER = new ObjectType(STR_BUFFER);
+ private static final ObjectType TYPE_STRING = new ObjectType(STR_STRING);
private static final ArrayType TYPE_LOCALUPVALUE = new ArrayType( TYPE_LUAVALUE, 1 );
private static final ArrayType TYPE_CHARARRAY = new ArrayType( Type.CHAR, 1 );
- private static final ArrayType TYPE_LUAVALUEARRAY = new ArrayType( TYPE_LUAVALUE, 1 );
+ private static final ArrayType TYPE_STRINGARRAY = new ArrayType( TYPE_STRING, 1 );
private static final String STR_FUNCV = VarArgFunction.class.getName();
@@ -116,6 +118,8 @@ public class JavaBuilder {
private static final Type[] ARG_TYPES_INT_INT = { Type.INT, Type.INT };
private static final Type[] ARG_TYPES_LUAVALUE = { TYPE_LUAVALUE };
private static final Type[] ARG_TYPES_BUFFER = { TYPE_BUFFER };
+ private static final Type[] ARG_TYPES_STRINGARRAY = { TYPE_STRINGARRAY };
+ private static final Type[] ARG_TYPES_LUAVALUE_STRINGARRAY = { TYPE_LUAVALUE, TYPE_STRINGARRAY };
// names, arg types for main prototype classes
private static final String[] SUPER_NAME_N = { STR_FUNC0, STR_FUNC1, STR_FUNC2, STR_FUNC3, STR_FUNCV, };
@@ -257,7 +261,7 @@ public class JavaBuilder {
}
}
- public byte[] completeClass() {
+ public byte[] completeClass(boolean genmain) {
// add class initializer
if ( ! init.isEmpty() ) {
@@ -303,6 +307,26 @@ public class JavaBuilder {
main.dispose();
}
+ // add main function so class is invokable from the java command line
+ if (genmain) {
+ MethodGen mg = new MethodGen( Constants.ACC_PUBLIC | Constants.ACC_STATIC, // access flags
+ Type.VOID, // return type
+ ARG_TYPES_STRINGARRAY, // argument types
+ new String[] { "arg" }, // arg names
+ "main",
+ classname, // method, defining class
+ main, cp);
+ append(factory.createNew(classname));
+ append(InstructionConstants.DUP);
+ append(factory.createInvoke(classname, Constants.CONSTRUCTOR_NAME, Type.VOID, ARG_TYPES_NONE, Constants.INVOKESPECIAL));
+ append(new ALOAD(0));
+ append(factory.createInvoke(STR_JSEPLATFORM, "luaMain", Type.VOID, ARG_TYPES_LUAVALUE_STRINGARRAY, Constants.INVOKESTATIC));
+ append(InstructionConstants.RETURN);
+ mg.setMaxStack();
+ cg.addMethod(mg.getMethod());
+ main.dispose();
+ }
+
// convert to class bytes
try {
diff --git a/src/jse/org/luaj/vm2/luajc/JavaGen.java b/src/jse/org/luaj/vm2/luajc/JavaGen.java
index ab493348..4e2d2bd6 100644
--- a/src/jse/org/luaj/vm2/luajc/JavaGen.java
+++ b/src/jse/org/luaj/vm2/luajc/JavaGen.java
@@ -37,11 +37,11 @@ public class JavaGen {
public final byte[] bytecode;
public final JavaGen[] inners;
- public JavaGen( Prototype p, String classname, String filename ) {
- this( new ProtoInfo(p,classname), classname, filename );
+ public JavaGen( Prototype p, String classname, String filename, boolean genmain ) {
+ this( new ProtoInfo(p,classname), classname, filename, genmain );
}
- private JavaGen( ProtoInfo pi, String classname, String filename ) {
+ private JavaGen( ProtoInfo pi, String classname, String filename, boolean genmain ) {
this.classname = classname;
// build this class
@@ -51,14 +51,14 @@ public class JavaGen {
LocVars l = pi.prototype.locvars[i];
builder.setVarStartEnd(i, l.startpc, l.endpc, l.varname.tojstring());
}
- this.bytecode = builder.completeClass();
+ this.bytecode = builder.completeClass(genmain);
// build sub-prototypes
if ( pi.subprotos != null ) {
int n = pi.subprotos.length;
inners = new JavaGen[n];
for ( int i=0; i