fix tail call return value processing

This commit is contained in:
James Roseborough
2008-06-14 14:40:49 +00:00
parent a9b8cc5655
commit 59b75d5ce0
4 changed files with 366 additions and 296 deletions

View File

@@ -735,8 +735,8 @@ public class LuaState extends Lua {
// adjustTop only for case when call was completed // adjustTop only for case when call was completed
// and number of args > 0. If call completed but // and number of args > 0. If call completed but
// c == 0, leave top to point to end of results // c == 0, leave top to point to end of results
if (this.nresults >= 0) if (ci.nresults >= 0)
luaV_adjusttop(base + nresults); luaV_adjusttop(base + ci.nresults);
// force restore of base, etc. // force restore of base, etc.
return; return;

View File

@@ -1,4 +1,5 @@
package org.luaj.vm; package org.luaj.vm;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -10,10 +11,8 @@ import org.luaj.TestPlatform;
import org.luaj.compiler.LuaC; import org.luaj.compiler.LuaC;
import org.luaj.lib.BaseLib; import org.luaj.lib.BaseLib;
public class LuaJTest extends TestCase { public class LuaJTest extends TestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
Platform.setInstance(new TestPlatform()); Platform.setInstance(new TestPlatform());
@@ -99,7 +98,6 @@ public class LuaJTest extends TestCase {
runTest("manylocals"); runTest("manylocals");
} }
public void testMathLib() throws IOException, InterruptedException { public void testMathLib() throws IOException, InterruptedException {
runTest("mathlib"); runTest("mathlib");
} }
@@ -156,6 +154,10 @@ public class LuaJTest extends TestCase {
runTest("table"); runTest("table");
} }
public void testTailcall() throws IOException, InterruptedException {
runTest("tailcall");
}
public void testType() throws IOException, InterruptedException { public void testType() throws IOException, InterruptedException {
runTest("type"); runTest("type");
} }
@@ -177,7 +179,8 @@ public class LuaJTest extends TestCase {
} }
// */ // */
private void runTest( String testName ) throws IOException, InterruptedException { private void runTest(String testName) throws IOException,
InterruptedException {
// new lua state // new lua state
LuaState state = Platform.newLuaState(); LuaState state = Platform.newLuaState();
@@ -208,8 +211,10 @@ public class LuaJTest extends TestCase {
} }
} }
protected LPrototype loadScriptResource( LuaState state, String name ) throws IOException { protected LPrototype loadScriptResource(LuaState state, String name)
InputStream script = getClass().getResourceAsStream( "/"+name+".luac" ); throws IOException {
InputStream script = getClass().getResourceAsStream(
"/" + name + ".luac");
if (script == null) { if (script == null) {
script = getClass().getResourceAsStream("/" + name + ".lua"); script = getClass().getResourceAsStream("/" + name + ".lua");
if (script == null) { if (script == null) {
@@ -226,7 +231,8 @@ public class LuaJTest extends TestCase {
} }
} }
private String getExpectedOutput( final String testName ) throws IOException, InterruptedException { private String getExpectedOutput(final String testName) throws IOException,
InterruptedException {
String expectedOutputName = "/" + testName + "-expected.out"; String expectedOutputName = "/" + testName + "-expected.out";
InputStream is = getClass().getResourceAsStream(expectedOutputName); InputStream is = getClass().getResourceAsStream(expectedOutputName);
if (is != null) { if (is != null) {
@@ -237,7 +243,8 @@ public class LuaJTest extends TestCase {
} }
} else { } else {
InputStream script; InputStream script;
// script = getClass().getResourceAsStream( "/" + testName + ".luac" ); // script = getClass().getResourceAsStream( "/" + testName + ".luac"
// );
// if ( script == null ) { // if ( script == null ) {
script = getClass().getResourceAsStream("/" + testName + ".lua"); script = getClass().getResourceAsStream("/" + testName + ".lua");
if (script == null) { if (script == null) {
@@ -252,7 +259,8 @@ public class LuaJTest extends TestCase {
} }
} }
private String collectProcessOutput( String[] cmd, final InputStream input ) throws IOException, InterruptedException { private String collectProcessOutput(String[] cmd, final InputStream input)
throws IOException, InterruptedException {
Runtime r = Runtime.getRuntime(); Runtime r = Runtime.getRuntime();
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final Process p = r.exec(cmd); final Process p = r.exec(cmd);

62
src/test/res/tailcall.lua Normal file
View File

@@ -0,0 +1,62 @@
function a()
return pcall( function() end )
end
function b()
return pcall( function() print 'b' end )
end
function c()
return pcall( function() return 'c' end )
end
print( pcall( a ) )
print( pcall( b ) )
print( pcall( c ) )
local function sum(...)
local s = 0
for i,v in ipairs({...}) do
s = s + v
end
return s
end
local function f1(n,a,b,c)
local a = a or 0
local b = b or 0
local c = c or 0
if n <= 0 then
return a,a+b,a+b+c
end
return f1(n-1,a,a+b,a+b+c)
end
local function f2(n,...)
if n <= 0 then
return sum(...)
end
return f2(n-1,n,...)
end
local function f3(n,...)
if n <= 0 then
return sum(...)
end
return pcall(f3,n-1,n,...)
end
local function all(f)
for n=0,3 do
t = {}
for m=1,5 do
print( pcall( f, n, unpack(t)) )
t[m] = m
end
end
end
all(f1)
all(f2)
all(f3)

View File

@@ -1 +1 @@
version: 0.38 version: 0.39