aboutsummaryrefslogtreecommitdiff
path: root/bugs
diff options
context:
space:
mode:
Diffstat (limited to 'bugs')
-rw-r--r--bugs67
1 files changed, 67 insertions, 0 deletions
diff --git a/bugs b/bugs
index ab8a8369..8c163475 100644
--- a/bugs
+++ b/bugs
@@ -3376,6 +3376,73 @@ patch = [[
3376} 3376}
3377 3377
3378 3378
3379Bug{
3380what = [[suspended '__le' metamethod can give wrong result]],
3381report = [[Eric Zhong, 2015/04/07]],
3382since = [[5.2]],
3383fix = nil,
3384
3385example = [[
3386mt = {__le = function (a,b) coroutine.yield("yield"); return a.x <= b.x end}
3387t1 = setmetatable({x=1}, mt)
3388t2 = {x=2}
3389co = coroutine.wrap(function (a,b) return t2 <= t1 end)
3390co()
3391print(co()) --> true (should be false)
3392]],
3393
3394patch = [[
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--[=[
3380Bug{ 3447Bug{
3381what = [[ ]], 3448what = [[ ]],