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) ) +