Fix varargs handling in code generator.

This commit is contained in:
James Roseborough
2010-07-24 00:24:59 +00:00
parent bd8775984e
commit ea931c1438
4 changed files with 35 additions and 21 deletions

View File

@@ -49,10 +49,10 @@ public class LuaTable extends LuaValue {
int nl = (lastarg!=null? lastarg.narg(): 0);
presize(nu+nl, nn-(nn>>1));
for ( int i=0; i<nu; i++ )
rawset(i+1,unnamed[i].optvalue(null));
rawset(i+1,unnamed[i]);
if ( lastarg != null )
for ( int i=1,n=lastarg.narg(); i<=n; ++i )
rawset(nu+i,lastarg.arg(i).optvalue(null));
rawset(nu+i,lastarg.arg(i));
for ( int i=0; i<nn; i+=2 )
if (!named[i+1].isnil())
rawset(named[i], named[i+1]);

View File

@@ -4,6 +4,7 @@ import java.util.List;
import org.luaj.vm2.ast.Exp.NameExp;
import org.luaj.vm2.ast.Exp.VarExp;
import org.luaj.vm2.ast.Exp.VarargsExp;
import org.luaj.vm2.ast.NameScope.NamedVariable;
import org.luaj.vm2.ast.Stat.Assign;
import org.luaj.vm2.ast.Stat.FuncDef;
@@ -77,13 +78,6 @@ public class NameResolver extends Visitor {
super.visit(stat);
}
protected NamedVariable resolveNameReference(Name name) {
NamedVariable v = scope.find(name.name);
if ( v.isLocal() && scope.functionNestingCount != v.definingScope.functionNestingCount )
v.isupvalue = true;
return v;
}
public void visit(Assign stat) {
super.visit(stat);
for ( VarExp v : stat.vars )
@@ -98,6 +92,8 @@ public class NameResolver extends Visitor {
public void visit(ParList pars) {
if ( pars.names != null )
defineLocalVars(pars.names);
if ( pars.isvararg )
scope.define("arg");
super.visit(pars);
}
@@ -109,4 +105,11 @@ public class NameResolver extends Visitor {
protected void defineLocalVar(Name name) {
name.variable = scope.define(name.name);
}
protected NamedVariable resolveNameReference(Name name) {
NamedVariable v = scope.find(name.name);
if ( v.isLocal() && scope.functionNestingCount != v.definingScope.functionNestingCount )
v.isupvalue = true;
return v;
}
}

View File

@@ -56,6 +56,7 @@ import org.luaj.vm2.ast.Exp.ParensExp;
import org.luaj.vm2.ast.Exp.UnopExp;
import org.luaj.vm2.ast.Exp.VarExp;
import org.luaj.vm2.ast.Exp.VarargsExp;
import org.luaj.vm2.ast.NameScope.NamedVariable;
import org.luaj.vm2.ast.Stat.Assign;
import org.luaj.vm2.ast.Stat.Break;
import org.luaj.vm2.ast.Stat.FuncCallStat;
@@ -134,7 +135,7 @@ public class JavaCodeGen {
outl("import org.luaj.vm2.*;");
outl("import org.luaj.vm2.lib.*;");
outb("public class "+classname+" extends VarArgFunction {");
outl("public Varargs invoke(Varargs arg) {");
outl("public Varargs invoke(Varargs $arg) {");
addindent();
javascope = JavaScope.newJavaScope( chunk );
writeBodyBlock(chunk.block);
@@ -514,19 +515,19 @@ public class JavaCodeGen {
if ( n>=0 && n<=1 && m<=3 && ! body.parlist.isvararg ) {
switch ( m ) {
case 0:
outr("new ZeroArgFunction() {");
outr("new ZeroArgFunction(env) {");
addindent();
outb("public LuaValue call() {");
break;
case 1:
outr("new OneArgFunction() {");
outr("new OneArgFunction(env) {");
addindent();
outb("public LuaValue call("
+declareArg(body.parlist.names.get(0))+") {");
assignArg(body.parlist.names.get(0));
break;
case 2:
outr("new TwoArgFunction() {");
outr("new TwoArgFunction(env) {");
addindent();
outb("public LuaValue call("
+declareArg(body.parlist.names.get(0))+","
@@ -535,7 +536,7 @@ public class JavaCodeGen {
assignArg(body.parlist.names.get(1));
break;
case 3:
outr("new ThreeArgFunction() {");
outr("new ThreeArgFunction(env) {");
addindent();
outb("public LuaValue call("
+declareArg(body.parlist.names.get(0))+","
@@ -547,20 +548,24 @@ public class JavaCodeGen {
break;
}
} else {
outr("new VarArgFunction() {");
outr("new VarArgFunction(env) {");
addindent();
outb("public Varargs invoke(Varargs arg) {");
outb("public Varargs invoke(Varargs $arg) {");
if ( body.parlist.isvararg ) {
NamedVariable arg = body.scope.find("arg");
javascope.setJavaName(arg,"arg");
String value = "LuaValue.tableOf($arg,"+(m+1)+")";
outl( arg.isupvalue? "final LuaValue[] arg = {"+value+"};": "LuaValue arg = "+value+";" );
}
for ( int i=0; i<m; i++ ) {
Name name = body.parlist.names.get(i);
String argname = javascope.getJavaName(name.variable);
String value = i>0? "arg.arg("+(i+1)+")": "arg.arg1()";
String value = i>0? "$arg.arg("+(i+1)+")": "$arg.arg1()";
if ( name.variable.isupvalue )
outl( "final LuaValue[] "+argname+" = {"+value+"};" );
else
outl( "LuaValue "+argname+" = "+value+";" );
}
if ( body.parlist.isvararg && m > 0 )
outl( "arg = arg.subargs("+(m+1)+");" );
}
writeBodyBlock(body.block);
oute("}");

View File

@@ -43,7 +43,7 @@ public class JavaScope extends NameScope {
private static final String[] specials = {
// keywords used by our code generator
"name", "opcode", "env", "arg",
"name", "opcode", "env", // "arg",
// java keywords
"abstract", "continue", "for", "new", "switch",
@@ -112,6 +112,11 @@ public class JavaScope extends NameScope {
}
}
public void setJavaName(NamedVariable 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) )
@@ -169,4 +174,5 @@ public class JavaScope extends NameScope {
super.visit(exp);
}
}
}