diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-17 17:29:29 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-17 17:29:29 -0200 |
| commit | 422318f6777d8d3bac13ade797d9c8eaa38686b6 (patch) | |
| tree | 5cfabc21fcebb714daf237bff783fe9630e70582 | |
| parent | 49dae52d0808776f5861eb33efa1d13b05e44512 (diff) | |
| download | lua-422318f6777d8d3bac13ade797d9c8eaa38686b6.tar.gz lua-422318f6777d8d3bac13ade797d9c8eaa38686b6.tar.bz2 lua-422318f6777d8d3bac13ade797d9c8eaa38686b6.zip | |
two new fields 'fTransfer'/'nTransfer' in 'lua_Debug' structure
(for information about values being given and returned in function calls)
| -rw-r--r-- | ldblib.c | 8 | ||||
| -rw-r--r-- | ldebug.c | 14 | ||||
| -rw-r--r-- | ldo.c | 31 | ||||
| -rw-r--r-- | ldo.h | 5 | ||||
| -rw-r--r-- | lstate.h | 9 | ||||
| -rw-r--r-- | lua.h | 4 |
6 files changed, 52 insertions, 19 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.150 2015/11/19 19:16:22 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.151 2015/11/23 11:29:43 roberto Exp roberto $ |
| 3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -146,7 +146,7 @@ static int db_getinfo (lua_State *L) { | |||
| 146 | lua_Debug ar; | 146 | lua_Debug ar; |
| 147 | int arg; | 147 | int arg; |
| 148 | lua_State *L1 = getthread(L, &arg); | 148 | lua_State *L1 = getthread(L, &arg); |
| 149 | const char *options = luaL_optstring(L, arg+2, "flnStu"); | 149 | const char *options = luaL_optstring(L, arg+2, "flnSrtu"); |
| 150 | checkstack(L, L1, 3); | 150 | checkstack(L, L1, 3); |
| 151 | if (lua_isfunction(L, arg + 1)) { /* info about a function? */ | 151 | if (lua_isfunction(L, arg + 1)) { /* info about a function? */ |
| 152 | options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ | 152 | options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ |
| @@ -180,6 +180,10 @@ static int db_getinfo (lua_State *L) { | |||
| 180 | settabss(L, "name", ar.name); | 180 | settabss(L, "name", ar.name); |
| 181 | settabss(L, "namewhat", ar.namewhat); | 181 | settabss(L, "namewhat", ar.namewhat); |
| 182 | } | 182 | } |
| 183 | if (strchr(options, 'r')) { | ||
| 184 | settabsi(L, "fTransfer", ar.fTransfer); | ||
| 185 | settabsi(L, "nTransfer", ar.nTransfer); | ||
| 186 | } | ||
| 183 | if (strchr(options, 't')) | 187 | if (strchr(options, 't')) |
| 184 | settabsb(L, "istailcall", ar.istailcall); | 188 | settabsb(L, "istailcall", ar.istailcall); |
| 185 | if (strchr(options, 'L')) | 189 | if (strchr(options, 'L')) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.153 2018/02/06 19:16:56 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.154 2018/02/09 15:16: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 | */ |
| @@ -356,6 +356,14 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 356 | } | 356 | } |
| 357 | break; | 357 | break; |
| 358 | } | 358 | } |
| 359 | case 'r': { | ||
| 360 | if (ci == NULL || !(ci->callstatus & CIST_TRAN)) | ||
| 361 | ar->fTransfer = ar->nTransfer = 0; | ||
| 362 | else { | ||
| 363 | ar->fTransfer = ci->u2.transferinfo.fTransfer; | ||
| 364 | ar->nTransfer = ci->u2.transferinfo.nTransfer; | ||
| 365 | } | ||
| 366 | } | ||
| 359 | case 'L': | 367 | case 'L': |
| 360 | case 'f': /* handled by lua_getinfo */ | 368 | case 'f': /* handled by lua_getinfo */ |
| 361 | break; | 369 | break; |
| @@ -790,7 +798,7 @@ void luaG_traceexec (lua_State *L) { | |||
| 790 | if (!isIT(*(ci->u.l.savedpc - 1))) | 798 | if (!isIT(*(ci->u.l.savedpc - 1))) |
| 791 | L->top = ci->top; /* prepare top */ | 799 | L->top = ci->top; /* prepare top */ |
| 792 | if (counthook) | 800 | if (counthook) |
| 793 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ | 801 | luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ |
| 794 | if (mask & LUA_MASKLINE) { | 802 | if (mask & LUA_MASKLINE) { |
| 795 | Proto *p = ci_func(ci)->p; | 803 | Proto *p = ci_func(ci)->p; |
| 796 | const Instruction *npc = ci->u.l.savedpc; | 804 | const Instruction *npc = ci->u.l.savedpc; |
| @@ -799,7 +807,7 @@ void luaG_traceexec (lua_State *L) { | |||
| 799 | npc <= L->oldpc || /* when jump back (loop), or when */ | 807 | npc <= L->oldpc || /* when jump back (loop), or when */ |
| 800 | changedline(p, pcRel(L->oldpc, p), npci)) { /* enter new line */ | 808 | changedline(p, pcRel(L->oldpc, p), npci)) { /* enter new line */ |
| 801 | int newline = luaG_getfuncline(p, npci); /* new line */ | 809 | int newline = luaG_getfuncline(p, npci); /* new line */ |
| 802 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ | 810 | luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ |
| 803 | } | 811 | } |
| 804 | L->oldpc = npc; | 812 | L->oldpc = npc; |
| 805 | } | 813 | } |
| @@ -267,9 +267,11 @@ void luaD_inctop (lua_State *L) { | |||
| 267 | ** called. (Both 'L->hook' and 'L->hookmask', which triggers this | 267 | ** called. (Both 'L->hook' and 'L->hookmask', which triggers this |
| 268 | ** function, can be changed asynchronously by signals.) | 268 | ** function, can be changed asynchronously by signals.) |
| 269 | */ | 269 | */ |
| 270 | void luaD_hook (lua_State *L, int event, int line) { | 270 | void luaD_hook (lua_State *L, int event, int line, |
| 271 | int fTransfer, int nTransfer) { | ||
| 271 | lua_Hook hook = L->hook; | 272 | lua_Hook hook = L->hook; |
| 272 | if (hook && L->allowhook) { /* make sure there is a hook */ | 273 | if (hook && L->allowhook) { /* make sure there is a hook */ |
| 274 | int mask = CIST_HOOKED; | ||
| 273 | CallInfo *ci = L->ci; | 275 | CallInfo *ci = L->ci; |
| 274 | ptrdiff_t top = savestack(L, L->top); | 276 | ptrdiff_t top = savestack(L, L->top); |
| 275 | ptrdiff_t ci_top = savestack(L, ci->top); | 277 | ptrdiff_t ci_top = savestack(L, ci->top); |
| @@ -277,11 +279,16 @@ void luaD_hook (lua_State *L, int event, int line) { | |||
| 277 | ar.event = event; | 279 | ar.event = event; |
| 278 | ar.currentline = line; | 280 | ar.currentline = line; |
| 279 | ar.i_ci = ci; | 281 | ar.i_ci = ci; |
| 282 | if (nTransfer != 0) { | ||
| 283 | mask |= CIST_TRAN; /* 'ci' has transfer information */ | ||
| 284 | ci->u2.transferinfo.fTransfer = fTransfer; | ||
| 285 | ci->u2.transferinfo.nTransfer = nTransfer; | ||
| 286 | } | ||
| 280 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 287 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 281 | if (L->top + LUA_MINSTACK > ci->top) | 288 | if (L->top + LUA_MINSTACK > ci->top) |
| 282 | ci->top = L->top + LUA_MINSTACK; | 289 | ci->top = L->top + LUA_MINSTACK; |
| 283 | L->allowhook = 0; /* cannot call hooks inside a hook */ | 290 | L->allowhook = 0; /* cannot call hooks inside a hook */ |
| 284 | ci->callstatus |= CIST_HOOKED; | 291 | ci->callstatus |= mask; |
| 285 | lua_unlock(L); | 292 | lua_unlock(L); |
| 286 | (*hook)(L, &ar); | 293 | (*hook)(L, &ar); |
| 287 | lua_lock(L); | 294 | lua_lock(L); |
| @@ -289,7 +296,7 @@ void luaD_hook (lua_State *L, int event, int line) { | |||
| 289 | L->allowhook = 1; | 296 | L->allowhook = 1; |
| 290 | ci->top = restorestack(L, ci_top); | 297 | ci->top = restorestack(L, ci_top); |
| 291 | L->top = restorestack(L, top); | 298 | L->top = restorestack(L, top); |
| 292 | ci->callstatus &= ~CIST_HOOKED; | 299 | ci->callstatus &= ~mask; |
| 293 | } | 300 | } |
| 294 | } | 301 | } |
| 295 | 302 | ||
| @@ -301,16 +308,18 @@ void luaD_hook (lua_State *L, int event, int line) { | |||
| 301 | */ | 308 | */ |
| 302 | void luaD_hookcall (lua_State *L, CallInfo *ci) { | 309 | void luaD_hookcall (lua_State *L, CallInfo *ci) { |
| 303 | int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL; | 310 | int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL; |
| 311 | Proto *p; | ||
| 304 | if (!(L->hookmask & LUA_MASKCALL)) /* some other hook? */ | 312 | if (!(L->hookmask & LUA_MASKCALL)) /* some other hook? */ |
| 305 | return; /* don't call hook */ | 313 | return; /* don't call hook */ |
| 314 | p = clLvalue(s2v(ci->func))->p; | ||
| 306 | L->top = ci->top; /* prepare top */ | 315 | L->top = ci->top; /* prepare top */ |
| 307 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ | 316 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ |
| 308 | luaD_hook(L, hook, -1); | 317 | luaD_hook(L, hook, -1, 1, p->numparams); |
| 309 | ci->u.l.savedpc--; /* correct 'pc' */ | 318 | ci->u.l.savedpc--; /* correct 'pc' */ |
| 310 | } | 319 | } |
| 311 | 320 | ||
| 312 | 321 | ||
| 313 | static void rethook (lua_State *L, CallInfo *ci) { | 322 | static void rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { |
| 314 | int delta = 0; | 323 | int delta = 0; |
| 315 | if (isLuacode(ci)) { | 324 | if (isLuacode(ci)) { |
| 316 | Proto *p = clLvalue(s2v(ci->func))->p; | 325 | Proto *p = clLvalue(s2v(ci->func))->p; |
| @@ -320,8 +329,10 @@ static void rethook (lua_State *L, CallInfo *ci) { | |||
| 320 | L->top = ci->top; /* correct top */ | 329 | L->top = ci->top; /* correct top */ |
| 321 | } | 330 | } |
| 322 | if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ | 331 | if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ |
| 332 | int fTransfer; | ||
| 323 | ci->func += delta; /* if vararg, back to virtual 'func' */ | 333 | ci->func += delta; /* if vararg, back to virtual 'func' */ |
| 324 | luaD_hook(L, LUA_HOOKRET, -1); /* call it */ | 334 | fTransfer = cast(unsigned short, firstres - ci->func); |
| 335 | luaD_hook(L, LUA_HOOKRET, -1, fTransfer, nres); /* call it */ | ||
| 325 | ci->func -= delta; | 336 | ci->func -= delta; |
| 326 | } | 337 | } |
| 327 | if (isLua(ci->previous)) | 338 | if (isLua(ci->previous)) |
| @@ -396,7 +407,7 @@ static void moveresults (lua_State *L, StkId firstResult, StkId res, | |||
| 396 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { | 407 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { |
| 397 | if (L->hookmask) { | 408 | if (L->hookmask) { |
| 398 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 409 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ |
| 399 | rethook(L, ci); | 410 | rethook(L, ci, firstResult, nres); |
| 400 | firstResult = restorestack(L, fr); | 411 | firstResult = restorestack(L, fr); |
| 401 | } | 412 | } |
| 402 | L->ci = ci->previous; /* back to caller */ | 413 | L->ci = ci->previous; /* back to caller */ |
| @@ -458,8 +469,10 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
| 458 | ci->top = L->top + LUA_MINSTACK; | 469 | ci->top = L->top + LUA_MINSTACK; |
| 459 | ci->func = func; | 470 | ci->func = func; |
| 460 | lua_assert(ci->top <= L->stack_last); | 471 | lua_assert(ci->top <= L->stack_last); |
| 461 | if (L->hookmask & LUA_MASKCALL) | 472 | if (L->hookmask & LUA_MASKCALL) { |
| 462 | luaD_hook(L, LUA_HOOKCALL, -1); | 473 | int narg = cast_int(L->top - func) - 1; |
| 474 | luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); | ||
| 475 | } | ||
| 463 | lua_unlock(L); | 476 | lua_unlock(L); |
| 464 | n = (*f)(L); /* do the actual call */ | 477 | n = (*f)(L); /* do the actual call */ |
| 465 | lua_lock(L); | 478 | lua_lock(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 2.41 2018/02/09 15:16:06 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.42 2018/02/15 15:34:29 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 | */ |
| @@ -52,7 +52,8 @@ typedef void (*Pfunc) (lua_State *L, void *ud); | |||
| 52 | 52 | ||
| 53 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | 53 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, |
| 54 | const char *mode); | 54 | const char *mode); |
| 55 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); | 55 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, |
| 56 | int fTransfer, int nTransfer); | ||
| 56 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); | 57 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); |
| 57 | LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); | 58 | LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); |
| 58 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | 59 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.154 2018/02/09 15:16:06 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.155 2018/02/15 18:06:24 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 | */ |
| @@ -103,9 +103,13 @@ typedef struct CallInfo { | |||
| 103 | union { | 103 | union { |
| 104 | int funcidx; /* called-function index */ | 104 | int funcidx; /* called-function index */ |
| 105 | int nyield; /* number of values yielded */ | 105 | int nyield; /* number of values yielded */ |
| 106 | struct { /* info about transfered values (for call/return hooks) */ | ||
| 107 | unsigned short fTransfer; /* offset of first value transfered */ | ||
| 108 | unsigned short nTransfer; /* number of values transfered */ | ||
| 109 | } transferinfo; | ||
| 106 | } u2; | 110 | } u2; |
| 107 | short nresults; /* expected number of results from this function */ | 111 | short nresults; /* expected number of results from this function */ |
| 108 | lu_byte callstatus; | 112 | unsigned short callstatus; |
| 109 | } CallInfo; | 113 | } CallInfo; |
| 110 | 114 | ||
| 111 | 115 | ||
| @@ -120,6 +124,7 @@ typedef struct CallInfo { | |||
| 120 | #define CIST_HOOKYIELD (1<<5) /* last hook called yielded */ | 124 | #define CIST_HOOKYIELD (1<<5) /* last hook called yielded */ |
| 121 | #define CIST_LEQ (1<<6) /* using __lt for __le */ | 125 | #define CIST_LEQ (1<<6) /* using __lt for __le */ |
| 122 | #define CIST_FIN (1<<7) /* call is running a finalizer */ | 126 | #define CIST_FIN (1<<7) /* call is running a finalizer */ |
| 127 | #define CIST_TRAN (1<<8) /* 'ci' has transfer information */ | ||
| 123 | 128 | ||
| 124 | /* active function is a Lua function */ | 129 | /* active function is a Lua function */ |
| 125 | #define isLua(ci) (!((ci)->callstatus & CIST_C)) | 130 | #define isLua(ci) (!((ci)->callstatus & CIST_C)) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.337 2017/11/02 11:28:56 roberto Exp $ | 2 | ** $Id: lua.h,v 1.339 2017/11/07 13:25:26 roberto Exp roberto $ |
| 3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
| 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
| @@ -452,6 +452,8 @@ struct lua_Debug { | |||
| 452 | int lastlinedefined; /* (S) */ | 452 | int lastlinedefined; /* (S) */ |
| 453 | unsigned char nups; /* (u) number of upvalues */ | 453 | unsigned char nups; /* (u) number of upvalues */ |
| 454 | unsigned char nparams;/* (u) number of parameters */ | 454 | unsigned char nparams;/* (u) number of parameters */ |
| 455 | unsigned char fTransfer;/* (r) index of first value transfered */ | ||
| 456 | unsigned char nTransfer; /* (r) number of transfered values */ | ||
| 455 | char isvararg; /* (u) */ | 457 | char isvararg; /* (u) */ |
| 456 | char istailcall; /* (t) */ | 458 | char istailcall; /* (t) */ |
| 457 | char short_src[LUA_IDSIZE]; /* (S) */ | 459 | char short_src[LUA_IDSIZE]; /* (S) */ |
