summaryrefslogtreecommitdiffstats
path: root/apps/plugins/lua/ldebug.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/ldebug.c')
-rw-r--r--apps/plugins/lua/ldebug.c99
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) {
}
else {
Table *t = luaH_new(L, 0, 0);
+#ifdef LUA_OPTIMIZE_DEBUG
+ int line = 0;
+ unsigned char *p = f->l.p->packedlineinfo;
+ if (p) {
+ for (; *p && *p != INFO_FILL_BYTE; ) {
+ if (*p & INFO_DELTA_MASK) { /* line delta */
+ int delta = *p & INFO_DELTA_6BITS;
+ unsigned char sign = *p++ & INFO_SIGN_MASK;
+ int shift;
+ for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) {
+ delta += (*p & INFO_DELTA_7BITS)<<shift;
+ }
+ line += sign ? -delta : delta+2;
+ } else {
+ line++;
+ }
+ p++;
+ setbvalue(luaH_setnum(L, t, line), 1);
+ }
+ }
+#else
int *lineinfo = f->l.p->lineinfo;
int i;
for (i=0; i<f->l.p->sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
- sethvalue(L, L->top, t);
+#endif
+ sethvalue(L, L->top, t);
}
incr_top(L);
}
+#ifdef LUA_OPTIMIZE_DEBUG
+/*
+ * This may seem expensive but this is only accessed frequently in traceexec
+ * and the while loop will be executed roughly half the number of non-blank
+ * source lines in the Lua function and these tend to be short.
+ */
+LUAI_FUNC int luaG_getline (const Proto *f, int pc) {
+ int line = 0, thispc = 0, nextpc;
+ unsigned char *p;
+
+ for (p = f->packedlineinfo; *p && *p != INFO_FILL_BYTE;) {
+ if (*p & INFO_DELTA_MASK) { /* line delta */
+ int delta = *p & INFO_DELTA_6BITS;
+ unsigned char sign = *p++ & INFO_SIGN_MASK;
+ int shift;
+ for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) {
+ delta += (*p & INFO_DELTA_7BITS)<<shift;
+ }
+ line += sign ? -delta : delta+2;
+ } else {
+ line++;
+ }
+ lua_assert(*p<127);
+ nextpc = thispc + *p++;
+ if (thispc <= pc && pc < nextpc) {
+ return line;
+ }
+ thispc = nextpc;
+ }
+ lua_assert(0);
+ return 0;
+}
+
+
+static int stripdebug (lua_State *L, Proto *f, const int level) {
+ int len = 0;
+ TString* dummy;
+ switch (level) {
+ case 3:
+ len += f->sizelineinfo;
+ f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, f->sizelineinfo, unsigned char);
+ case 2:
+ len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *));
+ f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
+ f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
+ len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) +
+ f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *));
+ f->sizelocvars = 0;
+ f->sizeupvalues = 0;
+ case 1:
+ default:
+ break;
+ }
+ return len;
+}
+
+
+/* This is a recursive function so it's stack size has been kept to a minimum! */
+LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){
+ int len = 0, i;
+#ifndef LUA_OPTIMIZE_DEBUG_USER /* gcc doesn't realize level can't be changed */
+ level = LUA_OPTIMIZE_DEBUG;
+#endif
+ if (recv > 0 && f->sizep != 0) {
+ /* recv limits recursion depth */
+ for(i=0;i<f->sizep;i++) len += luaG_stripdebug(L, f->p[i], level, --recv);
+ }
+ len += stripdebug (L, f, level);
+ return len;
+}
+#endif
+
+
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
@@ -279,7 +374,9 @@ static int precheck (const Proto *pt) {
check(!(pt->is_vararg & VARARG_NEEDSARG) ||
(pt->is_vararg & VARARG_HASARG));
check(pt->sizeupvalues <= pt->nups);
+#ifndef LUA_OPTIMIZE_DEBUG
check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
+#endif
check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
return 1;
}