summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbaselib.c7
-rw-r--r--testes/nextvar.lua21
2 files changed, 27 insertions, 1 deletions
diff --git a/lbaselib.c b/lbaselib.c
index 83ad306d..fd6687e6 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -261,6 +261,11 @@ static int luaB_next (lua_State *L) {
}
+static int pairscont (lua_State *L, int status, lua_KContext k) {
+ (void)L; (void)status; (void)k; /* unused */
+ return 3;
+}
+
static int luaB_pairs (lua_State *L) {
luaL_checkany(L, 1);
if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */
@@ -270,7 +275,7 @@ static int luaB_pairs (lua_State *L) {
}
else {
lua_pushvalue(L, 1); /* argument 'self' to metamethod */
- lua_call(L, 1, 3); /* get 3 values from metamethod */
+ lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */
}
return 3;
}
diff --git a/testes/nextvar.lua b/testes/nextvar.lua
index 29cb05d5..076f6361 100644
--- a/testes/nextvar.lua
+++ b/testes/nextvar.lua
@@ -764,4 +764,25 @@ for k,v in ipairs(a) do
end
assert(i == a.n)
+
+-- testing yield inside __pairs
+do
+ local t = setmetatable({10, 20, 30}, {__pairs = function (t)
+ local inc = coroutine.yield()
+ return function (t, i)
+ if i > 1 then return i - inc, t[i - inc] else return nil end
+ end, t, #t + 1
+ end})
+
+ local res = {}
+ local co = coroutine.wrap(function ()
+ for i,p in pairs(t) do res[#res + 1] = p end
+ end)
+
+ co() -- start coroutine
+ co(1) -- continue after yield
+ assert(res[1] == 30 and res[2] == 20 and res[3] == 10 and #res == 3)
+
+end
+
print"OK"