diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-18 18:52:30 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-18 18:52:30 -0200 |
commit | e04f7ed4509af1577c10ead8e5d7d55c65754bf8 (patch) | |
tree | 36cfd31846b6f49c505adfbd1311ed1794689127 | |
parent | 101cee3032918bae8a5fa9dfc334c478c4aa15f6 (diff) | |
download | lua-e04f7ed4509af1577c10ead8e5d7d55c65754bf8.tar.gz lua-e04f7ed4509af1577c10ead8e5d7d55c65754bf8.tar.bz2 lua-e04f7ed4509af1577c10ead8e5d7d55c65754bf8.zip |
first version of Lua "stackless"
-rw-r--r-- | lapi.c | 4 | ||||
-rw-r--r-- | ldebug.c | 40 | ||||
-rw-r--r-- | ldo.h | 7 | ||||
-rw-r--r-- | lgc.c | 3 | ||||
-rw-r--r-- | lobject.h | 14 | ||||
-rw-r--r-- | lstate.c | 5 | ||||
-rw-r--r-- | lstate.h | 22 | ||||
-rw-r--r-- | luadebug.h | 4 |
8 files changed, 49 insertions, 50 deletions
@@ -517,9 +517,7 @@ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { | |||
517 | lua_lock(L); | 517 | lua_lock(L); |
518 | api_checknelems(L, nargs+1); | 518 | api_checknelems(L, nargs+1); |
519 | func = L->top - (nargs+1); | 519 | func = L->top - (nargs+1); |
520 | luaD_call(L, func); | 520 | luaD_call(L, func, nresults); |
521 | if (nresults != LUA_MULTRET) | ||
522 | luaD_adjusttop(L, func + nresults); | ||
523 | lua_unlock(L); | 521 | lua_unlock(L); |
524 | } | 522 | } |
525 | 523 | ||
@@ -31,8 +31,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, | |||
31 | 31 | ||
32 | 32 | ||
33 | static int isLmark (CallInfo *ci) { | 33 | static int isLmark (CallInfo *ci) { |
34 | lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION); | 34 | return (ttype(ci->base - 1) == LUA_TFUNCTION && !ci_func(ci)->c.isC); |
35 | return (ci && ci->prev && !ci_func(ci)->c.isC); | ||
36 | } | 35 | } |
37 | 36 | ||
38 | 37 | ||
@@ -58,23 +57,17 @@ LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) { | |||
58 | 57 | ||
59 | static CallInfo *ci_stack (lua_State *L, StkId obj) { | 58 | static CallInfo *ci_stack (lua_State *L, StkId obj) { |
60 | CallInfo *ci = L->ci; | 59 | CallInfo *ci = L->ci; |
61 | while (ci->base > obj) ci = ci->prev; | 60 | while (ci->base > obj) ci--; |
62 | return (ci != &L->basefunc) ? ci : NULL; | 61 | return ci; |
63 | } | 62 | } |
64 | 63 | ||
65 | 64 | ||
66 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | 65 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { |
67 | CallInfo *ci; | ||
68 | int status; | 66 | int status; |
69 | lua_lock(L); | 67 | lua_lock(L); |
70 | ci = L->ci; | 68 | if (L->ci - L->base_ci <= level) status = 0; /* there is no such level */ |
71 | while (level-- && ci != &L->basefunc) { | ||
72 | lua_assert(ci->base > ci->prev->base); | ||
73 | ci = ci->prev; | ||
74 | } | ||
75 | if (ci == &L->basefunc) status = 0; /* there is no such level */ | ||
76 | else { | 69 | else { |
77 | ar->_ci = ci; | 70 | ar->_ci = (L->ci - L->base_ci) - level; |
78 | status = 1; | 71 | status = 1; |
79 | } | 72 | } |
80 | lua_unlock(L); | 73 | lua_unlock(L); |
@@ -84,8 +77,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | |||
84 | 77 | ||
85 | int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { | 78 | int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { |
86 | int refi; | 79 | int refi; |
87 | if (lineinfo == NULL || pc == -1) | 80 | if (lineinfo == NULL) return -1; /* no line info */ |
88 | return -1; /* no line info or function is not active */ | ||
89 | refi = prefi ? *prefi : 0; | 81 | refi = prefi ? *prefi : 0; |
90 | if (lineinfo[refi] < 0) | 82 | if (lineinfo[refi] < 0) |
91 | refline += -lineinfo[refi++]; | 83 | refline += -lineinfo[refi++]; |
@@ -115,10 +107,11 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { | |||
115 | 107 | ||
116 | static int currentpc (CallInfo *ci) { | 108 | static int currentpc (CallInfo *ci) { |
117 | lua_assert(isLmark(ci)); | 109 | lua_assert(isLmark(ci)); |
118 | if (ci->pc) | 110 | if (ci->savedpc) |
111 | return (ci->savedpc - ci_func(ci)->l.p->code) - 1; | ||
112 | else if (ci->pc) | ||
119 | return (*ci->pc - ci_func(ci)->l.p->code) - 1; | 113 | return (*ci->pc - ci_func(ci)->l.p->code) - 1; |
120 | else | 114 | else return 0; |
121 | return -1; /* function is not active */ | ||
122 | } | 115 | } |
123 | 116 | ||
124 | 117 | ||
@@ -144,7 +137,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
144 | Proto *fp; | 137 | Proto *fp; |
145 | lua_lock(L); | 138 | lua_lock(L); |
146 | name = NULL; | 139 | name = NULL; |
147 | ci = ar->_ci; | 140 | ci = L->base_ci + ar->_ci; |
148 | fp = getluaproto(ci); | 141 | fp = getluaproto(ci); |
149 | if (fp) { /* is a Lua function? */ | 142 | if (fp) { /* is a Lua function? */ |
150 | name = luaF_getlocalname(fp, n, currentpc(ci)); | 143 | name = luaF_getlocalname(fp, n, currentpc(ci)); |
@@ -162,7 +155,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
162 | Proto *fp; | 155 | Proto *fp; |
163 | lua_lock(L); | 156 | lua_lock(L); |
164 | name = NULL; | 157 | name = NULL; |
165 | ci = ar->_ci; | 158 | ci = L->base_ci + ar->_ci; |
166 | fp = getluaproto(ci); | 159 | fp = getluaproto(ci); |
167 | L->top--; /* pop new value */ | 160 | L->top--; /* pop new value */ |
168 | if (fp) { /* is a Lua function? */ | 161 | if (fp) { /* is a Lua function? */ |
@@ -231,7 +224,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
231 | int status = 1; | 224 | int status = 1; |
232 | lua_lock(L); | 225 | lua_lock(L); |
233 | if (*what != '>') { /* function is active? */ | 226 | if (*what != '>') { /* function is active? */ |
234 | ci = ar->_ci; | 227 | ci = L->base_ci + ar->_ci; |
235 | f = ci->base - 1; | 228 | f = ci->base - 1; |
236 | } | 229 | } |
237 | else { | 230 | else { |
@@ -246,7 +239,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
246 | break; | 239 | break; |
247 | } | 240 | } |
248 | case 'l': { | 241 | case 'l': { |
249 | ar->currentline = currentline(ci); | 242 | ar->currentline = (ci) ? currentline(ci) : -1; |
250 | break; | 243 | break; |
251 | } | 244 | } |
252 | case 'u': { | 245 | case 'u': { |
@@ -495,14 +488,13 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) { | |||
495 | 488 | ||
496 | static const char *getfuncname (lua_State *L, CallInfo *ci, | 489 | static const char *getfuncname (lua_State *L, CallInfo *ci, |
497 | const char **name) { | 490 | const char **name) { |
498 | ci = ci->prev; /* calling function */ | 491 | ci--; /* calling function */ |
499 | if (ci == &L->basefunc || !isLmark(ci)) | 492 | if (ci == L->base_ci || !isLmark(ci)) |
500 | return NULL; /* not an active Lua function */ | 493 | return NULL; /* not an active Lua function */ |
501 | else { | 494 | else { |
502 | Proto *p = ci_func(ci)->l.p; | 495 | Proto *p = ci_func(ci)->l.p; |
503 | int pc = currentpc(ci); | 496 | int pc = currentpc(ci); |
504 | Instruction i; | 497 | Instruction i; |
505 | if (pc == -1) return NULL; /* function is not activated */ | ||
506 | i = p->code[pc]; | 498 | i = p->code[pc]; |
507 | return (GET_OPCODE(i) == OP_CALL | 499 | return (GET_OPCODE(i) == OP_CALL |
508 | ? getobjname(L, ci->base+GETARG_A(i), name) | 500 | ? getobjname(L, ci->base+GETARG_A(i), name) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 1.34 2001/06/08 19:00:57 roberto Exp $ | 2 | ** $Id: ldo.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ |
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 | */ |
@@ -25,7 +25,10 @@ | |||
25 | void luaD_init (lua_State *L, int stacksize); | 25 | void luaD_init (lua_State *L, int stacksize); |
26 | void luaD_adjusttop (lua_State *L, StkId newtop); | 26 | void luaD_adjusttop (lua_State *L, StkId newtop); |
27 | void luaD_lineHook (lua_State *L, int line, lua_Hook linehook); | 27 | void luaD_lineHook (lua_State *L, int line, lua_Hook linehook); |
28 | void luaD_call (lua_State *L, StkId func); | 28 | void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event); |
29 | StkId luaD_precall (lua_State *L, StkId func); | ||
30 | void luaD_call (lua_State *L, StkId func, int nResults); | ||
31 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult); | ||
29 | void luaD_stackerror (lua_State *L); | 32 | void luaD_stackerror (lua_State *L); |
30 | 33 | ||
31 | void luaD_error (lua_State *L, const char *s); | 34 | void luaD_error (lua_State *L, const char *s); |
@@ -363,8 +363,7 @@ static void do1gcTM (lua_State *L, Udata *udata) { | |||
363 | setobj(top, tm); | 363 | setobj(top, tm); |
364 | setuvalue(top+1, udata); | 364 | setuvalue(top+1, udata); |
365 | L->top += 2; | 365 | L->top += 2; |
366 | luaD_call(L, top); | 366 | luaD_call(L, top, 0); |
367 | L->top = top; /* restore top */ | ||
368 | } | 367 | } |
369 | } | 368 | } |
370 | 369 | ||
@@ -248,20 +248,6 @@ typedef struct Table { | |||
248 | #define sizenode(t) (twoto((t)->lsizenode)) | 248 | #define sizenode(t) (twoto((t)->lsizenode)) |
249 | #define sizearray(t) ((t)->sizearray) | 249 | #define sizearray(t) ((t)->sizearray) |
250 | 250 | ||
251 | /* | ||
252 | ** informations about a call (for debugging) | ||
253 | */ | ||
254 | typedef struct CallInfo { | ||
255 | struct CallInfo *prev; /* linked list */ | ||
256 | StkId base; /* base for called function */ | ||
257 | const Instruction **pc; /* current pc of called function */ | ||
258 | int lastpc; /* last pc traced */ | ||
259 | int line; /* current line */ | ||
260 | int refi; /* current index in `lineinfo' */ | ||
261 | } CallInfo; | ||
262 | |||
263 | #define ci_func(ci) (clvalue((ci)->base - 1)) | ||
264 | |||
265 | 251 | ||
266 | extern const TObject luaO_nilobject; | 252 | extern const TObject luaO_nilobject; |
267 | 253 | ||
@@ -87,12 +87,12 @@ LUA_API lua_State *lua_newthread (lua_State *OL, int stacksize) { | |||
87 | L->_G = NULL; | 87 | L->_G = NULL; |
88 | L->stack = NULL; | 88 | L->stack = NULL; |
89 | L->stacksize = 0; | 89 | L->stacksize = 0; |
90 | L->ci = &L->basefunc; | ||
91 | L->basefunc.prev = NULL; | ||
92 | L->errorJmp = NULL; | 90 | L->errorJmp = NULL; |
93 | L->callhook = NULL; | 91 | L->callhook = NULL; |
94 | L->linehook = NULL; | 92 | L->linehook = NULL; |
95 | L->openupval = NULL; | 93 | L->openupval = NULL; |
94 | L->size_ci = 0; | ||
95 | L->base_ci = NULL; | ||
96 | L->allowhooks = 1; | 96 | L->allowhooks = 1; |
97 | L->next = L->previous = L; | 97 | L->next = L->previous = L; |
98 | so.stacksize = stacksize; | 98 | so.stacksize = stacksize; |
@@ -130,6 +130,7 @@ static void close_state (lua_State *L, lua_State *OL) { | |||
130 | luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char); | 130 | luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char); |
131 | luaM_freelem(NULL, L->_G); | 131 | luaM_freelem(NULL, L->_G); |
132 | } | 132 | } |
133 | luaM_freearray(OL, L->base_ci, L->size_ci, CallInfo); | ||
133 | luaM_freearray(OL, L->stack, L->stacksize, TObject); | 134 | luaM_freearray(OL, L->stack, L->stacksize, TObject); |
134 | luaM_freelem(OL, L); | 135 | luaM_freelem(OL, L); |
135 | } | 136 | } |
@@ -70,6 +70,24 @@ typedef struct stringtable { | |||
70 | 70 | ||
71 | 71 | ||
72 | /* | 72 | /* |
73 | ** informations about a call | ||
74 | */ | ||
75 | typedef struct CallInfo { | ||
76 | StkId base; /* base for called function */ | ||
77 | const Instruction *savedpc; | ||
78 | lua_Hook linehook; | ||
79 | /* extra information for debugging */ | ||
80 | const Instruction **pc; | ||
81 | int lastpc; /* last pc traced */ | ||
82 | int line; /* current line */ | ||
83 | int refi; /* current index in `lineinfo' */ | ||
84 | } CallInfo; | ||
85 | |||
86 | #define ci_func(ci) (clvalue((ci)->base - 1)) | ||
87 | |||
88 | |||
89 | |||
90 | /* | ||
73 | ** `global state', shared by all threads of this state | 91 | ** `global state', shared by all threads of this state |
74 | */ | 92 | */ |
75 | typedef struct global_State { | 93 | typedef struct global_State { |
@@ -98,6 +116,9 @@ struct lua_State { | |||
98 | StkId stack_last; /* last free slot in the stack */ | 116 | StkId stack_last; /* last free slot in the stack */ |
99 | StkId stack; /* stack base */ | 117 | StkId stack; /* stack base */ |
100 | int stacksize; | 118 | int stacksize; |
119 | CallInfo *end_ci; /* points after end of ci array*/ | ||
120 | CallInfo *base_ci; /* array of CallInfo's */ | ||
121 | int size_ci; /* size of array `base_ci' */ | ||
101 | global_State *_G; | 122 | global_State *_G; |
102 | lua_Hook callhook; | 123 | lua_Hook callhook; |
103 | lua_Hook linehook; | 124 | lua_Hook linehook; |
@@ -106,7 +127,6 @@ struct lua_State { | |||
106 | UpVal *openupval; /* list of open upvalues in this stack */ | 127 | UpVal *openupval; /* list of open upvalues in this stack */ |
107 | lua_State *next; /* circular double linked list of states */ | 128 | lua_State *next; /* circular double linked list of states */ |
108 | lua_State *previous; | 129 | lua_State *previous; |
109 | CallInfo basefunc; | ||
110 | }; | 130 | }; |
111 | 131 | ||
112 | 132 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: luadebug.h,v 1.20 2001/04/06 21:17:37 roberto Exp $ | 2 | ** $Id: luadebug.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ |
3 | ** Debugging API | 3 | ** Debugging API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -39,7 +39,7 @@ struct lua_Debug { | |||
39 | const char *source; /* (S) */ | 39 | const char *source; /* (S) */ |
40 | char short_src[LUA_IDSIZE]; /* (S) */ | 40 | char short_src[LUA_IDSIZE]; /* (S) */ |
41 | /* private part */ | 41 | /* private part */ |
42 | struct CallInfo *_ci; /* active function */ | 42 | int _ci; /* active function */ |
43 | }; | 43 | }; |
44 | 44 | ||
45 | 45 | ||