|
@@ -171,20 +171,113 @@ static void info_tailcall (lua_Debug *ar) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void collectvalidlines (lua_State *L, Closure *f) {
|
|
|
- if (f == NULL || f->c.isC) {
|
|
|
- setnilvalue(L->top);
|
|
|
+ static void collectvalidlines (lua_State *L, Closure *f) {
|
|
|
+ if (f == NULL || f->c.isC) {
|
|
|
+ setnilvalue(L->top);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ # define INFO_FILL_BYTE 0x7F
|
|
|
+# define INFO_DELTA_MASK 0x80
|
|
|
+# define INFO_SIGN_MASK 0x40
|
|
|
+# define INFO_DELTA_6BITS 0x3F
|
|
|
+# define INFO_DELTA_7BITS 0x7F
|
|
|
+# define INFO_MAX_LINECNT 126
|
|
|
+
|
|
|
+ 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);
|
|
|
+#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.
|
|
|
+ */
|
|
|
+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;
|
|
|
}
|
|
|
- else {
|
|
|
- Table *t = luaH_new(L, 0, 0);
|
|
|
- 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);
|
|
|
+ lua_assert(0);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int stripdebug (lua_State *L, Proto *f, int level) {
|
|
|
+ int len = 0, sizepackedlineinfo;
|
|
|
+ TString* dummy;
|
|
|
+ switch (level) {
|
|
|
+ case 3:
|
|
|
+ sizepackedlineinfo = c_strlen(cast(char *, f->packedlineinfo))+1;
|
|
|
+ f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
|
|
|
+ len += sizepackedlineinfo;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+/* This is a recursive function so it's stack size has been kept to a minimum! */
|
|
|
+LUA_API int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){
|
|
|
+ int len = 0, i;
|
|
|
+ if (recv != 0 && f->sizep != 0) {
|
|
|
+ for(i=0;i<f->sizep;i++) len += luaG_stripdebug(L, f->p[i], level, recv);
|
|
|
}
|
|
|
- incr_top(L);
|
|
|
+ len += stripdebug (L, f, level);
|
|
|
+ return len;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|
@@ -252,7 +345,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
|
|
}
|
|
|
status = auxgetinfo(L, what, ar, f, plight, ci);
|
|
|
if (c_strchr(what, 'f')) {
|
|
|
- if (f != NULL)
|
|
|
+ if (f != NULL)
|
|
|
setclvalue(L, L->top, f)
|
|
|
else if (plight != NULL)
|
|
|
setfvalue(L->top, plight)
|
|
@@ -287,7 +380,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;
|
|
|
}
|