Let generated code have class names that match variable names used in function creation.

This commit is contained in:
James Roseborough
2012-10-05 04:26:25 +00:00
parent 1a4eb0e3c7
commit 447c7f9850
4 changed files with 81 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009 Luaj.org. All rights reserved.
* Copyright (c) 2009-2012 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
@@ -28,24 +28,23 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Vector;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
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.luajc.LuaJC;
/**
* lua command for use in java se environments.
* lua command for use in JSE environments.
*/
public class lua {
private static final String version = Lua._VERSION + "Copyright (c) 2012 Luaj.org.org";
private static final String version = Lua._VERSION + " Copyright (c) 2012 Luaj.org.org";
private static final String usage =
"usage: java -cp luaj-jse.jar lua [options] [script [args]].\n" +
@@ -56,6 +55,7 @@ public class lua {
" -v show version information\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 print the prototype\n" +
" -- stop handling options\n" +
" - execute stdin and stop handling options";
@@ -64,7 +64,8 @@ public class lua {
System.exit(-1);
}
private static LuaValue _G;
private static Globals _G;
private static boolean print = false;
public static void main( String[] args ) throws IOException {
@@ -73,7 +74,6 @@ public class lua {
boolean versioninfo = false;
boolean processing = true;
boolean nodebug = false;
boolean print = false;
boolean luajc = false;
Vector libs = null;
try {
@@ -110,6 +110,9 @@ public class lua {
case 'n':
nodebug = true;
break;
case 'p':
print = true;
break;
case '-':
if ( args[i].length() > 2 )
usageExit();
@@ -190,6 +193,8 @@ public class lua {
} finally {
script.close();
}
if (print && c.isclosure())
Print.print(c.checkclosure().p);
Varargs scriptargs = setGlobalArg(chunkname, args, firstarg, _G);
c.invoke( scriptargs );
} catch ( Exception e ) {

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009 Luaj.org. All rights reserved.
* Copyright (c) 2009-2012 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
@@ -56,8 +56,8 @@ public class luajc {
System.exit(-1);
}
private String srcdir = null;
private String destdir = null;
private String srcdir = ".";
private String destdir = ".";
private boolean genmain = false;
private boolean recurse = false;
private boolean verbose = false;

View File

@@ -58,16 +58,12 @@ public class JavaGen {
int n = pi.subprotos.length;
inners = new JavaGen[n];
for ( int i=0; i<n; i++ )
inners[i] = new JavaGen(pi.subprotos[i], closureName(classname,i), filename, false);
inners[i] = new JavaGen(pi.subprotos[i], pi.subprotos[i].name, filename, false);
} else {
inners = null;
}
}
private String closureName(String classname, int subprotoindex) {
return classname+"$"+subprotoindex;
}
private void scanInstructions(ProtoInfo pi, String classname, JavaBuilder builder) {
Prototype p = pi.prototype;
int vresultbase = -1;
@@ -395,7 +391,7 @@ public class JavaGen {
{
Prototype newp = p.p[bx];
int nup = newp.upvalues.length;
String protoname = closureName(classname, bx);
String protoname = pi.subprotos[bx].name;
builder.closureCreate( protoname );
if ( nup > 0 )
builder.dup();

View File

@@ -2,8 +2,11 @@ package org.luaj.vm2.luajc;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Hashtable;
import java.util.Vector;
import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.Upvaldesc;
@@ -411,12 +414,13 @@ public class ProtoInfo {
int n = code.length;
// propogate to inner prototypes
String[] names = findInnerprotoNames();
for ( int pc=0; pc<n; pc++ ) {
if ( Lua.GET_OPCODE(code[pc]) == Lua.OP_CLOSURE ) {
int bx = Lua.GETARG_Bx(code[pc]);
Prototype newp = prototype.p[bx];
UpvalInfo[] newu = new UpvalInfo[newp.upvalues.length];
String newname = name + "$" + bx;
String newname = name + "$" + names[bx];
for ( int j=0; j<newp.upvalues.length; ++j ) {
Upvaldesc u = newp.upvalues[j];
newu[j] = u.instack? findOpenUp(pc,u.idx) : upvals[u.idx];
@@ -431,7 +435,6 @@ public class ProtoInfo {
upvals[Lua.GETARG_B(code[pc])].rw = true;
}
}
private UpvalInfo findOpenUp(int pc, int slot) {
if ( openups[slot] == null )
openups[slot] = new UpvalInfo[prototype.code.length];
@@ -470,4 +473,63 @@ public class ProtoInfo {
public boolean isReadWriteUpvalue(UpvalInfo u) {
return u.rw;
}
private String[] findInnerprotoNames() {
if (prototype.p.length <= 0)
return null;
// find all the prototype names
String[] names = new String[prototype.p.length];
Hashtable used = new Hashtable();
int[] code = prototype.code;
int n = code.length;
for ( int pc=0; pc<n; pc++ ) {
if ( Lua.GET_OPCODE(code[pc]) == Lua.OP_CLOSURE ) {
int bx = Lua.GETARG_Bx(code[pc]);
String name = null;
final int i = code[pc+1];
switch (Lua.GET_OPCODE(i)) {
case Lua.OP_SETTABLE:
case Lua.OP_SETTABUP: {
final int b = Lua.GETARG_B(i);
if (Lua.ISK(b))
name = prototype.k[b&0x0ff].tojstring();
break;
}
case Lua.OP_SETUPVAL: {
final int b = Lua.GETARG_B(i);
final LuaString s = prototype.upvalues[b].name;
if (s != null)
name = s.tojstring();
break;
}
default: // Local variable
final int a = Lua.GETARG_A(code[pc]);
final LuaString s = prototype.getlocalname(a+1, pc+1);
if (s != null)
name = s.tojstring();
break;
}
name = name != null? toJavaClassPart(name): String.valueOf(bx);
if (used.containsKey(name)) {
String basename = name;
int count = 1;
do {
name = basename + '$' + count++;
} while (used.containsKey(name));
}
used.put(name, Boolean.TRUE);
names[bx] = name;
}
}
return names;
}
private static String toJavaClassPart(String s) {
final int n = s.length();
StringBuffer sb = new StringBuffer(n);
for (int i = 0; i < n; ++i)
sb.append( Character.isJavaIdentifierPart(s.charAt(i)) ? s.charAt(i): "_" );
return sb.toString();
}
}