fix tail call return value processing
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
62
src/test/res/tailcall.lua
Normal 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)
|
||||||
@@ -1 +1 @@
|
|||||||
version: 0.38
|
version: 0.39
|
||||||
|
|||||||
Reference in New Issue
Block a user