aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldebug.c19
-rw-r--r--ldebug.h3
-rw-r--r--ldo.c47
-rw-r--r--lgc.c3
-rw-r--r--lgc.h6
-rw-r--r--lstate.c6
-rw-r--r--lstate.h20
-rw-r--r--lvm.c154
-rw-r--r--lvm.h4
9 files changed, 115 insertions, 147 deletions
diff --git a/ldebug.c b/ldebug.c
index bc7f9237..e7413507 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.153 2003/05/14 12:09:12 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.154 2003/07/10 11:59:06 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,14 +30,8 @@
30static const char *getfuncname (CallInfo *ci, const char **name); 30static const char *getfuncname (CallInfo *ci, const char **name);
31 31
32 32
33#define isLua(ci) (!((ci)->state & CI_C))
34
35
36static int currentpc (CallInfo *ci) { 33static int currentpc (CallInfo *ci) {
37 if (!isLua(ci)) return -1; /* function is not a Lua function? */ 34 if (!isLua(ci)) return -1; /* function is not a Lua function? */
38 if (ci->state & CI_HASFRAME) /* function has a frame? */
39 ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */
40 /* function's pc is saved */
41 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); 35 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
42} 36}
43 37
@@ -51,14 +45,6 @@ static int currentline (CallInfo *ci) {
51} 45}
52 46
53 47
54void luaG_inithooks (lua_State *L) {
55 CallInfo *ci;
56 for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */
57 currentpc(ci);
58 L->hookinit = 1;
59}
60
61
62/* 48/*
63** this function can be called asynchronous (e.g. during a signal) 49** this function can be called asynchronous (e.g. during a signal)
64*/ 50*/
@@ -71,7 +57,6 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
71 L->basehookcount = count; 57 L->basehookcount = count;
72 resethookcount(L); 58 resethookcount(L);
73 L->hookmask = cast(lu_byte, mask); 59 L->hookmask = cast(lu_byte, mask);
74 L->hookinit = 0;
75 return 1; 60 return 1;
76} 61}
77 62
@@ -97,7 +82,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
97 lua_lock(L); 82 lua_lock(L);
98 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { 83 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
99 level--; 84 level--;
100 if (!(ci->state & CI_C)) /* Lua function? */ 85 if (f_isLua(ci)) /* Lua function? */
101 level -= ci->u.l.tailcalls; /* skip lost tail calls */ 86 level -= ci->u.l.tailcalls; /* skip lost tail calls */
102 } 87 }
103 if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */ 88 if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */
diff --git a/ldebug.h b/ldebug.h
index 417bd47d..03baaaee 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.h,v 1.31 2002/08/20 20:03:05 roberto Exp roberto $ 2** $Id: ldebug.h,v 1.32 2002/11/18 11:01:55 roberto Exp $
3** Auxiliary functions from Debug Interface module 3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -18,7 +18,6 @@
18#define resethookcount(L) (L->hookcount = L->basehookcount) 18#define resethookcount(L) (L->hookcount = L->basehookcount)
19 19
20 20
21void luaG_inithooks (lua_State *L);
22void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); 21void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
23void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 22void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
24void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); 23void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
diff --git a/ldo.c b/ldo.c
index 93e2aa0a..f462353f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.218 2003/05/13 19:22:19 roberto Exp roberto $ 2** $Id: ldo.c,v 1.219 2003/05/14 21:02:39 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -243,6 +243,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
243 cl = &clvalue(func)->l; 243 cl = &clvalue(func)->l;
244 if (!cl->isC) { /* Lua function? prepare its call */ 244 if (!cl->isC) { /* Lua function? prepare its call */
245 CallInfo *ci; 245 CallInfo *ci;
246 StkId st;
246 Proto *p = cl->p; 247 Proto *p = cl->p;
247 if (p->is_vararg) /* varargs? */ 248 if (p->is_vararg) /* varargs? */
248 adjust_varargs(L, p->numparams, func+1); 249 adjust_varargs(L, p->numparams, func+1);
@@ -252,9 +253,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
252 ci->top = L->base + p->maxstacksize; 253 ci->top = L->base + p->maxstacksize;
253 ci->u.l.savedpc = p->code; /* starting point */ 254 ci->u.l.savedpc = p->code; /* starting point */
254 ci->u.l.tailcalls = 0; 255 ci->u.l.tailcalls = 0;
255 ci->state = CI_SAVEDPC; 256 for (st = L->top; st < ci->top; st++)
256 while (L->top < ci->top) 257 setnilvalue(st);
257 setnilvalue(L->top++);
258 L->top = ci->top; 258 L->top = ci->top;
259 return NULL; 259 return NULL;
260 } 260 }
@@ -265,7 +265,6 @@ StkId luaD_precall (lua_State *L, StkId func) {
265 ci = ++L->ci; /* now `enter' new function */ 265 ci = ++L->ci; /* now `enter' new function */
266 L->base = L->ci->base = restorestack(L, funcr) + 1; 266 L->base = L->ci->base = restorestack(L, funcr) + 1;
267 ci->top = L->top + LUA_MINSTACK; 267 ci->top = L->top + LUA_MINSTACK;
268 ci->state = CI_C; /* a C function */
269 if (L->hookmask & LUA_MASKCALL) 268 if (L->hookmask & LUA_MASKCALL)
270 luaD_callhook(L, LUA_HOOKCALL, -1); 269 luaD_callhook(L, LUA_HOOKCALL, -1);
271 lua_unlock(L); 270 lua_unlock(L);
@@ -279,7 +278,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
279static StkId callrethooks (lua_State *L, StkId firstResult) { 278static StkId callrethooks (lua_State *L, StkId firstResult) {
280 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 279 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
281 luaD_callhook(L, LUA_HOOKRET, -1); 280 luaD_callhook(L, LUA_HOOKRET, -1);
282 if (!(L->ci->state & CI_C)) { /* Lua function? */ 281 if (f_isLua(L->ci)) { /* Lua function? */
283 while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */ 282 while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
284 luaD_callhook(L, LUA_HOOKTAILRET, -1); 283 luaD_callhook(L, LUA_HOOKTAILRET, -1);
285 } 284 }
@@ -313,7 +312,6 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
313*/ 312*/
314void luaD_call (lua_State *L, StkId func, int nResults) { 313void luaD_call (lua_State *L, StkId func, int nResults) {
315 StkId firstResult; 314 StkId firstResult;
316 lua_assert(!(L->ci->state & CI_CALLING));
317 if (++L->nCcalls >= LUA_MAXCCALLS) { 315 if (++L->nCcalls >= LUA_MAXCCALLS) {
318 if (L->nCcalls == LUA_MAXCCALLS) 316 if (L->nCcalls == LUA_MAXCCALLS)
319 luaG_runerror(L, "C stack overflow"); 317 luaG_runerror(L, "C stack overflow");
@@ -322,7 +320,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
322 } 320 }
323 firstResult = luaD_precall(L, func); 321 firstResult = luaD_precall(L, func);
324 if (firstResult == NULL) /* is a Lua function? */ 322 if (firstResult == NULL) /* is a Lua function? */
325 firstResult = luaV_execute(L); /* call it */ 323 firstResult = luaV_execute(L, 1); /* call it */
326 luaD_poscall(L, nResults, firstResult); 324 luaD_poscall(L, nResults, firstResult);
327 L->nCcalls--; 325 L->nCcalls--;
328 luaC_checkGC(L); 326 luaC_checkGC(L);
@@ -333,29 +331,28 @@ static void resume (lua_State *L, void *ud) {
333 StkId firstResult; 331 StkId firstResult;
334 int nargs = *cast(int *, ud); 332 int nargs = *cast(int *, ud);
335 CallInfo *ci = L->ci; 333 CallInfo *ci = L->ci;
336 if (ci == L->base_ci) { /* no activation record? */ 334 if (!L->isSuspended) {
337 if (nargs >= L->top - L->base) 335 if (ci == L->base_ci) { /* no activation record? */
338 luaG_runerror(L, "cannot resume dead coroutine"); 336 if (nargs >= L->top - L->base)
339 luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ 337 luaG_runerror(L, "cannot resume dead coroutine");
338 luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */
339 }
340 else
341 luaG_runerror(L, "cannot resume non-suspended coroutine");
340 } 342 }
341 else if (ci->state & CI_YIELD) { /* inside a yield? */ 343 else { /* resumming from previous yield */
342 if (ci->state & CI_C) { /* `common' yield? */ 344 if (!f_isLua(ci)) { /* `common' yield? */
343 /* finish interrupted execution of `OP_CALL' */ 345 /* finish interrupted execution of `OP_CALL' */
344 int nresults; 346 int nresults;
345 lua_assert((ci-1)->state & CI_SAVEDPC);
346 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || 347 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
347 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); 348 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
348 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; 349 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
349 luaD_poscall(L, nresults, L->top - nargs); /* complete it */ 350 luaD_poscall(L, nresults, L->top - nargs); /* complete it */
350 if (nresults >= 0) L->top = L->ci->top; 351 if (nresults >= 0) L->top = L->ci->top;
351 } 352 } /* else yielded inside a hook: just continue its execution */
352 else { /* yielded inside a hook: just continue its execution */
353 ci->state &= ~CI_YIELD;
354 }
355 } 353 }
356 else 354 L->isSuspended = 0;
357 luaG_runerror(L, "cannot resume non-suspended coroutine"); 355 firstResult = luaV_execute(L, L->ci - L->base_ci);
358 firstResult = luaV_execute(L);
359 if (firstResult != NULL) /* return? */ 356 if (firstResult != NULL) /* return? */
360 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ 357 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
361} 358}
@@ -388,9 +385,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
388 ci = L->ci; 385 ci = L->ci;
389 if (L->nCcalls > 0) 386 if (L->nCcalls > 0)
390 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 387 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
391 if (ci->state & CI_C) { /* usual yield */ 388 if (!f_isLua(ci)) { /* usual yield */
392 if ((ci-1)->state & CI_C)
393 luaG_runerror(L, "cannot yield a C function");
394 if (L->top - nresults > L->base) { /* is there garbage in the stack? */ 389 if (L->top - nresults > L->base) { /* is there garbage in the stack? */
395 int i; 390 int i;
396 for (i=0; i<nresults; i++) /* move down results */ 391 for (i=0; i<nresults; i++) /* move down results */
@@ -398,7 +393,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
398 L->top = L->base + nresults; 393 L->top = L->base + nresults;
399 } 394 }
400 } /* else it's an yield inside a hook: nothing to do */ 395 } /* else it's an yield inside a hook: nothing to do */
401 ci->state |= CI_YIELD; 396 L->isSuspended = 1;
402 lua_unlock(L); 397 lua_unlock(L);
403 return -1; 398 return -1;
404} 399}
diff --git a/lgc.c b/lgc.c
index a0e1bcdb..c28ea8b9 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.173 2003/05/16 18:58:39 roberto Exp roberto $ 2** $Id: lgc.c,v 1.174 2003/07/07 13:32:19 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -232,7 +232,6 @@ static void traversestack (GCState *st, lua_State *L1) {
232 lim = L1->top; 232 lim = L1->top;
233 for (ci = L1->base_ci; ci <= L1->ci; ci++) { 233 for (ci = L1->base_ci; ci <= L1->ci; ci++) {
234 lua_assert(ci->top <= L1->stack_last); 234 lua_assert(ci->top <= L1->stack_last);
235 lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC));
236 if (lim < ci->top) lim = ci->top; 235 if (lim < ci->top) lim = ci->top;
237 } 236 }
238 for (o = L1->stack; o < L1->top; o++) 237 for (o = L1->stack; o < L1->top; o++)
diff --git a/lgc.h b/lgc.h
index 8e3a3257..4e66eaa8 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 1.18 2003/02/10 17:32:50 roberto Exp roberto $ 2** $Id: lgc.h,v 1.19 2003/02/28 19:45:15 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,8 +11,8 @@
11#include "lobject.h" 11#include "lobject.h"
12 12
13 13
14#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \ 14#define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \
15 if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); } 15 luaC_collectgarbage(L); }
16 16
17 17
18void luaC_separateudata (lua_State *L); 18void luaC_separateudata (lua_State *L);
diff --git a/lstate.c b/lstate.c
index 008955e4..2153d3d9 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.122 2003/03/18 12:50:04 roberto Exp roberto $ 2** $Id: lstate.c,v 1.123 2003/04/03 13:35:34 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -68,7 +68,6 @@ static void stack_init (lua_State *L1, lua_State *L) {
68 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 68 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
69 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); 69 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
70 L1->ci = L1->base_ci; 70 L1->ci = L1->base_ci;
71 L1->ci->state = CI_C; /* not a Lua function */
72 setnilvalue(L1->top++); /* `function' entry for this `ci' */ 71 setnilvalue(L1->top++); /* `function' entry for this `ci' */
73 L1->base = L1->ci->base = L1->top; 72 L1->base = L1->ci->base = L1->top;
74 L1->ci->top = L1->top + LUA_MINSTACK; 73 L1->ci->top = L1->top + LUA_MINSTACK;
@@ -128,13 +127,14 @@ static void preinit_state (lua_State *L) {
128 L->stacksize = 0; 127 L->stacksize = 0;
129 L->errorJmp = NULL; 128 L->errorJmp = NULL;
130 L->hook = NULL; 129 L->hook = NULL;
131 L->hookmask = L->hookinit = 0; 130 L->hookmask = 0;
132 L->basehookcount = 0; 131 L->basehookcount = 0;
133 L->allowhook = 1; 132 L->allowhook = 1;
134 resethookcount(L); 133 resethookcount(L);
135 L->openupval = NULL; 134 L->openupval = NULL;
136 L->size_ci = 0; 135 L->size_ci = 0;
137 L->nCcalls = 0; 136 L->nCcalls = 0;
137 L->isSuspended = 0;
138 L->base_ci = L->ci = NULL; 138 L->base_ci = L->ci = NULL;
139 L->errfunc = 0; 139 L->errfunc = 0;
140 setnilvalue(gt(L)); 140 setnilvalue(gt(L));
diff --git a/lstate.h b/lstate.h
index 37de2372..009ea790 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.109 2003/02/27 11:52:30 roberto Exp roberto $ 2** $Id: lstate.h,v 1.110 2003/04/28 19:26:16 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -75,11 +75,9 @@ typedef struct stringtable {
75typedef struct CallInfo { 75typedef struct CallInfo {
76 StkId base; /* base for called function */ 76 StkId base; /* base for called function */
77 StkId top; /* top for this function */ 77 StkId top; /* top for this function */
78 int state; /* bit fields; see below */
79 union { 78 union {
80 struct { /* for Lua functions */ 79 struct { /* for Lua functions */
81 const Instruction *savedpc; 80 const Instruction *savedpc;
82 const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
83 int tailcalls; /* number of tail calls lost under this entry */ 81 int tailcalls; /* number of tail calls lost under this entry */
84 } l; 82 } l;
85 struct { /* for C functions */ 83 struct { /* for C functions */
@@ -89,20 +87,10 @@ typedef struct CallInfo {
89} CallInfo; 87} CallInfo;
90 88
91 89
92/*
93** bit fields for `CallInfo.state'
94*/
95#define CI_C (1<<0) /* 1 if function is a C function */
96/* 1 if (Lua) function has an active `luaV_execute' running it */
97#define CI_HASFRAME (1<<1)
98/* 1 if Lua function is calling another Lua function (and therefore its
99 `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */
100#define CI_CALLING (1<<2)
101#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */
102#define CI_YIELD (1<<4) /* 1 if thread is suspended */
103
104 90
105#define ci_func(ci) (clvalue((ci)->base - 1)) 91#define ci_func(ci) (clvalue((ci)->base - 1))
92#define f_isLua(ci) (!ci_func(ci)->c.isC)
93#define isLua(ci) (ttisfunction((ci)->base - 1) && f_isLua(ci))
106 94
107 95
108/* 96/*
@@ -143,7 +131,7 @@ struct lua_State {
143 unsigned short nCcalls; /* number of nested C calls */ 131 unsigned short nCcalls; /* number of nested C calls */
144 lu_byte hookmask; 132 lu_byte hookmask;
145 lu_byte allowhook; 133 lu_byte allowhook;
146 lu_byte hookinit; 134 lu_byte isSuspended;
147 int basehookcount; 135 int basehookcount;
148 int hookcount; 136 int hookcount;
149 lua_Hook hook; 137 lua_Hook hook;
diff --git a/lvm.c b/lvm.c
index b8ac9ec8..e10763d6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.287 2003/05/14 12:09:12 roberto Exp roberto $ 2** $Id: lvm.c,v 1.288 2003/07/07 13:37:56 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -64,8 +64,11 @@ int luaV_tostring (lua_State *L, StkId obj) {
64} 64}
65 65
66 66
67static void traceexec (lua_State *L) { 67static void traceexec (lua_State *L, const Instruction *pc) {
68 lu_byte mask = L->hookmask; 68 lu_byte mask = L->hookmask;
69 CallInfo *ci = L->ci;
70 const Instruction *oldpc = ci->u.l.savedpc;
71 ci->u.l.savedpc = pc;
69 if (mask > LUA_MASKLINE) { /* instruction-hook set? */ 72 if (mask > LUA_MASKLINE) { /* instruction-hook set? */
70 if (L->hookcount == 0) { 73 if (L->hookcount == 0) {
71 resethookcount(L); 74 resethookcount(L);
@@ -74,25 +77,13 @@ static void traceexec (lua_State *L) {
74 } 77 }
75 } 78 }
76 if (mask & LUA_MASKLINE) { 79 if (mask & LUA_MASKLINE) {
77 CallInfo *ci = L->ci;
78 Proto *p = ci_func(ci)->l.p; 80 Proto *p = ci_func(ci)->l.p;
79 int pc = pcRel(*ci->u.l.pc, p); 81 int npc = pcRel(pc, p);
80 int newline = getline(p, pc); 82 int newline = getline(p, npc);
81 if (!L->hookinit) { 83 /* call linehook when enter a new function, when jump back (loop),
82 luaG_inithooks(L); 84 or when enter a new line */
83 if (pc != 0) /* not function start? */ 85 if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
84 return; /* begin tracing on next line */
85 }
86 lua_assert(ci->state & CI_HASFRAME);
87 if (pc == 0) /* function may be starting now? */
88 ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */
89 /* calls linehook when enters a new line or jumps back (loop) */
90 if (*ci->u.l.pc <= ci->u.l.savedpc ||
91 newline != getline(p, pcRel(ci->u.l.savedpc, p))) {
92 luaD_callhook(L, LUA_HOOKLINE, newline); 86 luaD_callhook(L, LUA_HOOKLINE, newline);
93 ci = L->ci; /* previous call may reallocate `ci' */
94 }
95 ci->u.l.savedpc = *ci->u.l.pc;
96 } 87 }
97} 88}
98 89
@@ -327,10 +318,11 @@ void luaV_concat (lua_State *L, int total, int last) {
327} 318}
328 319
329 320
330static void Arith (lua_State *L, StkId ra, 321static StkId Arith (lua_State *L, StkId ra, const TObject *rb,
331 const TObject *rb, const TObject *rc, TMS op) { 322 const TObject *rc, TMS op, const Instruction *pc) {
332 TObject tempb, tempc; 323 TObject tempb, tempc;
333 const TObject *b, *c; 324 const TObject *b, *c;
325 L->ci->u.l.savedpc = pc;
334 if ((b = luaV_tonumber(rb, &tempb)) != NULL && 326 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
335 (c = luaV_tonumber(rc, &tempc)) != NULL) { 327 (c = luaV_tonumber(rc, &tempc)) != NULL) {
336 switch (op) { 328 switch (op) {
@@ -350,6 +342,7 @@ static void Arith (lua_State *L, StkId ra,
350 } 342 }
351 else if (!call_binTM(L, rb, rc, ra, op)) 343 else if (!call_binTM(L, rb, rc, ra, op))
352 luaG_aritherror(L, rb, rc); 344 luaG_aritherror(L, rb, rc);
345 return L->base;
353} 346}
354 347
355 348
@@ -362,7 +355,6 @@ static void Arith (lua_State *L, StkId ra,
362 355
363#define RA(i) (base+GETARG_A(i)) 356#define RA(i) (base+GETARG_A(i))
364/* to be used after possible stack reallocation */ 357/* to be used after possible stack reallocation */
365#define XRA(i) (L->base+GETARG_A(i))
366#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) 358#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
367#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) 359#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
368#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ 360#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
@@ -375,39 +367,35 @@ static void Arith (lua_State *L, StkId ra,
375#define dojump(pc, i) ((pc) += (i)) 367#define dojump(pc, i) ((pc) += (i))
376 368
377 369
378StkId luaV_execute (lua_State *L) { 370StkId luaV_execute (lua_State *L, int nexeccalls) {
379 LClosure *cl; 371 LClosure *cl;
380 TObject *k; 372 TObject *k;
373 StkId base;
381 const Instruction *pc; 374 const Instruction *pc;
382 callentry: /* entry point when calling new functions */ 375 callentry: /* entry point when calling new functions */
383 L->ci->u.l.pc = &pc;
384 if (L->hookmask & LUA_MASKCALL) 376 if (L->hookmask & LUA_MASKCALL)
385 luaD_callhook(L, LUA_HOOKCALL, -1); 377 luaD_callhook(L, LUA_HOOKCALL, -1);
386 retentry: /* entry point when returning to old functions */ 378 retentry: /* entry point when returning to old functions */
387 lua_assert(L->ci->state == CI_SAVEDPC ||
388 L->ci->state == (CI_SAVEDPC | CI_CALLING));
389 L->ci->state = CI_HASFRAME; /* activate frame */
390 pc = L->ci->u.l.savedpc; 379 pc = L->ci->u.l.savedpc;
391 cl = &clvalue(L->base - 1)->l; 380 base = L->base;
381 cl = &clvalue(base - 1)->l;
392 k = cl->p->k; 382 k = cl->p->k;
393 /* main loop of interpreter */ 383 /* main loop of interpreter */
394 for (;;) { 384 for (;;) {
395 const Instruction i = *pc++; 385 const Instruction i = *pc++;
396 StkId base, ra; 386 StkId ra;
397 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && 387 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
398 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { 388 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
399 traceexec(L); 389 traceexec(L, pc); /***/
400 if (L->ci->state & CI_YIELD) { /* did hook yield? */ 390 if (L->isSuspended) { /* did hook yield? */
401 L->ci->u.l.savedpc = pc - 1; 391 L->ci->u.l.savedpc = pc - 1;
402 L->ci->state = CI_YIELD | CI_SAVEDPC;
403 return NULL; 392 return NULL;
404 } 393 }
394 base = L->base;
405 } 395 }
406 /* warning!! several calls may realloc the stack and invalidate `ra' */ 396 /* warning!! several calls may realloc the stack and invalidate `ra' */
407 base = L->base;
408 ra = RA(i); 397 ra = RA(i);
409 lua_assert(L->ci->state & CI_HASFRAME); 398 lua_assert(base == L->ci->base && base == L->base);
410 lua_assert(base == L->ci->base);
411 lua_assert(L->top <= L->stack + L->stacksize && L->top >= base); 399 lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
412 lua_assert(L->top == L->ci->top || 400 lua_assert(L->top == L->ci->top ||
413 GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || 401 GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
@@ -441,16 +429,22 @@ StkId luaV_execute (lua_State *L) {
441 case OP_GETGLOBAL: { 429 case OP_GETGLOBAL: {
442 TObject *rb = KBx(i); 430 TObject *rb = KBx(i);
443 lua_assert(ttisstring(rb) && ttistable(&cl->g)); 431 lua_assert(ttisstring(rb) && ttistable(&cl->g));
444 luaV_gettable(L, &cl->g, rb, ra); 432 L->ci->u.l.savedpc = pc;
433 luaV_gettable(L, &cl->g, rb, ra); /***/
434 base = L->base;
445 break; 435 break;
446 } 436 }
447 case OP_GETTABLE: { 437 case OP_GETTABLE: {
448 luaV_gettable(L, RB(i), RKC(i), ra); 438 L->ci->u.l.savedpc = pc;
439 luaV_gettable(L, RB(i), RKC(i), ra); /***/
440 base = L->base;
449 break; 441 break;
450 } 442 }
451 case OP_SETGLOBAL: { 443 case OP_SETGLOBAL: {
452 lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); 444 lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
453 luaV_settable(L, &cl->g, KBx(i), ra); 445 L->ci->u.l.savedpc = pc;
446 luaV_settable(L, &cl->g, KBx(i), ra); /***/
447 base = L->base;
454 break; 448 break;
455 } 449 }
456 case OP_SETUPVAL: { 450 case OP_SETUPVAL: {
@@ -459,20 +453,26 @@ StkId luaV_execute (lua_State *L) {
459 break; 453 break;
460 } 454 }
461 case OP_SETTABLE: { 455 case OP_SETTABLE: {
462 luaV_settable(L, ra, RKB(i), RKC(i)); 456 L->ci->u.l.savedpc = pc;
457 luaV_settable(L, ra, RKB(i), RKC(i)); /***/
458 base = L->base;
463 break; 459 break;
464 } 460 }
465 case OP_NEWTABLE: { 461 case OP_NEWTABLE: {
466 int b = GETARG_B(i); 462 int b = GETARG_B(i);
467 b = fb2int(b); 463 b = fb2int(b);
468 sethvalue(ra, luaH_new(L, b, GETARG_C(i))); 464 sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
469 luaC_checkGC(L); 465 L->ci->u.l.savedpc = pc;
466 luaC_checkGC(L); /***/
467 base = L->base;
470 break; 468 break;
471 } 469 }
472 case OP_SELF: { 470 case OP_SELF: {
473 StkId rb = RB(i); 471 StkId rb = RB(i);
474 setobjs2s(ra+1, rb); 472 setobjs2s(ra+1, rb);
475 luaV_gettable(L, rb, RKC(i), ra); 473 L->ci->u.l.savedpc = pc;
474 luaV_gettable(L, rb, RKC(i), ra); /***/
475 base = L->base;
476 break; 476 break;
477 } 477 }
478 case OP_ADD: { 478 case OP_ADD: {
@@ -482,7 +482,7 @@ StkId luaV_execute (lua_State *L) {
482 setnvalue(ra, nvalue(rb) + nvalue(rc)); 482 setnvalue(ra, nvalue(rb) + nvalue(rc));
483 } 483 }
484 else 484 else
485 Arith(L, ra, rb, rc, TM_ADD); 485 base = Arith(L, ra, rb, rc, TM_ADD, pc); /***/
486 break; 486 break;
487 } 487 }
488 case OP_SUB: { 488 case OP_SUB: {
@@ -492,7 +492,7 @@ StkId luaV_execute (lua_State *L) {
492 setnvalue(ra, nvalue(rb) - nvalue(rc)); 492 setnvalue(ra, nvalue(rb) - nvalue(rc));
493 } 493 }
494 else 494 else
495 Arith(L, ra, rb, rc, TM_SUB); 495 base = Arith(L, ra, rb, rc, TM_SUB, pc); /***/
496 break; 496 break;
497 } 497 }
498 case OP_MUL: { 498 case OP_MUL: {
@@ -502,7 +502,7 @@ StkId luaV_execute (lua_State *L) {
502 setnvalue(ra, nvalue(rb) * nvalue(rc)); 502 setnvalue(ra, nvalue(rb) * nvalue(rc));
503 } 503 }
504 else 504 else
505 Arith(L, ra, rb, rc, TM_MUL); 505 base = Arith(L, ra, rb, rc, TM_MUL, pc); /***/
506 break; 506 break;
507 } 507 }
508 case OP_DIV: { 508 case OP_DIV: {
@@ -512,11 +512,11 @@ StkId luaV_execute (lua_State *L) {
512 setnvalue(ra, nvalue(rb) / nvalue(rc)); 512 setnvalue(ra, nvalue(rb) / nvalue(rc));
513 } 513 }
514 else 514 else
515 Arith(L, ra, rb, rc, TM_DIV); 515 base = Arith(L, ra, rb, rc, TM_DIV, pc); /***/
516 break; 516 break;
517 } 517 }
518 case OP_POW: { 518 case OP_POW: {
519 Arith(L, ra, RKB(i), RKC(i), TM_POW); 519 base = Arith(L, ra, RKB(i), RKC(i), TM_POW, pc); /***/
520 break; 520 break;
521 } 521 }
522 case OP_UNM: { 522 case OP_UNM: {
@@ -527,8 +527,10 @@ StkId luaV_execute (lua_State *L) {
527 } 527 }
528 else { 528 else {
529 setnilvalue(&temp); 529 setnilvalue(&temp);
530 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) 530 L->ci->u.l.savedpc = pc;
531 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/
531 luaG_aritherror(L, RB(i), &temp); 532 luaG_aritherror(L, RB(i), &temp);
533 base = L->base;
532 } 534 }
533 break; 535 break;
534 } 536 }
@@ -540,10 +542,11 @@ StkId luaV_execute (lua_State *L) {
540 case OP_CONCAT: { 542 case OP_CONCAT: {
541 int b = GETARG_B(i); 543 int b = GETARG_B(i);
542 int c = GETARG_C(i); 544 int c = GETARG_C(i);
543 luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ 545 L->ci->u.l.savedpc = pc;
546 luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/
547 luaC_checkGC(L); /***/
544 base = L->base; 548 base = L->base;
545 setobjs2s(RA(i), base+b); 549 setobjs2s(RA(i), base+b);
546 luaC_checkGC(L);
547 break; 550 break;
548 } 551 }
549 case OP_JMP: { 552 case OP_JMP: {
@@ -551,18 +554,24 @@ StkId luaV_execute (lua_State *L) {
551 break; 554 break;
552 } 555 }
553 case OP_EQ: { 556 case OP_EQ: {
554 if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; 557 L->ci->u.l.savedpc = pc;
558 if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
555 else dojump(pc, GETARG_sBx(*pc) + 1); 559 else dojump(pc, GETARG_sBx(*pc) + 1);
560 base = L->base;
556 break; 561 break;
557 } 562 }
558 case OP_LT: { 563 case OP_LT: {
559 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; 564 L->ci->u.l.savedpc = pc;
565 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
560 else dojump(pc, GETARG_sBx(*pc) + 1); 566 else dojump(pc, GETARG_sBx(*pc) + 1);
567 base = L->base;
561 break; 568 break;
562 } 569 }
563 case OP_LE: { 570 case OP_LE: {
564 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; 571 L->ci->u.l.savedpc = pc;
572 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
565 else dojump(pc, GETARG_sBx(*pc) + 1); 573 else dojump(pc, GETARG_sBx(*pc) + 1);
574 base = L->base;
566 break; 575 break;
567 } 576 }
568 case OP_TEST: { 577 case OP_TEST: {
@@ -575,18 +584,16 @@ StkId luaV_execute (lua_State *L) {
575 break; 584 break;
576 } 585 }
577 case OP_CALL: 586 case OP_CALL:
578 case OP_TAILCALL: { 587 case OP_TAILCALL: { /***/
579 StkId firstResult; 588 StkId firstResult;
580 int b = GETARG_B(i); 589 int b = GETARG_B(i);
581 int nresults;
582 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 590 if (b != 0) L->top = ra+b; /* else previous instruction set top */
583 nresults = GETARG_C(i) - 1; 591 L->ci->u.l.savedpc = pc;
584 firstResult = luaD_precall(L, ra); 592 firstResult = luaD_precall(L, ra);
585 if (firstResult) { 593 if (firstResult) {
594 int nresults = GETARG_C(i) - 1;
586 if (firstResult > L->top) { /* yield? */ 595 if (firstResult > L->top) { /* yield? */
587 lua_assert(L->ci->state == (CI_C | CI_YIELD));
588 (L->ci - 1)->u.l.savedpc = pc; 596 (L->ci - 1)->u.l.savedpc = pc;
589 (L->ci - 1)->state = CI_SAVEDPC;
590 return NULL; 597 return NULL;
591 } 598 }
592 /* it was a C function (`precall' called it); adjust results */ 599 /* it was a C function (`precall' called it); adjust results */
@@ -594,10 +601,8 @@ StkId luaV_execute (lua_State *L) {
594 if (nresults >= 0) L->top = L->ci->top; 601 if (nresults >= 0) L->top = L->ci->top;
595 } 602 }
596 else { /* it is a Lua function */ 603 else { /* it is a Lua function */
597 if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ 604 if (GET_OPCODE(i) == OP_CALL) /* regular call? */
598 (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ 605 nexeccalls++;
599 (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
600 }
601 else { /* tail call: put new frame in place of previous one */ 606 else { /* tail call: put new frame in place of previous one */
602 int aux; 607 int aux;
603 base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */ 608 base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */
@@ -606,35 +611,27 @@ StkId luaV_execute (lua_State *L) {
606 for (aux = 0; ra+aux < L->top; aux++) /* move frame down */ 611 for (aux = 0; ra+aux < L->top; aux++) /* move frame down */
607 setobjs2s(base+aux-1, ra+aux); 612 setobjs2s(base+aux-1, ra+aux);
608 (L->ci - 1)->top = L->top = base+aux; /* correct top */ 613 (L->ci - 1)->top = L->top = base+aux; /* correct top */
609 lua_assert(L->ci->state & CI_SAVEDPC);
610 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; 614 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
611 (L->ci - 1)->u.l.tailcalls++; /* one more call lost */ 615 (L->ci - 1)->u.l.tailcalls++; /* one more call lost */
612 (L->ci - 1)->state = CI_SAVEDPC;
613 L->ci--; /* remove new frame */ 616 L->ci--; /* remove new frame */
614 L->base = L->ci->base; 617 L->base = L->ci->base;
615 } 618 }
616 goto callentry; 619 goto callentry;
617 } 620 }
621 base = L->base;
618 break; 622 break;
619 } 623 }
620 case OP_RETURN: { 624 case OP_RETURN: {
621 CallInfo *ci = L->ci - 1; /* previous function frame */ 625 CallInfo *ci = L->ci - 1; /* previous function frame */
622 int b = GETARG_B(i); 626 int b = GETARG_B(i);
623 if (b != 0) L->top = ra+b-1; 627 if (b != 0) L->top = ra+b-1;
624 lua_assert(L->ci->state & CI_HASFRAME);
625 if (L->openupval) luaF_close(L, base); 628 if (L->openupval) luaF_close(L, base);
626 L->ci->state = CI_SAVEDPC; /* deactivate current function */
627 L->ci->u.l.savedpc = pc; 629 L->ci->u.l.savedpc = pc;
628 /* previous function was running `here'? */ 630 if (--nexeccalls == 0) /* was previous function running `here'? */
629 if (!(ci->state & CI_CALLING)) {
630 lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
631 return ra; /* no: return */ 631 return ra; /* no: return */
632 }
633 else { /* yes: continue its execution */ 632 else { /* yes: continue its execution */
634 int nresults; 633 int nresults;
635 lua_assert(ci->u.l.pc == &pc && 634 lua_assert(isLua(ci));
636 ttisfunction(ci->base - 1) &&
637 (ci->state & CI_SAVEDPC));
638 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); 635 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
639 nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; 636 nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
640 luaD_poscall(L, nresults, ra); 637 luaD_poscall(L, nresults, ra);
@@ -653,10 +650,11 @@ StkId luaV_execute (lua_State *L) {
653 } 650 }
654 break; 651 break;
655 } 652 }
656 case OP_FORPREP: { 653 case OP_FORPREP: { /***/
657 const TObject *init = ra; 654 const TObject *init = ra;
658 const TObject *plimit = ra+1; 655 const TObject *plimit = ra+1;
659 const TObject *pstep = ra+2; 656 const TObject *pstep = ra+2;
657 L->ci->u.l.savedpc = pc;
660 if (!tonumber(init, ra)) 658 if (!tonumber(init, ra))
661 luaG_runerror(L, "`for' initial value must be a number"); 659 luaG_runerror(L, "`for' initial value must be a number");
662 else if (!tonumber(plimit, ra+1)) 660 else if (!tonumber(plimit, ra+1))
@@ -673,9 +671,11 @@ StkId luaV_execute (lua_State *L) {
673 setobjs2s(cb+1, ra+1); 671 setobjs2s(cb+1, ra+1);
674 setobjs2s(cb, ra); 672 setobjs2s(cb, ra);
675 L->top = cb+3; /* func. + 2 args (state and index) */ 673 L->top = cb+3; /* func. + 2 args (state and index) */
676 luaD_call(L, cb, GETARG_C(i)); 674 L->ci->u.l.savedpc = pc;
675 luaD_call(L, cb, GETARG_C(i)); /***/
677 L->top = L->ci->top; 676 L->top = L->ci->top;
678 cb = XRA(i) + 3; /* previous call may change the stack */ 677 base = L->base;
678 cb = RA(i) + 3; /* previous call may change the stack */
679 if (ttisnil(cb)) /* break loop? */ 679 if (ttisnil(cb)) /* break loop? */
680 pc++; /* skip jump (break loop) */ 680 pc++; /* skip jump (break loop) */
681 else { 681 else {
@@ -732,7 +732,9 @@ StkId luaV_execute (lua_State *L) {
732 } 732 }
733 } 733 }
734 setclvalue(ra, ncl); 734 setclvalue(ra, ncl);
735 luaC_checkGC(L); 735 L->ci->u.l.savedpc = pc;
736 luaC_checkGC(L); /***/
737 base = L->base;
736 break; 738 break;
737 } 739 }
738 } 740 }
diff --git a/lvm.h b/lvm.h
index 667b25bb..b2d9f8d5 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.47 2002/11/14 16:16:21 roberto Exp roberto $ 2** $Id: lvm.h,v 1.48 2003/05/05 18:39:57 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -28,7 +28,7 @@ const TObject *luaV_tonumber (const TObject *obj, TObject *n);
28int luaV_tostring (lua_State *L, StkId obj); 28int luaV_tostring (lua_State *L, StkId obj);
29void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId val); 29void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId val);
30void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); 30void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val);
31StkId luaV_execute (lua_State *L); 31StkId luaV_execute (lua_State *L, int nexeccalls);
32void luaV_concat (lua_State *L, int total, int last); 32void luaV_concat (lua_State *L, int total, int last);
33 33
34#endif 34#endif