simpler implementation for line information

This commit is contained in:
Roberto Ierusalimschy 2002-03-25 14:47:14 -03:00
parent 00af2faae7
commit 801aaf37b1
15 changed files with 79 additions and 175 deletions

27
lcode.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 1.91 2002/03/08 19:10:32 roberto Exp roberto $
** $Id: lcode.c,v 1.92 2002/03/21 20:31:43 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -737,31 +737,16 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
}
static void codelineinfo (FuncState *fs) {
Proto *f = fs->f;
LexState *ls = fs->ls;
if (ls->lastline > fs->lastline) {
if (ls->lastline > fs->lastline+1) {
luaM_growvector(fs->L, f->lineinfo, fs->nlineinfo, f->sizelineinfo, int,
MAX_INT, "line info overflow");
f->lineinfo[fs->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
}
luaM_growvector(fs->L, f->lineinfo, fs->nlineinfo, f->sizelineinfo, int,
MAX_INT, "line info overflow");
f->lineinfo[fs->nlineinfo++] = fs->pc;
fs->lastline = ls->lastline;
}
}
static int luaK_code (FuncState *fs, Instruction i) {
Proto *f;
codelineinfo(fs);
f = fs->f;
Proto *f = fs->f;
int oldsize = f->sizecode;
/* put new instruction in code array */
luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "code size overflow");
f->code[fs->pc] = i;
if (f->sizecode != oldsize)
luaM_reallocvector(fs->L, f->lineinfo, oldsize, f->sizecode, int);
f->lineinfo[fs->pc] = fs->ls->lastline;
return fs->pc++;
}

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.103 2002/03/19 12:45:25 roberto Exp roberto $
** $Id: ldebug.c,v 1.104 2002/03/22 16:54:31 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -34,6 +34,24 @@ static int isLmark (CallInfo *ci) {
}
static int currentpc (lua_State *L, CallInfo *ci) {
if (ci->pc == NULL) return -1; /* function is not an active Lua function */
if (ci == L->ci || ci->pc != (ci+1)->pc) /* no other function using `pc'? */
return (*ci->pc - ci_func(ci)->l.p->code) - 1;
else /* function's pc is saved */
return (ci->savedpc - ci_func(ci)->l.p->code) - 1;
}
static int currentline (lua_State *L, CallInfo *ci) {
int pc = currentpc(L, ci);
if (pc < 0)
return -1; /* only active lua functions have current-line information */
else
return ci_func(ci)->l.p->lineinfo[pc];
}
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
lua_Hook oldhook;
lua_lock(L);
@ -45,10 +63,13 @@ LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
CallInfo *ci;
lua_Hook oldhook;
lua_lock(L);
oldhook = L->linehook;
L->linehook = func;
for (ci = L->base_ci; ci <= L->ci; ci++)
ci->lastpc = currentpc(L, ci);
lua_unlock(L);
return oldhook;
}
@ -67,57 +88,6 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
}
int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
int refi;
if (lineinfo == NULL) return -1; /* no line info */
refi = prefi ? *prefi : 0;
if (lineinfo[refi] < 0)
refline += -lineinfo[refi++];
lua_assert(lineinfo[refi] >= 0);
while (lineinfo[refi] > pc) {
refline--;
refi--;
if (lineinfo[refi] < 0)
refline -= -lineinfo[refi--];
lua_assert(lineinfo[refi] >= 0);
}
for (;;) {
int nextline = refline + 1;
int nextref = refi + 1;
if (lineinfo[nextref] < 0)
nextline += -lineinfo[nextref++];
lua_assert(lineinfo[nextref] >= 0);
if (lineinfo[nextref] > pc)
break;
refline = nextline;
refi = nextref;
}
if (prefi) *prefi = refi;
return refline;
}
static int currentpc (lua_State *L, CallInfo *ci) {
lua_assert(isLmark(ci));
if (ci->pc == NULL) return 0; /* function is not active */
if (ci == L->ci || ci->pc != (ci+1)->pc) /* no other function using `pc'? */
return (*ci->pc - ci_func(ci)->l.p->code) - 1;
else /* function's pc is saved */
return (ci->savedpc - ci_func(ci)->l.p->code) - 1;
}
static int currentline (lua_State *L, CallInfo *ci) {
if (!isLmark(ci))
return -1; /* only active lua functions have current-line information */
else {
int *lineinfo = ci_func(ci)->l.p->lineinfo;
return luaG_getline(lineinfo, currentpc(L, ci), 1, NULL);
}
}
static Proto *getluaproto (CallInfo *ci) {
return (isLmark(ci) ? ci_func(ci)->l.p : NULL);
}
@ -272,19 +242,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
static int checklineinfo (const Proto *pt) {
int *lineinfo = pt->lineinfo;
if (lineinfo == NULL) return 1;
check(pt->sizelineinfo >= 2 && lineinfo[pt->sizelineinfo-1] == MAX_INT);
lua_assert(luaG_getline(lineinfo, pt->sizecode-1, 1, NULL) < MAX_INT);
if (*lineinfo < 0) lineinfo++;
check(*lineinfo == 0);
return 1;
}
static int precheck (const Proto *pt) {
check(checklineinfo(pt));
check(pt->maxstacksize <= MAXSTACK);
lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 1.16 2001/11/28 20:13:13 roberto Exp roberto $
** $Id: ldebug.h,v 1.17 2002/03/19 12:45:25 roberto Exp roberto $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@ -15,7 +15,6 @@
void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
int luaG_checkcode (const Proto *pt);

9
ldo.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.164 2002/03/15 17:17:16 roberto Exp roberto $
** $Id: ldo.c,v 1.165 2002/03/20 12:52:32 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -122,13 +122,13 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
}
void luaD_lineHook (lua_State *L, int line, lua_Hook linehook) {
void luaD_lineHook (lua_State *L, int line) {
if (L->allowhooks) {
lua_Debug ar;
ar.event = "line";
ar.i_ci = L->ci - L->base_ci;
ar.currentline = line;
dohook(L, &ar, linehook);
dohook(L, &ar, L->linehook);
}
}
@ -221,7 +221,6 @@ StkId luaD_precall (lua_State *L, StkId func) {
if (p->is_vararg) /* varargs? */
adjust_varargs(L, p->numparams);
luaD_checkstack(L, p->maxstacksize);
ci->line = 0;
ci->top = ci->base + p->maxstacksize;
while (L->top < ci->top)
setnilvalue(L->top++);
@ -250,7 +249,7 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
luaD_callHook(L, L->callhook, "return");
firstResult = restorestack(L, fr);
}
res = L->ci->base - 1; /* func == final position of 1st result */
res = L->ci->base - 1; /* res == final position of 1st result */
L->ci--;
/* move results to correct place */
while (wanted != 0 && firstResult < L->top) {

4
ldo.h
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 1.40 2002/01/30 17:27:53 roberto Exp roberto $
** $Id: ldo.h,v 1.41 2002/03/20 12:52:32 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -27,7 +27,7 @@
#define restorestack(L,n) ((TObject *)((char *)L->stack + (n)))
void luaD_lineHook (lua_State *L, int line, lua_Hook linehook);
void luaD_lineHook (lua_State *L, int line);
StkId luaD_precall (lua_State *L, StkId func);
void luaD_call (lua_State *L, StkId func, int nResults);
void luaD_poscall (lua_State *L, int wanted, StkId firstResult);

View File

@ -1,5 +1,5 @@
/*
** $Id: lfunc.c,v 1.53 2001/12/21 17:31:35 roberto Exp roberto $
** $Id: lfunc.c,v 1.54 2002/03/05 12:42:47 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@ -87,7 +87,6 @@ Proto *luaF_newproto (lua_State *L) {
f->marked = 0;
f->lineinfo = NULL;
f->sizelocvars = 0;
f->sizelineinfo = 0;
f->locvars = NULL;
f->lineDefined = 0;
f->source = NULL;
@ -99,10 +98,10 @@ Proto *luaF_newproto (lua_State *L) {
void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->code, f->sizecode, Instruction);
luaM_freearray(L, f->lineinfo, f->sizecode, int);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->k, f->sizek, TObject);
luaM_freearray(L, f->p, f->sizep, Proto *);
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
luaM_freelem(L, f);
}

View File

@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.126 2002/03/11 12:45:00 roberto Exp roberto $
** $Id: lobject.h,v 1.127 2002/03/18 18:16:16 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@ -129,7 +129,6 @@ typedef struct Proto {
int sizek; /* size of `k' */
int sizecode;
int sizep; /* size of `p' */
int sizelineinfo; /* size of `lineinfo' */
int sizelocvars;
int lineDefined;
lu_byte nupvalues;

View File

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.c,v 1.12 2002/03/08 19:10:32 roberto Exp roberto $
** $Id: lopcodes.c,v 1.13 2002/03/21 20:32:22 roberto Exp roberto $
** extracted automatically from lopcodes.h by mkprint.lua
** DO NOT EDIT
** See Copyright Notice in lua.h
@ -59,11 +59,11 @@ const char *const luaP_opnames[] = {
#define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \
((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
((sa)<<OpModesetA) | ((k)<<OpModeK) | (x)<<OpModeNoTrace | (m))
((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T n B C sA K mode opcode */
/* T _ B C sA K mode opcode */
opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */
,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */
,opmode(0,0,0,0, 1,0,iABC) /* OP_LOADBOOL */
@ -96,7 +96,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */
,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */
,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */
,opmode(0,1,0,0, 0,0,iAsBc) /* OP_FORLOOP */
,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORLOOP */
,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */
,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */
,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */

View File

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.91 2002/03/18 14:49:46 roberto Exp roberto $
** $Id: lopcodes.h,v 1.92 2002/03/21 20:32:22 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -207,8 +207,7 @@ enum OpModeMask {
OpModeCreg, /* C is a register/constant */
OpModesetA, /* instruction set register A */
OpModeK, /* Bc is a constant */
OpModeT, /* operator is a test */
OpModeNoTrace /* operator should not be traced */
OpModeT /* operator is a test */
};
extern const lu_byte luaP_opmodes[NUM_OPCODES];

View File

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 1.171 2002/03/18 14:49:46 roberto Exp roberto $
** $Id: lparser.c,v 1.172 2002/03/21 20:32:22 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@ -376,11 +376,9 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->nk = 0;
fs->h = luaH_new(ls->L, 0, 0);
fs->np = 0;
fs->nlineinfo = 0;
fs->nlocvars = 0;
fs->nactloc = 0;
fs->nactvar = 0;
fs->lastline = 0;
fs->defaultglob = NO_REG; /* default is free globals */
fs->bl = NULL;
f->code = NULL;
@ -402,6 +400,7 @@ static void close_func (LexState *ls) {
G(L)->roottable = fs->h->next;
luaH_free(L, fs->h);
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
luaM_reallocvector(L, f->lineinfo, f->sizecode, fs->pc, int);
f->sizecode = fs->pc;
luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject);
f->sizek = fs->nk;
@ -409,9 +408,6 @@ static void close_func (LexState *ls) {
f->sizep = fs->np;
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
f->sizelocvars = fs->nlocvars;
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int);
f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */
f->sizelineinfo = fs->nlineinfo;
lua_assert(luaG_checkcode(f));
lua_assert(fs->bl == NULL);
ls->fs = fs->prev;
@ -999,10 +995,10 @@ static int exp1 (LexState *ls) {
}
static void fornum (LexState *ls, TString *varname) {
static void fornum (LexState *ls, TString *varname, int line) {
/* fornum -> NAME = exp1,exp1[,exp1] DO body */
FuncState *fs = ls->fs;
int prep;
int prep, endfor;
int base = fs->freereg;
new_localvar(ls, varname, 0);
new_localvarstr(ls, "(for limit)", 1);
@ -1024,7 +1020,9 @@ static void fornum (LexState *ls, TString *varname) {
check(ls, TK_DO);
block(ls);
luaK_patchtohere(fs, prep-1);
luaK_patchlist(fs, luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP), prep);
endfor = luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP);
luaK_patchlist(fs, endfor, prep);
fs->f->lineinfo[endfor] = line; /* pretend that `OP_FOR' starts the loop */
}
@ -1065,7 +1063,7 @@ static void forstat (LexState *ls, int line) {
varname = str_checkname(ls); /* first variable name */
next(ls); /* skip var name */
switch (ls->t.token) {
case '=': fornum(ls, varname); break;
case '=': fornum(ls, varname, line); break;
case ',': case TK_IN: forlist(ls, varname); break;
default: luaK_error(ls, "`=' or `in' expected");
}

View File

@ -1,5 +1,5 @@
/*
** $Id: lparser.h,v 1.39 2002/02/08 22:42:41 roberto Exp roberto $
** $Id: lparser.h,v 1.40 2002/03/14 18:01:52 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@ -68,11 +68,9 @@ typedef struct FuncState {
int defaultglob; /* where to look for non-declared globals */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
int nlineinfo; /* number of elements in `lineinfo' */
int nlocvars; /* number of elements in `locvars' */
int nactloc; /* number of active local variables */
int nactvar; /* number of elements in array `actvar' */
int lastline; /* line where last `lineinfo' was generated */
expdesc upvalues[MAXUPVALUES]; /* upvalues */
vardesc actvar[MAXVARS]; /* declared-variable stack */
} FuncState;

View File

@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.78 2002/03/07 18:11:51 roberto Exp roberto $
** $Id: lstate.h,v 1.79 2002/03/11 12:45:00 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@ -91,16 +91,12 @@ typedef struct CallInfo {
StkId top; /* top for this function (when it's a Lua function) */
const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
StkId *pb; /* points to `base' variable in `luaV_execute' */
/* extra information for line tracing */
int lastpc; /* last pc traced */
int line; /* current line */
int refi; /* current index in `lineinfo' */
int yield_results;
} CallInfo;
#define ci_func(ci) (clvalue((ci)->base - 1))
#define yield_results refi /* reuse this field */
/*
** `global state', shared by all threads of this state

View File

@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 1.112 2002/03/14 18:01:52 roberto Exp roberto $
** $Id: ltests.c,v 1.113 2002/03/20 12:54:08 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@ -144,7 +144,7 @@ static char *buildop (Proto *p, int pc, char *buff) {
Instruction i = p->code[pc];
OpCode o = GET_OPCODE(i);
const char *name = luaP_opnames[o];
int line = luaG_getline(p->lineinfo, pc, 1, NULL);
int line = p->lineinfo[pc];
sprintf(buff, "(%4d) %4d - ", line, pc);
switch (getOpMode(o)) {
case iABC:

View File

@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 1.43 2001/07/24 21:57:19 roberto Exp $
** $Id: lundump.c,v 1.44 2001/11/28 20:13:13 roberto Exp roberto $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@ -133,7 +133,6 @@ static void LoadLines (lua_State* L, Proto* f, ZIO* Z, int swap)
int n;
n=LoadInt(L,Z,swap);
f->lineinfo=luaM_newvector(L,n,int);
f->sizelineinfo=n;
LoadVector(L,f->lineinfo,n,sizeof(*f->lineinfo),Z,swap);
}

68
lvm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.221 2002/03/20 12:52:32 roberto Exp roberto $
** $Id: lvm.c,v 1.222 2002/03/22 16:54:31 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -62,33 +62,17 @@ int luaV_tostring (lua_State *L, TObject *obj) {
}
static void traceexec (lua_State *L, lua_Hook linehook) {
static void traceexec (lua_State *L) {
CallInfo *ci = L->ci;
int *lineinfo = ci_func(ci)->l.p->lineinfo;
int pc = cast(int, *ci->pc - ci_func(ci)->l.p->code) - 1;
int newline;
if (testOpMode(GET_OPCODE(*(*ci->pc - 1)), OpModeNoTrace))
return;
if (ci->line == -1) return; /* no linehooks for this function */
else if (ci->line == 0) { /* first linehook? */
if (pc == 0) { /* function is starting now? */
ci->line = 1;
ci->refi = 0;
ci->lastpc = pc+1; /* make sure it will call linehook */
}
else { /* function started without hooks: */
ci->line = -1; /* keep it that way */
return;
}
}
newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
int newline = lineinfo[pc];
if (pc == 0) /* tracing may be starting now? */
ci->lastpc = 0; /* initialize `lastpc' */
/* calls linehook when enters a new line or jumps back (loop) */
if (newline != ci->line || pc <= ci->lastpc) {
ci->line = newline;
luaD_lineHook(L, newline, linehook);
ci = L->ci; /* previous call may realocate `ci' */
}
ci->lastpc = pc;
if (pc <= ci->lastpc || newline != lineinfo[ci->lastpc])
luaD_lineHook(L, newline);
L->ci->lastpc = pc;
}
@ -316,21 +300,17 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
#define dojump(pc, i) ((pc) += (i))
/*
** Executes current Lua function. Parameters are between [base,top).
** Returns n such that the results are between [n,top).
*/
StkId luaV_execute (lua_State *L) {
StkId base;
LClosure *cl;
TObject *k;
const Instruction *pc;
lua_Hook linehook;
reinit:
linehook = L->linehook;
callentry: /* entry point when calling new functions */
L->ci->pc = &pc;
pc = L->ci->savedpc;
L->ci->pb = &base;
pc = L->ci->savedpc;
retentry: /* entry point when returning to old functions */
base = L->ci->base;
cl = &clvalue(base - 1)->l;
k = cl->p->k;
@ -338,13 +318,13 @@ StkId luaV_execute (lua_State *L) {
for (;;) {
const Instruction i = *pc++;
StkId ra;
if (linehook)
traceexec(L, linehook);
if (L->linehook)
traceexec(L);
ra = RA(i);
lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base);
lua_assert(L->top == L->ci->top || GET_OPCODE(i) == OP_CALL ||
GET_OPCODE(i) == OP_TAILCALL || GET_OPCODE(i) == OP_RETURN ||
GET_OPCODE(i) == OP_SETLISTO);
lua_assert(L->top == L->ci->top ||
GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
switch (GET_OPCODE(i)) {
case OP_MOVE: {
setobj(ra, RB(i));
@ -453,7 +433,6 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_JMP: {
linehook = L->linehook;
dojump(pc, GETARG_sBc(i));
break;
}
@ -511,7 +490,7 @@ StkId luaV_execute (lua_State *L) {
}
else { /* it is a Lua function: `call' it */
(L->ci-1)->savedpc = pc;
goto reinit;
goto callentry;
}
break;
}
@ -521,7 +500,7 @@ StkId luaV_execute (lua_State *L) {
if (b != 0) L->top = ra+b; /* else previous instruction set top */
luaD_poscall(L, LUA_MULTRET, ra); /* move down function and args. */
ra = luaD_precall(L, base-1);
if (ra == NULL) goto reinit; /* it is a Lua function */
if (ra == NULL) goto callentry; /* it is a Lua function */
else if (ra > L->top) return NULL; /* yield??? */
else goto ret;
}
@ -540,14 +519,12 @@ StkId luaV_execute (lua_State *L) {
else { /* yes: continue its execution */
int nresults;
lua_assert(ttype(ci->base-1) == LUA_TFUNCTION);
base = ci->base; /* restore previous values */
cl = &clvalue(base - 1)->l;
k = cl->p->k;
pc = ci->savedpc;
lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL);
nresults = GETARG_C(*(pc-1)) - 1;
luaD_poscall(L, nresults, ra);
if (nresults >= 0) L->top = L->ci->top;
goto retentry;
}
break;
}
@ -556,7 +533,6 @@ StkId luaV_execute (lua_State *L) {
int j = GETARG_sBc(i);
const TObject *plimit = ra+1;
const TObject *pstep = ra+2;
dojump(pc, j); /* jump back before tests (for error messages) */
if (ttype(ra) != LUA_TNUMBER)
luaD_error(L, "`for' initial value must be a number");
if (!tonumber(plimit, ra+1))
@ -567,11 +543,9 @@ StkId luaV_execute (lua_State *L) {
index = nvalue(ra) + step; /* increment index */
limit = nvalue(plimit);
if (step > 0 ? index <= limit : index >= limit) {
dojump(pc, j); /* jump back */
chgnvalue(ra, index); /* update index */
linehook = L->linehook;
}
else
dojump(pc, -j); /* undo jump */
break;
}
case OP_TFORLOOP: {