static void retstat (LexState *ls) { /* stat -> RETURN explist */ FuncState *fs = ls->fs; expdesc e; int first, nret; /* registers with returned values */ luaX_next(ls); /* skip RETURN */ if (block_follow(ls->t.token) || ls->t.token == ';') first = nret = 0; /* return no values */ else { nret = explist1(ls, &e); /* optional return values */ if (hasmultret(e.k)) { luaK_setmultret(fs, &e); if (e.k == VCALL && nret == 1) { /* tail call? */ SET_OPCODE(getcode(fs,&e), OP_TAILCALL); lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); } first = fs->nactvar; nret = LUA_MULTRET; /* return all values */ } else { if (nret == 1) /* only one single value? */ first = luaK_exp2anyreg(fs, &e); else { luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ first = fs->nactvar; /* return all `active' values */ lua_assert(nret == fs->freereg - first); } } } luaK_ret(fs, first, nret); }
static void chunk (LexState *ls) { /* chunk -> { stat [`;'] } */ int islast = 0; enterlevel(ls); while (!islast && !block_follow(ls->t.token)) { islast = statement(ls); testnext(ls, ';'); lua_assert(ls->fs->freereg >= ls->fs->nactvar); ls->fs->freereg = ls->fs->nactvar; /* free registers */ } leavelevel(ls); }
static void retstat (LexState *ls) { /* stat -> RETURN explist */ FuncState *fs = ls->fs; BlockCnt *bl = fs->bl; expdesc e; int first, nret; /* registers with returned values */ int ret_in_try = 0; luaX_next(ls); /* skip RETURN */ if (block_follow(ls->t.token) || ls->t.token == ';') first = nret = 0; /* return no values */ else { nret = explist1(ls, &e); /* optional return values */ if (hasmultret(e.k)) { luaK_setmultret(fs, &e); if (e.k == VCALL && nret == 1) { /* tail call? */ SET_OPCODE(getcode(fs,&e), OP_TAILCALL); lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); } first = fs->nactvar; nret = LUA_MULTRET; /* return all values */ } else { if (nret == 1) /* only one single value? */ first = luaK_exp2anyreg(fs, &e); else { luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ first = fs->nactvar; /* return all `active' values */ lua_assert(nret == fs->freereg - first); } } } /* before return, we should exit all try-catch blocks */ while (bl) { if (bl->isbreakable == 2) { if (ret_in_try) luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0); else { ret_in_try = 1; luaK_codeABC(fs, OP_EXITTRY, first, nret+1, 1); /* here we will save all return values */ } } else if (bl->isbreakable == 3) luaX_syntaxerror(ls, "can't return in _finally_ clause"); bl = bl->previous; } luaK_codeABC(fs, OP_RETURN, first, nret+1, ret_in_try); }
static void chunk (LexState *ls) { /* chunk -> { stat [`;'] } */ int islast = 0; callstack_ref cref( *ls->L ); while (!islast && !block_follow(ls->t.token)) { islast = statement(ls); testnext(ls, ';'); FuncState *fs = GetCurrentFuncState( ls ); lua_assert(fs->f->maxstacksize >= fs->freereg && fs->freereg >= fs->nactvar); fs->freereg = fs->nactvar; /* free registers */ } }