Fix load(func) when mutiple string fragments are supplied by calls to func

This commit is contained in:
James Roseborough
2012-01-21 17:36:03 +00:00
parent 26ed1ef392
commit c46ee6b9bd
4 changed files with 38 additions and 15 deletions

View File

@@ -733,6 +733,7 @@ and LuaForge:
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li> <li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
<li>Fix lua command vararg values passed into main script to match what is in global arg table </li> <li>Fix lua command vararg values passed into main script to match what is in global arg table </li>
<li>Add arithmetic metatag processing when left hand side is a number and right hand side has metatable </li> <li>Add arithmetic metatag processing when left hand side is a number and right hand side has metatable </li>
<li>Fix load(func) when mutiple string fragments are supplied by calls to func </li>
</ul></td></tr> </ul></td></tr>
</table></td></tr></table> </table></td></tr></table>

View File

@@ -413,28 +413,26 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
private static class StringInputStream extends InputStream { private static class StringInputStream extends InputStream {
LuaValue func; final LuaValue func;
byte[] bytes; byte[] bytes;
int offset; int offset, remaining = 0;
StringInputStream(LuaValue func) { StringInputStream(LuaValue func) {
this.func = func; this.func = func;
} }
public int read() throws IOException { public int read() throws IOException {
if ( func == null ) return -1; if ( remaining <= 0 ) {
if ( bytes == null ) {
LuaValue s = func.call(); LuaValue s = func.call();
if ( s.isnil() ) { if ( s.isnil() )
func = null; return -1;
bytes = null; LuaString ls = s.strvalue();
bytes = ls.m_bytes;
offset = ls.m_offset;
remaining = ls.m_length;
if (remaining <= 0)
return -1; return -1;
} }
bytes = s.tojstring().getBytes(); --remaining;
offset = 0;
}
if ( offset >= bytes.length )
return -1;
return bytes[offset++]; return bytes[offset++];
} }
} }
} }

View File

@@ -95,6 +95,23 @@ public class OrphanedThreadTest extends TestCase {
doTest(LuaValue.TRUE, LuaValue.ZERO); 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 { private void doTest(LuaValue status2, LuaValue value2) throws Exception {
luathread = new LuaThread(function, env); luathread = new LuaThread(function, env);
luathr_ref = new WeakReference(luathread); luathr_ref = new WeakReference(luathread);
@@ -103,11 +120,11 @@ public class OrphanedThreadTest extends TestCase {
// resume two times // resume two times
Varargs a = luathread.resume(LuaValue.valueOf("foo")); Varargs a = luathread.resume(LuaValue.valueOf("foo"));
assertEquals(LuaValue.TRUE, a.arg1());
assertEquals(LuaValue.ONE, a.arg(2)); assertEquals(LuaValue.ONE, a.arg(2));
assertEquals(LuaValue.TRUE, a.arg1());
a = luathread.resume(LuaValue.valueOf("bar")); a = luathread.resume(LuaValue.valueOf("bar"));
assertEquals(status2, a.arg1());
assertEquals(value2, a.arg(2)); assertEquals(value2, a.arg(2));
assertEquals(status2, a.arg1());
// drop strong references // drop strong references
luathread = null; luathread = null;

View File

@@ -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 for k,v in ipairs({[30]='30',[20]='20'}) do print('ipairs5',k,v)end
-- load -- 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 -- loadfile
-- loadstring -- loadstring
local lst = "print(3+4); return 8" 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(badfunc,badfunc))', pcall(xpcall,badfunc,badfunc) )
print( 'pcall(xpcall(wrappedbad))', pcall(xpcall,wrappedbad) ) print( 'pcall(xpcall(wrappedbad))', pcall(xpcall,wrappedbad) )
print( 'xpcall(wrappedbad,errfunc)', xpcall(wrappedbad,errfunc) ) print( 'xpcall(wrappedbad,errfunc)', xpcall(wrappedbad,errfunc) )