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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * 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.io.InputStreamReader;
import java.util.Vector; import java.util.Vector;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState; import org.luaj.vm2.LoadState;
import org.luaj.vm2.Lua; import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Print; 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.jse.JsePlatform; import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.luajc.LuaJC; import org.luaj.vm2.luajc.LuaJC;
/** /**
* lua command for use in java se environments. * lua command for use in JSE environments.
*/ */
public class lua { 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 = private static final String usage =
"usage: java -cp luaj-jse.jar lua [options] [script [args]].\n" + "usage: java -cp luaj-jse.jar lua [options] [script [args]].\n" +
@@ -56,6 +55,7 @@ public class lua {
" -v show version information\n" + " -v show version information\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 print the prototype\n" +
" -- stop handling options\n" + " -- stop handling options\n" +
" - execute stdin and stop handling options"; " - execute stdin and stop handling options";
@@ -64,7 +64,8 @@ public class lua {
System.exit(-1); System.exit(-1);
} }
private static LuaValue _G; private static Globals _G;
private static boolean print = false;
public static void main( String[] args ) throws IOException { public static void main( String[] args ) throws IOException {
@@ -73,7 +74,6 @@ public class lua {
boolean versioninfo = false; boolean versioninfo = false;
boolean processing = true; boolean processing = true;
boolean nodebug = false; boolean nodebug = false;
boolean print = false;
boolean luajc = false; boolean luajc = false;
Vector libs = null; Vector libs = null;
try { try {
@@ -110,6 +110,9 @@ public class lua {
case 'n': case 'n':
nodebug = true; nodebug = true;
break; break;
case 'p':
print = true;
break;
case '-': case '-':
if ( args[i].length() > 2 ) if ( args[i].length() > 2 )
usageExit(); usageExit();
@@ -190,6 +193,8 @@ public class lua {
} finally { } finally {
script.close(); script.close();
} }
if (print && c.isclosure())
Print.print(c.checkclosure().p);
Varargs scriptargs = setGlobalArg(chunkname, args, firstarg, _G); Varargs scriptargs = setGlobalArg(chunkname, args, firstarg, _G);
c.invoke( scriptargs ); c.invoke( scriptargs );
} catch ( Exception e ) { } 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -56,8 +56,8 @@ public class luajc {
System.exit(-1); System.exit(-1);
} }
private String srcdir = null; private String srcdir = ".";
private String destdir = null; private String destdir = ".";
private boolean genmain = false; private boolean genmain = false;
private boolean recurse = false; private boolean recurse = false;
private boolean verbose = false; private boolean verbose = false;

View File

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

View File

@@ -2,8 +2,11 @@ package org.luaj.vm2.luajc;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Hashtable;
import java.util.Vector;
import org.luaj.vm2.Lua; import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.Print; import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype; import org.luaj.vm2.Prototype;
import org.luaj.vm2.Upvaldesc; import org.luaj.vm2.Upvaldesc;
@@ -411,12 +414,13 @@ public class ProtoInfo {
int n = code.length; int n = code.length;
// propogate to inner prototypes // propogate to inner prototypes
String[] names = findInnerprotoNames();
for ( int pc=0; pc<n; pc++ ) { for ( int pc=0; pc<n; pc++ ) {
if ( Lua.GET_OPCODE(code[pc]) == Lua.OP_CLOSURE ) { if ( Lua.GET_OPCODE(code[pc]) == Lua.OP_CLOSURE ) {
int bx = Lua.GETARG_Bx(code[pc]); int bx = Lua.GETARG_Bx(code[pc]);
Prototype newp = prototype.p[bx]; Prototype newp = prototype.p[bx];
UpvalInfo[] newu = new UpvalInfo[newp.upvalues.length]; 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 ) { for ( int j=0; j<newp.upvalues.length; ++j ) {
Upvaldesc u = newp.upvalues[j]; Upvaldesc u = newp.upvalues[j];
newu[j] = u.instack? findOpenUp(pc,u.idx) : upvals[u.idx]; 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; upvals[Lua.GETARG_B(code[pc])].rw = true;
} }
} }
private UpvalInfo findOpenUp(int pc, int slot) { private UpvalInfo findOpenUp(int pc, int slot) {
if ( openups[slot] == null ) if ( openups[slot] == null )
openups[slot] = new UpvalInfo[prototype.code.length]; openups[slot] = new UpvalInfo[prototype.code.length];
@@ -470,4 +473,63 @@ public class ProtoInfo {
public boolean isReadWriteUpvalue(UpvalInfo u) { public boolean isReadWriteUpvalue(UpvalInfo u) {
return u.rw; 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();
}
} }