diff --git a/README.html b/README.html
index 4826fb1a..67c794c6 100644
--- a/README.html
+++ b/README.html
@@ -733,6 +733,7 @@ and LuaForge:
Improve coroutine state logic including let unreferenced coroutines be garbage collected
Fix lua command vararg values passed into main script to match what is in global arg table
Add arithmetic metatag processing when left hand side is a number and right hand side has metatable
+Fix load(func) when mutiple string fragments are supplied by calls to func
diff --git a/src/core/org/luaj/vm2/lib/BaseLib.java b/src/core/org/luaj/vm2/lib/BaseLib.java
index b2172529..f70f7e52 100644
--- a/src/core/org/luaj/vm2/lib/BaseLib.java
+++ b/src/core/org/luaj/vm2/lib/BaseLib.java
@@ -413,28 +413,26 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
private static class StringInputStream extends InputStream {
- LuaValue func;
+ final LuaValue func;
byte[] bytes;
- int offset;
+ int offset, remaining = 0;
StringInputStream(LuaValue func) {
this.func = func;
}
public int read() throws IOException {
- if ( func == null ) return -1;
- if ( bytes == null ) {
+ if ( remaining <= 0 ) {
LuaValue s = func.call();
- if ( s.isnil() ) {
- func = null;
- bytes = null;
+ if ( s.isnil() )
+ return -1;
+ LuaString ls = s.strvalue();
+ bytes = ls.m_bytes;
+ offset = ls.m_offset;
+ remaining = ls.m_length;
+ if (remaining <= 0)
return -1;
- }
- bytes = s.tojstring().getBytes();
- offset = 0;
}
- if ( offset >= bytes.length )
- return -1;
+ --remaining;
return bytes[offset++];
-
}
}
}
diff --git a/test/junit/org/luaj/vm2/OrphanedThreadTest.java b/test/junit/org/luaj/vm2/OrphanedThreadTest.java
index 94244239..2c801abb 100644
--- a/test/junit/org/luaj/vm2/OrphanedThreadTest.java
+++ b/test/junit/org/luaj/vm2/OrphanedThreadTest.java
@@ -95,6 +95,23 @@ public class OrphanedThreadTest extends TestCase {
doTest(LuaValue.TRUE, LuaValue.ZERO);
}
+ public void testCollectOrphanedLoadCloasureThread() throws Exception {
+ String script =
+ "t = { \"print \", \"'hello, \", \"world'\", }\n" +
+ "i = 0\n" +
+ "arg = ...\n" +
+ "f = function()\n" +
+ " i = i + 1\n" +
+ " print('in load-closure, arg is', arg, 'next is', t[i])\n" +
+ " arg = coroutine.yield(1)\n" +
+ " return t[i]\n" +
+ "end\n" +
+ "load(f)()\n";
+ LuaC.install();
+ function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", env);
+ doTest(LuaValue.TRUE, LuaValue.ONE);
+ }
+
private void doTest(LuaValue status2, LuaValue value2) throws Exception {
luathread = new LuaThread(function, env);
luathr_ref = new WeakReference(luathread);
@@ -103,11 +120,11 @@ public class OrphanedThreadTest extends TestCase {
// resume two times
Varargs a = luathread.resume(LuaValue.valueOf("foo"));
- assertEquals(LuaValue.TRUE, a.arg1());
assertEquals(LuaValue.ONE, a.arg(2));
+ assertEquals(LuaValue.TRUE, a.arg1());
a = luathread.resume(LuaValue.valueOf("bar"));
- assertEquals(status2, a.arg1());
assertEquals(value2, a.arg(2));
+ assertEquals(status2, a.arg1());
// drop strong references
luathread = null;
diff --git a/test/lua/baselib.lua b/test/lua/baselib.lua
index a4e893fb..dae00527 100644
--- a/test/lua/baselib.lua
+++ b/test/lua/baselib.lua
@@ -52,6 +52,12 @@ for k,v in ipairs({aa='aaa',bb='bbb','one','two'}) do print('ipairs4',k,v)end
for k,v in ipairs({[30]='30',[20]='20'}) do print('ipairs5',k,v)end
-- load
+t = { "print ", "'table ", "loaded'", "", " print'after empty string'" }
+i = 0
+f = function() i = i + 1; return t[i]; end
+c,e = load(f)
+if c then print('load: ', pcall(c)) else print('load failed:', e) end
+
-- loadfile
-- loadstring
local lst = "print(3+4); return 8"
@@ -303,3 +309,4 @@ print( 'pcall(xpcall(badfunc,errfunc))', pcall(xpcall,badfunc,errfunc) )
print( 'pcall(xpcall(badfunc,badfunc))', pcall(xpcall,badfunc,badfunc) )
print( 'pcall(xpcall(wrappedbad))', pcall(xpcall,wrappedbad) )
print( 'xpcall(wrappedbad,errfunc)', xpcall(wrappedbad,errfunc) )
+