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 | ||
