diff -up lua-5.4.3/src/lvm.c.bug3 lua-5.4.3/src/lvm.c --- lua-5.4.3/src/lvm.c.bug3 2021-04-28 13:27:54.025590350 -0400 +++ lua-5.4.3/src/lvm.c 2021-04-28 13:28:55.233614835 -0400 @@ -847,10 +847,19 @@ void luaV_finishOp (lua_State *L) { luaV_concat(L, total); /* concat them (may yield again) */ break; } - case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */ + case OP_CLOSE: { /* yielded closing variables */ ci->u.l.savedpc--; /* repeat instruction to close other vars. */ break; } + case OP_RETURN: { /* yielded closing variables */ + StkId ra = base + GETARG_A(inst); + /* correct top to signal correct number of returns (in case the + return is "in top" */ + L->top = ra + ci->u2.nres; + /* repeat instruction to close other vars. and complete the return */ + ci->u.l.savedpc--; + break; + } default: { /* only these other opcodes can yield */ lua_assert(op == OP_TFORCALL || op == OP_CALL || @@ -1670,6 +1679,7 @@ void luaV_execute (lua_State *L, CallInf n = cast_int(L->top - ra); /* get what is available */ savepc(ci); if (TESTARG_k(i)) { /* may there be open upvalues? */ + ci->u2.nres = n; /* save number of returns */ if (L->top < ci->top) L->top = ci->top; luaF_close(L, base, CLOSEKTOP, 1);