diff options
Diffstat (limited to 'bugs')
-rw-r--r-- | bugs | 67 |
1 files changed, 67 insertions, 0 deletions
@@ -3376,6 +3376,73 @@ patch = [[ | |||
3376 | } | 3376 | } |
3377 | 3377 | ||
3378 | 3378 | ||
3379 | Bug{ | ||
3380 | what = [[suspended '__le' metamethod can give wrong result]], | ||
3381 | report = [[Eric Zhong, 2015/04/07]], | ||
3382 | since = [[5.2]], | ||
3383 | fix = nil, | ||
3384 | |||
3385 | example = [[ | ||
3386 | mt = {__le = function (a,b) coroutine.yield("yield"); return a.x <= b.x end} | ||
3387 | t1 = setmetatable({x=1}, mt) | ||
3388 | t2 = {x=2} | ||
3389 | co = coroutine.wrap(function (a,b) return t2 <= t1 end) | ||
3390 | co() | ||
3391 | print(co()) --> true (should be false) | ||
3392 | ]], | ||
3393 | |||
3394 | patch = [[ | ||
3395 | --- lstate.h 2015/03/04 13:31:21 2.120 | ||
3396 | +++ lstate.h 2015/04/08 16:30:40 | ||
3397 | @@ -94,6 +94,7 @@ | ||
3398 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ | ||
3399 | #define CIST_TAIL (1<<5) /* call was tail called */ | ||
3400 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ | ||
3401 | +#define CIST_LEQ (1<<7) /* using __lt for __le */ | ||
3402 | |||
3403 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) | ||
3404 | |||
3405 | |||
3406 | --- lvm.c 2015/03/30 15:45:01 2.238 | ||
3407 | +++ lvm.c 2015/04/09 15:30:13 | ||
3408 | @@ -275,9 +275,14 @@ | ||
3409 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; | ||
3410 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */ | ||
3411 | return res; | ||
3412 | - else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */ | ||
3413 | - luaG_ordererror(L, l, r); | ||
3414 | - return !res; | ||
3415 | + else { /* try 'lt': */ | ||
3416 | + L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ | ||
3417 | + res = luaT_callorderTM(L, r, l, TM_LT); | ||
3418 | + L->ci->callstatus ^= CIST_LEQ; /* clear mark */ | ||
3419 | + if (res < 0) | ||
3420 | + luaG_ordererror(L, l, r); | ||
3421 | + return !res; /* result is negated */ | ||
3422 | + } | ||
3423 | } | ||
3424 | |||
3425 | @@ -542,11 +547,11 @@ | ||
3426 | case OP_LE: case OP_LT: case OP_EQ: { | ||
3427 | int res = !l_isfalse(L->top - 1); | ||
3428 | L->top--; | ||
3429 | - /* metamethod should not be called when operand is K */ | ||
3430 | - lua_assert(!ISK(GETARG_B(inst))); | ||
3431 | - if (op == OP_LE && /* "<=" using "<" instead? */ | ||
3432 | - ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) | ||
3433 | - res = !res; /* invert result */ | ||
3434 | + if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ | ||
3435 | + lua_assert(op == OP_LE); | ||
3436 | + ci->callstatus ^= CIST_LEQ; /* clear mark */ | ||
3437 | + res = !res; /* negate result */ | ||
3438 | + } | ||
3439 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); | ||
3440 | if (res != GETARG_A(inst)) /* condition failed? */ | ||
3441 | ci->u.l.savedpc++; /* skip jump instruction */ | ||
3442 | ]] | ||
3443 | } | ||
3444 | |||
3445 | |||
3379 | --[=[ | 3446 | --[=[ |
3380 | Bug{ | 3447 | Bug{ |
3381 | what = [[ ]], | 3448 | what = [[ ]], |