From 83d06b667de42b3440f9148c09e037390e76ab4d Mon Sep 17 00:00:00 2001 From: TerryE Date: Sun, 8 Nov 2015 23:46:08 +0000 Subject: [PATCH] Port of strip debug patch to the SDK 1.4-baseline dev --- app/include/user_config.h | 1 + app/lua/lcode.c | 101 ++++++++++++++++++++++++++++++- app/lua/ldebug.c | 121 ++++++++++++++++++++++++++++++++++---- app/lua/ldebug.h | 18 +++++- app/lua/ldump.c | 31 ++++++---- app/lua/lfunc.c | 13 +++- app/lua/lgc.c | 11 +++- app/lua/lobject.h | 12 +++- app/lua/lparser.c | 31 ++++++++++ app/lua/lparser.h | 6 ++ app/lua/lua.h | 5 +- app/lua/lundump.c | 15 +++++ app/modules/node.c | 72 ++++++++++++++++++++++- 13 files changed, 404 insertions(+), 33 deletions(-) diff --git a/app/include/user_config.h b/app/include/user_config.h index b28da199..c01ce62d 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -64,6 +64,7 @@ #define LUA_TASK_PRIO USER_TASK_PRIO_0 #define LUA_PROCESS_LINE_SIG 2 +#define LUA_OPTIMIZE_DEBUG 2 #ifdef DEVKIT_VERSION_0_9 #define KEYLED_INTERVAL 80 diff --git a/app/lua/lcode.c b/app/lua/lcode.c index bf5c3fc3..ed53def7 100644 --- a/app/lua/lcode.c +++ b/app/lua/lcode.c @@ -781,8 +781,91 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { } +#ifdef LUA_OPTIMIZE_DEBUG + +/* + * Attempted to write to last (null terminator) byte of lineinfo, so need + * to grow the lineinfo vector and extend the fill bytes + */ +static unsigned char *growLineInfo(FuncState *fs) { + int i, oldsize = fs->packedlineinfoSize; + Proto *f = fs->f; + unsigned char *p, *r; + + lua_assert(f->packedlineinfo==NULL || f->packedlineinfo[oldsize-1] == 0); + + /* using the macro results in a redundant if test, but what the hell */ + luaM_growvector(fs->L, f->packedlineinfo, fs->packedlineinfoSize, fs->packedlineinfoSize, + unsigned char, MAX_INT, "code size overflow"); + r = p = f->packedlineinfo + oldsize; + if (oldsize) *--r = INFO_FILL_BYTE; + i = fs->packedlineinfoSize - oldsize - 1; + while (i--) *p++ = INFO_FILL_BYTE; + *p = 0; + return r; +} + +static void generateInfoDeltaLine(FuncState *fs, int line) { + /* Handle first time through when lineinfo points is NULL */ + unsigned char *p = fs->f->packedlineinfo ? lineInfoTop(fs) + 1 : growLineInfo(fs); +#define addDLbyte(v) if (*p==0) p = growLineInfo(fs); *p++ = (v); + int delta = line - fs->lastline - 1; + if (delta) { + if (delta<0) { + delta = -delta - 1; + addDLbyte((INFO_DELTA_MASK|INFO_SIGN_MASK) | (delta & INFO_DELTA_6BITS)); + } else { + delta = delta - 1; + addDLbyte(INFO_DELTA_MASK | (delta & INFO_DELTA_6BITS)); + } + delta >>= 6; + while (delta) { + addDLbyte(INFO_DELTA_MASK | (delta & INFO_DELTA_7BITS)); + delta >>= 7; + } + } + addDLbyte(1); + fs->lastline = line; + fs->lastlineOffset = p - fs->f->packedlineinfo - 1; +#undef addDLbyte +} +#endif + void luaK_fixline (FuncState *fs, int line) { - fs->f->lineinfo[fs->pc - 1] = line; +#ifdef LUA_OPTIMIZE_DEBUG + /* The fixup line can be the same as existing one and in this case there's nothing to do */ + if (line != fs->lastline) { + /* first remove the current line reference */ + unsigned char *p = lineInfoTop(fs); + lua_assert(*p < 127); + if (*p >1) { + (*p)--; /* this is simply decrementing the last count a multi-PC line */ + } else { + /* it's a bit more complicated if it's the 1st instruction on the line */ + int delta = 0; + unsigned char code; + /* this logic handles [1snnnnnnn [1nnnnnnn]*]? */ + *p-- = INFO_FILL_BYTE; + /* work backwards over the coded delta computing the delta */ + while ((code=*p) & INFO_DELTA_MASK) { + *p-- = INFO_FILL_BYTE; + if (*p & INFO_DELTA_MASK) { + delta = delta + ((code & INFO_DELTA_7BITS)<<7); + } else { + delta += (code & INFO_DELTA_6BITS) + 1; + if (code & INFO_SIGN_MASK) delta = -delta; + } + } + /* and reposition the FuncState lastline pointers at the previous instruction count */ + fs->lastline-= delta + 1; + fs->lastlineOffset = p - fs->f->packedlineinfo; + } + /* Then add the new line reference */ + generateInfoDeltaLine(fs, line); + } +#else + fs->f->lineinfo[fs->pc - 1] = line; +#endif } @@ -794,9 +877,25 @@ static int luaK_code (FuncState *fs, Instruction i, int line) { MAX_INT, "code size overflow"); f->code[fs->pc] = i; /* save corresponding line information */ +#ifdef LUA_OPTIMIZE_DEBUG + /* note that frst time fs->lastline==0 through, so the else branch is taken */ + if (fs->pc == fs->lineinfoLastPC+1) { + if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) { + f->packedlineinfo[fs->lastlineOffset]++; + } else { + generateInfoDeltaLine(fs, line); + } + } else { + /* The last instruction is occasionally overwritten as part of branch optimisation*/ + lua_assert(fs->pc == fs->lineinfoLastPC); /* panic if its anything other than this !! */ + luaK_fixline(fs,line); + } + fs->lineinfoLastPC = fs->pc; +#else luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, MAX_INT, "code size overflow"); f->lineinfo[fs->pc] = line; +#endif return fs->pc++; } diff --git a/app/lua/ldebug.c b/app/lua/ldebug.c index 9f1dff2d..1441e69d 100644 --- a/app/lua/ldebug.c +++ b/app/lua/ldebug.c @@ -171,21 +171,114 @@ 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)<l.p->lineinfo; + int i; + for (i=0; il.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)<l.p->lineinfo; - int i; - for (i=0; il.p->sizelineinfo; i++) - setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); - sethvalue(L, L->top, t); - } - incr_top(L); + 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;isizep;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, void *plight, CallInfo *ci) { @@ -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; } diff --git a/app/lua/ldebug.h b/app/lua/ldebug.h index ba28a972..1da88361 100644 --- a/app/lua/ldebug.h +++ b/app/lua/ldebug.h @@ -13,7 +13,19 @@ #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) -#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) +#ifdef LUA_OPTIMIZE_DEBUG +# include "lvm.h" +# define getline(f,pc) (((f)->packedlineinfo) ? luaG_getline((f), pc) : 0) +# 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 +# define lineInfoTop(fs) ((fs)->f->packedlineinfo + (fs)->lastlineOffset) +#else +# define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) +#endif #define resethookcount(L) (L->hookcount = L->basehookcount) @@ -29,5 +41,9 @@ LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); LUAI_FUNC void luaG_errormsg (lua_State *L); LUAI_FUNC int luaG_checkcode (const Proto *pt); LUAI_FUNC int luaG_checkopenop (Instruction i); +#ifdef LUA_OPTIMIZE_DEBUG +LUAI_FUNC int luaG_getline (const Proto *f, int pc); +LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv); +#endif #endif diff --git a/app/lua/ldump.c b/app/lua/ldump.c index 9f3543b3..1c5d5b7b 100644 --- a/app/lua/ldump.c +++ b/app/lua/ldump.c @@ -72,18 +72,18 @@ static void DumpIntWithSize(int x, int sizeof_int, DumpState* D) /* dump signed integer */ switch(sizeof_int) { case 1: { - if (x>0x7F || x<(-0x80)) D->status=LUA_ERR_CC_INTOVERFLOW; + if (x>0x7F || x<(-0x80)) D->status=LUA_ERR_CC_INTOVERFLOW; DumpChar(x,D); } break; case 2: { - if (x>0x7FFF || x<(-0x8000)) D->status=LUA_ERR_CC_INTOVERFLOW; + if (x>0x7FFF || x<(-0x8000)) D->status=LUA_ERR_CC_INTOVERFLOW; int16_t y=(int16_t)x; MaybeByteSwap((char*)&y,2,D); DumpVar(y,D); } break; case 4: { /* Need to reduce bounds by 1 to avoid messing 32-bit compilers up */ - if (x>0x7FFFFFFE || x<(-0x7FFFFFFF)) D->status=LUA_ERR_CC_INTOVERFLOW; + if (x>0x7FFFFFFE || x<(-0x7FFFFFFF)) D->status=LUA_ERR_CC_INTOVERFLOW; int32_t y=(int32_t)x; MaybeByteSwap((char*)&y,4,D); DumpVar(y,D); @@ -102,7 +102,7 @@ static void DumpSize(uint32_t x, DumpState* D) /* dump unsigned integer */ switch(D->target.sizeof_strsize_t) { case 1: { - if (x>0xFF) D->status=LUA_ERR_CC_INTOVERFLOW; + if (x>0xFF) D->status=LUA_ERR_CC_INTOVERFLOW; DumpChar(x,D); } break; case 2: { @@ -144,8 +144,8 @@ static void DumpNumber(lua_Number x, DumpState* D) } break; case 8: { double y=x; - // ARM FPA mode: keep endianness, but swap high and low parts of the - // memory representation. This is the default compilation mode for ARM + // ARM FPA mode: keep endianness, but swap high and low parts of the + // memory representation. This is the default compilation mode for ARM // targets with non-EABI gcc if(D->target.is_arm_fpa) { @@ -153,7 +153,7 @@ static void DumpNumber(lua_Number x, DumpState* D) c_memcpy(temp,pnum,4); c_memcpy(pnum,pnum+4,4); c_memcpy(pnum+4,temp,4); - } + } MaybeByteSwap((char*)&y,8,D); DumpVar(y,D); } break; @@ -228,6 +228,16 @@ static void DumpConstants(const Proto* f, DumpState* D) static void DumpDebug(const Proto* f, DumpState* D) { int i,n; + +#ifdef LUA_OPTIMIZE_DEBUG + n = (D->strip || f->packedlineinfo == NULL) ? 0: c_strlen(cast(char *,f->packedlineinfo))+1; + DumpInt(n,D); + Align4(D); + if (n) + { + DumpBlock(f->packedlineinfo, n, D); + } +#else n= (D->strip) ? 0 : f->sizelineinfo; DumpInt(n,D); Align4(D); @@ -235,7 +245,8 @@ static void DumpDebug(const Proto* f, DumpState* D) { DumpInt(f->lineinfo[i],D); } - + #endif + n= (D->strip) ? 0 : f->sizelocvars; DumpInt(n,D); for (i=0; itarget.sizeof_lua_Number; *h++=(char)D->target.lua_Number_integral; - + DumpBlock(buf,LUAC_HEADERSIZE,D); } diff --git a/app/lua/lfunc.c b/app/lua/lfunc.c index b82ea17b..3d0dd133 100644 --- a/app/lua/lfunc.c +++ b/app/lua/lfunc.c @@ -9,6 +9,7 @@ #define LUAC_CROSS_FILE #include "lua.h" +#include C_HEADER_STRING #include "lfunc.h" #include "lgc.h" @@ -119,14 +120,18 @@ Proto *luaF_newproto (lua_State *L) { f->sizep = 0; f->code = NULL; f->sizecode = 0; - f->sizelineinfo = 0; f->sizeupvalues = 0; f->nups = 0; f->upvalues = NULL; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; +#ifdef LUA_OPTIMIZE_DEBUG + f->packedlineinfo = NULL; +#else + f->sizelineinfo = 0; f->lineinfo = NULL; +#endif f->sizelocvars = 0; f->locvars = NULL; f->linedefined = 0; @@ -143,7 +148,13 @@ void luaF_freeproto (lua_State *L, Proto *f) { luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); if (!proto_is_readonly(f)) { luaM_freearray(L, f->code, f->sizecode, Instruction); +#ifdef LUA_OPTIMIZE_DEBUG + if (f->packedlineinfo) { + luaM_freearray(L, f->packedlineinfo, c_strlen(cast(char *, f->packedlineinfo))+1, unsigned char); + } +#else luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); +#endif } luaM_free(L, f); } diff --git a/app/lua/lgc.c b/app/lua/lgc.c index 4288933d..e41a779d 100644 --- a/app/lua/lgc.c +++ b/app/lua/lgc.c @@ -312,12 +312,19 @@ static l_mem propagatemark (global_State *g) { Proto *p = gco2p(o); g->gray = p->gclist; traverseproto(g, p); + return sizeof(Proto) + sizeof(Proto *) * p->sizep + - sizeof(TValue) * p->sizek + + sizeof(TValue) * p->sizek + sizeof(LocVar) * p->sizelocvars + sizeof(TString *) * p->sizeupvalues + (proto_is_readonly(p) ? 0 : sizeof(Instruction) * p->sizecode + +#ifdef LUA_OPTIMIZE_DEBUG + (p->packedlineinfo ? + c_strlen(cast(char *, p->packedlineinfo))+1 : + 0)); +#else sizeof(int) * p->sizelineinfo); +#endif } default: lua_assert(0); return 0; } @@ -729,7 +736,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { GCObject *o = obj2gco(uv); o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ g->rootgc = o; - if (isgray(o)) { + if (isgray(o)) { if (g->gcstate == GCSpropagate) { gray2black(o); /* closed upvalues need barrier */ luaC_barrier(L, uv, uv->v); diff --git a/app/lua/lobject.h b/app/lua/lobject.h index e41b65bc..5b020953 100644 --- a/app/lua/lobject.h +++ b/app/lua/lobject.h @@ -211,10 +211,10 @@ typedef TValuefields TValue; #define setpvalue(obj,x) \ { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; } - + #define setrvalue(obj,x) \ { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TROTABLE; } - + #define setfvalue(obj,x) \ { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; } @@ -394,14 +394,20 @@ typedef struct Proto { TValue *k; /* constants used by the function */ Instruction *code; struct Proto **p; /* functions defined inside the function */ +#ifdef LUA_OPTIMIZE_DEBUG + unsigned char *packedlineinfo; +#else int *lineinfo; /* map from opcodes to source lines */ +#endif struct LocVar *locvars; /* information about local variables */ TString **upvalues; /* upvalue names */ TString *source; int sizeupvalues; int sizek; /* size of `k' */ int sizecode; +#ifndef LUA_OPTIMIZE_DEBUG int sizelineinfo; +#endif int sizep; /* size of `p' */ int sizelocvars; int linedefined; @@ -510,7 +516,7 @@ typedef struct Node { typedef struct Table { CommonHeader; - lu_byte flags; /* 1<

bl = NULL; f->source = ls->source; f->maxstacksize = 2; /* registers 0/1 are always valid */ +#ifdef LUA_OPTIMIZE_DEBUG + fs->packedlineinfoSize = 0; + fs->lastline = 0; + fs->lastlineOffset = 0; + fs->lineinfoLastPC = -1; +#endif fs->h = luaH_new(L, 0, 0); /* anchor table of constants and prototype (to avoid being collected) */ sethvalue2s(L, L->top, fs->h); @@ -361,8 +367,15 @@ static void close_func (LexState *ls) { luaK_ret(fs, 0, 0); /* final return */ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); f->sizecode = fs->pc; +#ifdef LUA_OPTIMIZE_DEBUG + f->packedlineinfo[fs->lastlineOffset+1]=0; + luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize, + fs->lastlineOffset+2, unsigned char); +#else luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); f->sizelineinfo = fs->pc; +#endif + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); f->sizek = fs->nk; luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); @@ -379,6 +392,21 @@ static void close_func (LexState *ls) { L->top -= 2; /* remove table and prototype from the stack */ } +#ifdef LUA_OPTIMIZE_DEBUG +static void compile_stripdebug(lua_State *L, Proto *f) { + int level; + lua_pushlightuserdata(L, &luaG_stripdebug ); + lua_gettable(L, LUA_REGISTRYINDEX); + level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1); + lua_pop(L, 1); + + if (level > 1) { + int len = luaG_stripdebug(L, f, level, 1); + UNUSED(len); + } +} +#endif + Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { struct LexState lexstate; @@ -394,6 +422,9 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { chunk(&lexstate); check(&lexstate, TK_EOS); close_func(&lexstate); +#ifdef LUA_OPTIMIZE_DEBUG + compile_stripdebug(L, funcstate.f); +#endif L->top--; /* remove 'name' from stack */ lua_assert(funcstate.prev == NULL); lua_assert(funcstate.f->nups == 0); diff --git a/app/lua/lparser.h b/app/lua/lparser.h index 18836afd..74b7aa6e 100644 --- a/app/lua/lparser.h +++ b/app/lua/lparser.h @@ -72,6 +72,12 @@ typedef struct FuncState { lu_byte nactvar; /* number of active local variables */ upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ +#ifdef LUA_OPTIMIZE_DEBUG + int packedlineinfoSize; /* only used during compilation for line info */ + int lastline; /* ditto */ + int lastlineOffset; /* ditto */ + int lineinfoLastPC; /* ditto */ +#endif } FuncState; diff --git a/app/lua/lua.h b/app/lua/lua.h index 2986e2dc..6d3fd1a0 100644 --- a/app/lua/lua.h +++ b/app/lua/lua.h @@ -102,6 +102,9 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); #include LUA_USER_H #endif +#if defined(LUA_OPTIMIZE_DEBUG) && LUA_OPTIMIZE_DEBUG == 0 +#undef LUA_OPTIMIZE_DEBUG +#endif /* type of numbers in Lua */ typedef LUA_NUMBER lua_Number; @@ -258,7 +261,7 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); -/* +/* ** =============================================================== ** some useful macros ** =============================================================== diff --git a/app/lua/lundump.c b/app/lua/lundump.c index 7644e4de..76178c20 100644 --- a/app/lua/lundump.c +++ b/app/lua/lundump.c @@ -235,6 +235,20 @@ static void LoadDebug(LoadState* S, Proto* f) int i,n; n=LoadInt(S); Align4(S); + +#ifdef LUA_OPTIMIZE_DEBUG + if(n) { + if (!luaZ_direct_mode(S->Z)) { + f->packedlineinfo=luaM_newvector(S->L,n,unsigned char); + LoadBlock(S,f->packedlineinfo,n); + } else { + f->packedlineinfo=(unsigned char*)luaZ_get_crt_address(S->Z); + LoadBlock(S,NULL,n); + } + } else { + f->packedlineinfo=NULL; + } +#else if (!luaZ_direct_mode(S->Z)) { f->lineinfo=luaM_newvector(S->L,n,int); LoadVector(S,f->lineinfo,n,sizeof(int)); @@ -243,6 +257,7 @@ static void LoadDebug(LoadState* S, Proto* f) LoadVector(S,NULL,n,sizeof(int)); } f->sizelineinfo=n; + #endif n=LoadInt(S); f->locvars=luaM_newvector(S->L,n,LocVar); f->sizelocvars=n; diff --git a/app/modules/node.c b/app/modules/node.c index c99e215b..cd1d60f9 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -3,10 +3,13 @@ #include "lua.h" #include "lauxlib.h" +#include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lmem.h" #include "lobject.h" +#include "lstate.h" + #include "lopcodes.h" #include "lstring.h" #include "lundump.h" @@ -484,6 +487,69 @@ static int node_restore (lua_State *L) return 0; } +#ifdef LUA_OPTIMIZE_DEBUG +/* node.stripdebug([level[, function]]).  + * level: 1 don't discard debug + * 2 discard Local and Upvalue debug info + * 3 discard Local, Upvalue and lineno debug info. + * function: Function to be stripped as per setfenv except 0 not permitted. + * If no arguments then the current default setting is returned. + * If function is omitted, this is the default setting for future compiles + * The function returns an estimated integer count of the bytes stripped. + */ +static int node_stripdebug (lua_State *L) { + int level; + + if (L->top == L->base) { + lua_pushlightuserdata(L, &luaG_stripdebug ); + lua_gettable(L, LUA_REGISTRYINDEX); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + lua_pushinteger(L, LUA_OPTIMIZE_DEBUG); + } + return 1; + } + + level = luaL_checkint(L, 1); + if ((level <= 0) || (level > 3)) luaL_argerror(L, 1, "must in range 1-3"); + + if (L->top == L->base + 1) { + /* Store the default level in the registry if no function parameter */ + lua_pushlightuserdata(L, &luaG_stripdebug); + lua_pushinteger(L, level); + lua_settable(L, LUA_REGISTRYINDEX); + lua_settop(L,0); + return 0; + } + + if (level == 1) { + lua_settop(L,0); + lua_pushinteger(L, 0); + return 1; + } + + if (!lua_isfunction(L, 2)) { + int scope = luaL_checkint(L, 2); + if (scope > 0) { + /* if the function parameter is a +ve integer then climb to find function */ + lua_Debug ar; + lua_pop(L, 1); /* pop level as getinfo will replace it by the function */ + if (lua_getstack(L, scope, &ar)) { + lua_getinfo(L, "f", &ar); + } + } + } + + if(!lua_isfunction(L, 2) || lua_iscfunction(L, -1)) luaL_argerror(L, 2, "must be a Lua Function"); + // lua_lock(L); + Proto *f = clvalue(L->base + 1)->l.p; + // lua_unlock(L); + lua_settop(L,0); + lua_pushinteger(L, luaG_stripdebug(L, f, level, 1)); + return 1; +} +#endif + // Module function map #define MIN_OPT_LEVEL 2 #include "lrodefs.h" @@ -502,7 +568,7 @@ const LUA_REG_TYPE node_map[] = #endif { LSTRKEY( "input" ), LFUNCVAL( node_input ) }, { LSTRKEY( "output" ), LFUNCVAL( node_output ) }, -// Moved to adc module, use adc.readvdd33() +// Moved to adc module, use adc.readvdd33() // { LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) }, { LSTRKEY( "compile" ), LFUNCVAL( node_compile) }, { LSTRKEY( "CPU80MHZ" ), LNUMVAL( CPU80MHZ ) }, @@ -510,6 +576,10 @@ const LUA_REG_TYPE node_map[] = { LSTRKEY( "setcpufreq" ), LFUNCVAL( node_setcpufreq) }, { LSTRKEY( "bootreason" ), LFUNCVAL( node_bootreason) }, { LSTRKEY( "restore" ), LFUNCVAL( node_restore) }, +#ifdef LUA_OPTIMIZE_DEBUG + { LSTRKEY( "stripdebug" ), LFUNCVAL( node_stripdebug ) }, +#endif + // Combined to dsleep(us, option) // { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) }, #if LUA_OPTIMIZE_MEMORY > 0