Fix to tailcall processing.
This commit is contained in:
@@ -101,6 +101,10 @@ public class LuaClosure extends LuaFunction {
|
||||
}
|
||||
|
||||
public final Varargs invoke(Varargs varargs) {
|
||||
return oninvoke( varargs ).eval();
|
||||
}
|
||||
|
||||
final Varargs oninvoke(Varargs varargs) {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
for ( int i=0; i<p.numparams; i++ )
|
||||
@@ -108,6 +112,7 @@ public class LuaClosure extends LuaFunction {
|
||||
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
||||
}
|
||||
|
||||
|
||||
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
|
||||
// loop through instructions
|
||||
int i,a,b,c,pc=0,top=0;
|
||||
|
||||
@@ -71,6 +71,20 @@ public class LuaError extends RuntimeException {
|
||||
public LuaError(String message) {
|
||||
super( errorHook( message ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message message to supply
|
||||
* @param level where to supply line info from in call stack
|
||||
*/
|
||||
public LuaError(String message, int level) {
|
||||
super( errorHook( addFileLine( message, level ) ) );
|
||||
}
|
||||
|
||||
/** Add file and line info to a message */
|
||||
private static String addFileLine( String message, int level ) {
|
||||
LuaFunction f = LuaThread.getCallstackFunction(level);
|
||||
return f!=null? f+": "+message: message;
|
||||
}
|
||||
|
||||
/** Get the message, including source line info if there is any */
|
||||
public String getMessage() {
|
||||
|
||||
@@ -32,13 +32,15 @@ public class TailcallVarargs extends Varargs {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
private void eval() {
|
||||
public Varargs eval() {
|
||||
TailcallVarargs nextcall = this;
|
||||
do {
|
||||
LuaValue func = nextcall.func;
|
||||
Varargs args = nextcall.args;
|
||||
nextcall = null;
|
||||
Varargs r = func.invoke(args);
|
||||
Varargs r = func.isclosure()?
|
||||
((LuaClosure) func).oninvoke(args):
|
||||
func.invoke(args);
|
||||
|
||||
if (r instanceof TailcallVarargs)
|
||||
nextcall = (TailcallVarargs)r;
|
||||
@@ -46,6 +48,7 @@ public class TailcallVarargs extends Varargs {
|
||||
this.result = r;
|
||||
|
||||
} while (nextcall != null);
|
||||
return result;
|
||||
}
|
||||
|
||||
public LuaValue arg( int i ) {
|
||||
|
||||
@@ -45,6 +45,12 @@ public abstract class Varargs {
|
||||
* @return Value
|
||||
*/
|
||||
abstract public LuaValue arg1();
|
||||
|
||||
/**
|
||||
* Evaluate any pending tail call and return result
|
||||
* @return the evaluated tail call result
|
||||
*/
|
||||
public Varargs eval() { return this; }
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// utilities to get specific arguments and type-check them.
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.io.PrintStream;
|
||||
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaThread;
|
||||
@@ -162,7 +161,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
}
|
||||
return NIL;
|
||||
case 1: // "error", // ( message [,level] ) -> ERR
|
||||
throw new LuaError( arg1.isnil()? null: arg1.toString() );
|
||||
throw new LuaError( arg1.isnil()? null: arg1.toString(), arg2.optint(1) );
|
||||
case 2: // "rawequal", // (v1, v2) -> boolean
|
||||
return valueOf(arg1 == arg2);
|
||||
case 3: { // "setfenv", // (f, table) -> void
|
||||
@@ -347,7 +346,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
private Varargs loadFile(String filename) throws IOException {
|
||||
public static Varargs loadFile(String filename) throws IOException {
|
||||
InputStream is = FINDER.findResource(filename);
|
||||
if ( is == null )
|
||||
return varargsOf(NIL, valueOf("not found: "+filename));
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2.lib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
@@ -306,11 +307,6 @@ public class PackageLib extends OneArgFunction {
|
||||
String name = args.checkString(1);
|
||||
InputStream is = null;
|
||||
|
||||
// try to use loadfile for the file
|
||||
LuaValue loadfile = env.get(_LOADFILE);
|
||||
if ( ! loadfile.isfunction() )
|
||||
return valueOf("loadfile is not a function" );
|
||||
|
||||
|
||||
// get package path
|
||||
LuaValue pp = PACKAGE.get(_PATH);
|
||||
@@ -340,7 +336,13 @@ public class PackageLib extends OneArgFunction {
|
||||
}
|
||||
|
||||
// try loading the file
|
||||
Varargs v = loadfile.invoke(valueOf(filename));
|
||||
Varargs v;
|
||||
try {
|
||||
v = BaseLib.loadFile(filename);
|
||||
} catch ( IOException ioe ) {
|
||||
v = varargsOf(NIL, valueOf(ioe.getMessage()));
|
||||
|
||||
}
|
||||
if ( v.arg1().isfunction() )
|
||||
return v.arg1();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user