mirror of
https://github.com/lua/lua
synced 2024-11-29 08:03:13 +03:00
'lua_toclose' gets the index to be closed as an argument
Sometimes it is useful to mark to-be-closed an index that is not at the top of the stack (e.g., if the value to be closed came from a function call returning multiple values).
This commit is contained in:
parent
9eafe9c053
commit
5fda30b4f9
13
lapi.c
13
lapi.c
@ -1207,12 +1207,19 @@ LUA_API int lua_next (lua_State *L, int idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API void lua_toclose (lua_State *L) {
|
LUA_API void lua_toclose (lua_State *L, int idx) {
|
||||||
int nresults = L->ci->nresults;
|
int nresults;
|
||||||
luaF_newtbcupval(L, L->top - 1); /* create new to-be-closed upvalue */
|
StkId o;
|
||||||
|
lua_lock(L);
|
||||||
|
o = index2stack(L, idx);
|
||||||
|
nresults = L->ci->nresults;
|
||||||
|
api_check(L, L->openupval == NULL || uplevel(L->openupval) < o,
|
||||||
|
"there is an already marked index below");
|
||||||
|
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
|
||||||
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
|
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
|
||||||
L->ci->nresults = codeNresults(nresults); /* mark it */
|
L->ci->nresults = codeNresults(nresults); /* mark it */
|
||||||
lua_assert(hastocloseCfunc(L->ci->nresults));
|
lua_assert(hastocloseCfunc(L->ci->nresults));
|
||||||
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
2
ltests.c
2
ltests.c
@ -1551,7 +1551,7 @@ static struct X { int x; } x;
|
|||||||
return lua_yieldk(L1, nres, i, Cfunck);
|
return lua_yieldk(L1, nres, i, Cfunck);
|
||||||
}
|
}
|
||||||
else if EQ("toclose") {
|
else if EQ("toclose") {
|
||||||
lua_toclose(L);
|
lua_toclose(L, getnum);
|
||||||
}
|
}
|
||||||
else luaL_error(L, "unknown instruction %s", buff);
|
else luaL_error(L, "unknown instruction %s", buff);
|
||||||
}
|
}
|
||||||
|
2
lua.h
2
lua.h
@ -333,7 +333,7 @@ LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
|
|||||||
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
|
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
|
||||||
LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
|
LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
|
||||||
|
|
||||||
LUA_API void (lua_toclose) (lua_State *L);
|
LUA_API void (lua_toclose) (lua_State *L, int idx);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -985,18 +985,20 @@ do
|
|||||||
return x
|
return x
|
||||||
end
|
end
|
||||||
|
|
||||||
local a = T.testC([[
|
local a, b = T.testC([[
|
||||||
call 0 1 # create resource
|
call 0 1 # create resource
|
||||||
toclose # mark it to be closed
|
pushint 34
|
||||||
return 1
|
toclose -2 # mark call result to be closed
|
||||||
|
toclose -1 # mark number to be closed (will be ignored)
|
||||||
|
return 2
|
||||||
]], newresource)
|
]], newresource)
|
||||||
assert(a[1] == 11)
|
assert(a[1] == 11 and b == 34)
|
||||||
assert(#openresource == 0) -- was closed
|
assert(#openresource == 0) -- was closed
|
||||||
|
|
||||||
-- repeat the test, but calling function in a 'multret' context
|
-- repeat the test, but calling function in a 'multret' context
|
||||||
local a = {T.testC([[
|
local a = {T.testC([[
|
||||||
call 0 1 # create resource
|
call 0 1 # create resource
|
||||||
toclose # mark it to be closed
|
toclose 2 # mark it to be closed
|
||||||
return 2
|
return 2
|
||||||
]], newresource)}
|
]], newresource)}
|
||||||
assert(type(a[1]) == "string" and a[2][1] == 11)
|
assert(type(a[1]) == "string" and a[2][1] == 11)
|
||||||
@ -1005,7 +1007,7 @@ do
|
|||||||
-- error
|
-- error
|
||||||
local a, b = pcall(T.testC, [[
|
local a, b = pcall(T.testC, [[
|
||||||
call 0 1 # create resource
|
call 0 1 # create resource
|
||||||
toclose # mark it to be closed
|
toclose -1 # mark it to be closed
|
||||||
error # resource is the error object
|
error # resource is the error object
|
||||||
]], newresource)
|
]], newresource)
|
||||||
assert(a == false and b[1] == 11)
|
assert(a == false and b[1] == 11)
|
||||||
@ -1019,10 +1021,10 @@ do
|
|||||||
local a = T.testC([[
|
local a = T.testC([[
|
||||||
pushvalue 2
|
pushvalue 2
|
||||||
call 0 1 # create resource
|
call 0 1 # create resource
|
||||||
toclose # mark it to be closed
|
toclose -1 # mark it to be closed
|
||||||
pushvalue 2
|
pushvalue 2
|
||||||
call 0 1 # create another resource
|
call 0 1 # create another resource
|
||||||
toclose # mark it to be closed
|
toclose -1 # mark it to be closed
|
||||||
pushvalue 3
|
pushvalue 3
|
||||||
pushint 2 # there should be two open resources
|
pushint 2 # there should be two open resources
|
||||||
call 1 0
|
call 1 0
|
||||||
|
Loading…
Reference in New Issue
Block a user