バグ
これはバージョン5.0のLuaに含まれるすべての既知のバグリストの日本語訳である。 原文 も参照のこと。
lua_closethread が存在しない。
function co_func (current_co) coroutine.resume(co) end co = coroutine.create(co_func) coroutine.resume(co) coroutine.resume(co) --> seg. faultパッチ:
* ldo.c:
325,326c325
< if (nargs >= L->top - L->base)
< luaG_runerror(L, "cannot resume dead coroutine");
---
> lua_assert(nargs < L->top - L->base);
329c328,329
< else if (ci->state & CI_YIELD) { /* inside a yield? */
---
> else { /* inside a yield */
> lua_assert(ci->state & CI_YIELD);
344,345d343
< else
< luaG_runerror(L, "cannot resume non-suspended coroutine");
351a350,358
> static int resume_error (lua_State *L, const char *msg) {
> L->top = L->ci->base;
> setsvalue2s(L->top, luaS_new(L, msg));
> incr_top(L);
> lua_unlock(L);
> return LUA_ERRRUN;
> }
>
>
355a363,368
> if (L->ci == L->base_ci) {
> if (nargs >= L->top - L->base)
> return resume_error(L, "cannot resume dead coroutine");
> }
> else if (!(L->ci->state & CI_YIELD)) /* not inside a yield? */
> return resume_error(L, "cannot resume non-suspended coroutine");
file:close をファイルなしで呼び出してはいけない (seg fault を起こす)。
> io.stdin.close() -- 正しい呼び出しは io.stdin:close()パッチ:
* liolib.c:
161c161
< if (lua_isnone(L, 1)) {
---
> if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {
パッチ:lua.cを変更してlua_assertを定義し、Luaを再コンパイルする必要がある。 * lua.c: 381a382 > lua_checkstack(l, 1000);
* lgc.c: 247c247 < if (!(ci->state & CI_C) && lim < ci->top) --- > if (lim < ci->top)
function g(x)
coroutine.yield(x)
end
function f (i)
debug.sethook(print, "l")
for j=1,1000 do
g(i+j)
end
end
co = coroutine.wrap(f)
co(10)
pcall(co)
pcall(co)
パッチ:* lvm.c: 402d401 < L->ci->u.l.pc = &pc; 405a405 > L->ci->u.l.pc = &pc; 676,678c676 < lua_assert(ci->u.l.pc == &pc && < ttisfunction(ci->base - 1) && < (ci->state & CI_SAVEDPC)); --- > lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));
a = newproxy(true) getmetatable(a).__gc = function () end for i=1,10000000 do newproxy(a) if math.mod(i, 10000) == 0 then print(gcinfo()) end endパッチ:
* lgc.h:
18c18
< void luaC_separateudata (lua_State *L);
---
> size_t luaC_separateudata (lua_State *L);
* lgc.c:
113c113,114
< void luaC_separateudata (lua_State *L) {
---
> size_t luaC_separateudata (lua_State *L) {
> size_t deadmem = 0;
127a129
> deadmem += sizeudata(gcotou(curr)->uv.len);
136a139
> return deadmem;
390c393
< static void checkSizes (lua_State *L) {
---
> static void checkSizes (lua_State *L, size_t deadmem) {
400c403
< G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
---
> G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */
454c457,458
< static void mark (lua_State *L) {
---
> static size_t mark (lua_State *L) {
> size_t deadmem;
467c471
< luaC_separateudata(L); /* separate userdata to be preserved */
---
> deadmem = luaC_separateudata(L); /* separate userdata to be preserved */
475a480
> return deadmem;
480c485
< mark(L);
---
> size_t deadmem = mark(L);
482c487
< checkSizes(L);
---
> checkSizes(L, deadmem);
print{}; -- (AS400 マシンで)
パッチ:* liolib.c: 178c178 < char buff[32]; --- > char buff[128]; * lbaselib.c: 327c327 < char buff[64]; --- > char buff[128];
-- コンパイル済みコードでこれを実行する必要がある local a,b,c local function d () endパッチ:
* lparser.c: 1143a1144 > FuncState *fs = ls->fs; 1145c1146,1147 < init_exp(&v, VLOCAL, ls->fs->freereg++); --- > init_exp(&v, VLOCAL, fs->freereg); > luaK_reserveregs(fs, 1); 1148c1150,1152 < luaK_storevar(ls->fs, &v, &b); --- > luaK_storevar(fs, &v, &b); > /* debug information will only see the variable after this point! */ > getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
以下のようにフックを設定してみよ。 lua_sethook(L, my_hook, LUA_MASKLINE | LUA_MASKRET, 1); (奇妙にもcountフックを設定せずにcountを1としているが、間違いではない)パッチ:
* lvm.c:
69c69
< if (mask > LUA_MASKLINE) { /* instruction-hook set? */
---
> if (mask & LUA_MASKCOUNT) { /* instruction-hook set? */