diff options
Diffstat (limited to 'apps/plugins/lua/ldebug.c')
-rw-r--r-- | apps/plugins/lua/ldebug.c | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/apps/plugins/lua/ldebug.c b/apps/plugins/lua/ldebug.c index 50ad3d3803..446f7d1a45 100644 --- a/apps/plugins/lua/ldebug.c +++ b/apps/plugins/lua/ldebug.c | |||
@@ -180,16 +180,111 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |||
180 | } | 180 | } |
181 | else { | 181 | else { |
182 | Table *t = luaH_new(L, 0, 0); | 182 | Table *t = luaH_new(L, 0, 0); |
183 | #ifdef LUA_OPTIMIZE_DEBUG | ||
184 | int line = 0; | ||
185 | unsigned char *p = f->l.p->packedlineinfo; | ||
186 | if (p) { | ||
187 | for (; *p && *p != INFO_FILL_BYTE; ) { | ||
188 | if (*p & INFO_DELTA_MASK) { /* line delta */ | ||
189 | int delta = *p & INFO_DELTA_6BITS; | ||
190 | unsigned char sign = *p++ & INFO_SIGN_MASK; | ||
191 | int shift; | ||
192 | for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) { | ||
193 | delta += (*p & INFO_DELTA_7BITS)<<shift; | ||
194 | } | ||
195 | line += sign ? -delta : delta+2; | ||
196 | } else { | ||
197 | line++; | ||
198 | } | ||
199 | p++; | ||
200 | setbvalue(luaH_setnum(L, t, line), 1); | ||
201 | } | ||
202 | } | ||
203 | #else | ||
183 | int *lineinfo = f->l.p->lineinfo; | 204 | int *lineinfo = f->l.p->lineinfo; |
184 | int i; | 205 | int i; |
185 | for (i=0; i<f->l.p->sizelineinfo; i++) | 206 | for (i=0; i<f->l.p->sizelineinfo; i++) |
186 | setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); | 207 | setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); |
187 | sethvalue(L, L->top, t); | 208 | #endif |
209 | sethvalue(L, L->top, t); | ||
188 | } | 210 | } |
189 | incr_top(L); | 211 | incr_top(L); |
190 | } | 212 | } |
191 | 213 | ||
192 | 214 | ||
215 | #ifdef LUA_OPTIMIZE_DEBUG | ||
216 | /* | ||
217 | * This may seem expensive but this is only accessed frequently in traceexec | ||
218 | * and the while loop will be executed roughly half the number of non-blank | ||
219 | * source lines in the Lua function and these tend to be short. | ||
220 | */ | ||
221 | LUAI_FUNC int luaG_getline (const Proto *f, int pc) { | ||
222 | int line = 0, thispc = 0, nextpc; | ||
223 | unsigned char *p; | ||
224 | |||
225 | for (p = f->packedlineinfo; *p && *p != INFO_FILL_BYTE;) { | ||
226 | if (*p & INFO_DELTA_MASK) { /* line delta */ | ||
227 | int delta = *p & INFO_DELTA_6BITS; | ||
228 | unsigned char sign = *p++ & INFO_SIGN_MASK; | ||
229 | int shift; | ||
230 | for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) { | ||
231 | delta += (*p & INFO_DELTA_7BITS)<<shift; | ||
232 | } | ||
233 | line += sign ? -delta : delta+2; | ||
234 | } else { | ||
235 | line++; | ||
236 | } | ||
237 | lua_assert(*p<127); | ||
238 | nextpc = thispc + *p++; | ||
239 | if (thispc <= pc && pc < nextpc) { | ||
240 | return line; | ||
241 | } | ||
242 | thispc = nextpc; | ||
243 | } | ||
244 | lua_assert(0); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | |||
249 | static int stripdebug (lua_State *L, Proto *f, const int level) { | ||
250 | int len = 0; | ||
251 | TString* dummy; | ||
252 | switch (level) { | ||
253 | case 3: | ||
254 | len += f->sizelineinfo; | ||
255 | f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, f->sizelineinfo, unsigned char); | ||
256 | case 2: | ||
257 | len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)); | ||
258 | f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); | ||
259 | f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); | ||
260 | len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) + | ||
261 | f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *)); | ||
262 | f->sizelocvars = 0; | ||
263 | f->sizeupvalues = 0; | ||
264 | case 1: | ||
265 | default: | ||
266 | break; | ||
267 | } | ||
268 | return len; | ||
269 | } | ||
270 | |||
271 | |||
272 | /* This is a recursive function so it's stack size has been kept to a minimum! */ | ||
273 | LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){ | ||
274 | int len = 0, i; | ||
275 | #ifndef LUA_OPTIMIZE_DEBUG_USER /* gcc doesn't realize level can't be changed */ | ||
276 | level = LUA_OPTIMIZE_DEBUG; | ||
277 | #endif | ||
278 | if (recv > 0 && f->sizep != 0) { | ||
279 | /* recv limits recursion depth */ | ||
280 | for(i=0;i<f->sizep;i++) len += luaG_stripdebug(L, f->p[i], level, --recv); | ||
281 | } | ||
282 | len += stripdebug (L, f, level); | ||
283 | return len; | ||
284 | } | ||
285 | #endif | ||
286 | |||
287 | |||
193 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | 288 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, |
194 | Closure *f, CallInfo *ci) { | 289 | Closure *f, CallInfo *ci) { |
195 | int status = 1; | 290 | int status = 1; |
@@ -279,7 +374,9 @@ static int precheck (const Proto *pt) { | |||
279 | check(!(pt->is_vararg & VARARG_NEEDSARG) || | 374 | check(!(pt->is_vararg & VARARG_NEEDSARG) || |
280 | (pt->is_vararg & VARARG_HASARG)); | 375 | (pt->is_vararg & VARARG_HASARG)); |
281 | check(pt->sizeupvalues <= pt->nups); | 376 | check(pt->sizeupvalues <= pt->nups); |
377 | #ifndef LUA_OPTIMIZE_DEBUG | ||
282 | check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); | 378 | check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); |
379 | #endif | ||
283 | check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); | 380 | check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); |
284 | return 1; | 381 | return 1; |
285 | } | 382 | } |