summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2019-08-05 00:03:08 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2019-08-08 07:11:30 +0200
commitd61ea6c5eeef4343e40c0225f22ad39c994f84a9 (patch)
tree13a5e6261dda3fda33aa7ae743105fc3f2bc2e39
parent1dabca6c267c2f8dfc8c0fb9269877856c00d4f1 (diff)
downloadrockbox-d61ea6c5eeef4343e40c0225f22ad39c994f84a9.tar.gz
rockbox-d61ea6c5eeef4343e40c0225f22ad39c994f84a9.zip
lua LCD (Lua Compact Debug) patch
LCD developed 9/2015 by Terry Ellison We've already discarded the ldebug module from lua it only makes sense to discard the debug info as well adds 1.5 K to the binary saves 8 Kb on the base state once scripts start getting called i've seen 10-50Kb savings but it all depends on what exactly you are running Change-Id: Ibb74f344df1c4c96380ec6c98b010a810e9ae9cc
-rw-r--r--apps/plugins/lua/lbaselib.c74
-rw-r--r--apps/plugins/lua/lcode.c103
-rw-r--r--apps/plugins/lua/ldebug.c99
-rw-r--r--apps/plugins/lua/ldebug.h19
-rw-r--r--apps/plugins/lua/ldump.c9
-rw-r--r--apps/plugins/lua/lfunc.c13
-rw-r--r--apps/plugins/lua/lgc.c8
-rw-r--r--apps/plugins/lua/lobject.h4
-rw-r--r--apps/plugins/lua/lparser.c32
-rw-r--r--apps/plugins/lua/lparser.h5
-rw-r--r--apps/plugins/lua/lua.h3
-rw-r--r--apps/plugins/lua/luaconf.h1
-rw-r--r--apps/plugins/lua/lundump.c9
13 files changed, 373 insertions, 6 deletions
diff --git a/apps/plugins/lua/lbaselib.c b/apps/plugins/lua/lbaselib.c
index ad94984191..cb7b29a92a 100644
--- a/apps/plugins/lua/lbaselib.c
+++ b/apps/plugins/lua/lbaselib.c
@@ -19,6 +19,13 @@
19#include "lauxlib.h" 19#include "lauxlib.h"
20#include "lualib.h" 20#include "lualib.h"
21 21
22#ifdef LUA_OPTIMIZE_DEBUG_USER
23#include "lobject.h"
24#include "lstate.h"
25#include "ldebug.h"
26#include "lfunc.h"
27#endif
28
22 29
23 30
24 31
@@ -302,6 +309,70 @@ static int luaB_loadfile (lua_State *L) {
302} 309}
303 310
304 311
312#ifdef LUA_OPTIMIZE_DEBUG_USER
313/* stripdebug([level[, function]]).
314 * level: 1 don't discard debug
315 * 2 discard Local and Upvalue debug info
316 * 3 discard Local, Upvalue and lineno debug info.
317 * function: Function to be stripped as per setfenv except 0 not permitted.
318 * If no arguments then the current default setting is returned.
319 * If function is omitted, this is the default setting for future compiles
320 * The function returns an estimated integer count of the bytes stripped.
321 */
322static int luaB_stripdebug (lua_State *L) {
323 int level;
324
325 if (L->top == L->base) {
326 lua_pushlightuserdata(L, &luaG_stripdebug);
327 lua_gettable(L, LUA_REGISTRYINDEX);
328 if (lua_isnil(L, -1)) {
329 lua_pop(L, 1);
330 lua_pushinteger(L, LUA_OPTIMIZE_DEBUG);
331 }
332 return 1;
333 }
334
335 level = luaL_checkint(L, 1);
336 if ((level <= 0) || (level > 3)) luaL_argerror(L, 1, "must in range 1-3");
337
338 if (L->top == L->base + 1) {
339 /* Store the default level in the registry if no function parameter */
340 lua_pushlightuserdata(L, &luaG_stripdebug);
341 lua_pushinteger(L, level);
342 lua_settable(L, LUA_REGISTRYINDEX);
343 lua_settop(L,0);
344 return 0;
345 }
346
347 if (level == 1) {
348 lua_settop(L,0);
349 lua_pushinteger(L, 0);
350 return 1;
351 }
352
353 if (!lua_isfunction(L, 2)) {
354 int scope = luaL_checkint(L, 2);
355 if (scope > 0) {
356 /* if the function parameter is a +ve integer then climb to find function */
357 lua_Debug ar;
358 lua_pop(L, 1); /* pop level as getinfo will replace it by the function */
359 if (lua_getstack(L, scope, &ar)) {
360 lua_getinfo(L, "f", &ar);
361 }
362 }
363 }
364
365 if(!lua_isfunction(L, 2) || lua_iscfunction(L, -1)) luaL_argerror(L, 2, "must be a Lua Function");
366 // lua_lock(L);
367 Proto *f = clvalue(L->base + 1)->l.p;
368 // lua_unlock(L);
369 lua_settop(L,0);
370 lua_pushinteger(L, luaG_stripdebug(L, f, level, 16));
371 return 1;
372}
373#endif
374
375
305/* 376/*
306** Reader for generic `load' function: `lua_load' uses the 377** Reader for generic `load' function: `lua_load' uses the
307** stack for internal stuff, so the reader cannot change the 378** stack for internal stuff, so the reader cannot change the
@@ -482,6 +553,9 @@ static const luaL_Reg base_funcs[] = {
482 {"select", luaB_select}, 553 {"select", luaB_select},
483 {"setfenv", luaB_setfenv}, 554 {"setfenv", luaB_setfenv},
484 {"setmetatable", luaB_setmetatable}, 555 {"setmetatable", luaB_setmetatable},
556#ifdef LUA_OPTIMIZE_DEBUG_USER
557 {"stripdebug", luaB_stripdebug},
558#endif
485 {"tonumber", luaB_tonumber}, 559 {"tonumber", luaB_tonumber},
486 {"tostring", luaB_tostring}, 560 {"tostring", luaB_tostring},
487 {"type", luaB_type}, 561 {"type", luaB_type},
diff --git a/apps/plugins/lua/lcode.c b/apps/plugins/lua/lcode.c
index 07f9cbe4c4..18102d460e 100644
--- a/apps/plugins/lua/lcode.c
+++ b/apps/plugins/lua/lcode.c
@@ -784,8 +784,95 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
784} 784}
785 785
786 786
787#ifdef LUA_OPTIMIZE_DEBUG
788/*
789 * Attempted to write to last (null terminator) byte of lineinfo, so need
790 * to grow the lineinfo vector and extend the fill bytes
791 */
792static unsigned char *growLineInfo(FuncState *fs) {
793 Proto *f = fs->f;
794 int start = (f->sizelineinfo > 0 ? f->sizelineinfo - 1 : 0);
795
796 unsigned char *p;
797
798 lua_assert(f->packedlineinfo==NULL || f->packedlineinfo[start] == '\0');
799
800 /* using the macro results in a redundant if test, but what the hell */
801 luaM_growvector(fs->L, f->packedlineinfo, f->sizelineinfo, f->sizelineinfo,
802 unsigned char, MAX_INT, "code size overflow");
803
804 p = &f->packedlineinfo[start];
805 memset(p, INFO_FILL_BYTE, f->sizelineinfo - start);
806 f->packedlineinfo[f->sizelineinfo - 1] = '\0';
807 return p;
808}
809
810
811static void generateInfoDeltaLine(FuncState *fs, int line) {
812 /* Handle first time through when lineinfo points is NULL */
813 unsigned char mask = INFO_DELTA_MASK;
814 unsigned char *p = fs->f->packedlineinfo ? lineInfoTop(fs) + 1 : growLineInfo(fs);
815#define addDLbyte(v) if (*p=='\0') p = growLineInfo(fs); *p++ = (v);
816 int delta = line - fs->lastline - 1;
817 if (delta != 0) {
818 if (delta < 0) {
819 delta = -delta;
820 mask |= INFO_SIGN_MASK;
821 }
822 delta -= 1;
823 mask |= (delta & INFO_DELTA_6BITS);
824 delta >>= 6;
825 addDLbyte(mask);
826
827 while (delta > 0) {
828 mask = INFO_DELTA_MASK | (delta & INFO_DELTA_7BITS);
829 delta >>= 7;
830 addDLbyte(mask);
831 }
832 }
833 addDLbyte(1);
834 fs->lastline = line;
835 fs->lastlineOffset = p - fs->f->packedlineinfo - 1;
836#undef addDLbyte
837}
838#endif
839
840
787void luaK_fixline (FuncState *fs, int line) { 841void luaK_fixline (FuncState *fs, int line) {
842#ifdef LUA_OPTIMIZE_DEBUG
843 /* The fixup line can be the same as existing one and in this case there's nothing to do */
844 if (line != fs->lastline) {
845 /* first remove the current line reference */
846 unsigned char *p = lineInfoTop(fs);
847 lua_assert(*p < 127);
848 if (*p >1) {
849 (*p)--; /* this is simply decrementing the last count a multi-PC line */
850 } else {
851 /* it's a bit more complicated if it's the 1st instruction on the line */
852 int delta = 0;
853 unsigned char code;
854 /* this logic handles <i/c> [1snnnnnnn [1nnnnnnn]*]? <i/c=1> */
855 *p-- = INFO_FILL_BYTE;
856 /* work backwards over the coded delta computing the delta */
857 while ((code=*p) & INFO_DELTA_MASK) {
858 *p-- = INFO_FILL_BYTE;
859 if (*p & INFO_DELTA_MASK) {
860 delta += ((code & INFO_DELTA_7BITS)<<7);
861 } else {
862 delta += (code & INFO_DELTA_6BITS) + 1;
863 if (code & INFO_SIGN_MASK) delta = -delta;
864 }
865 }
866 /* and reposition the FuncState lastline pointers at the previous instruction count */
867 fs->lastline-= delta + 1;
868 fs->lastlineOffset = p - fs->f->packedlineinfo;
869 }
870 /* Then add the new line reference */
871 generateInfoDeltaLine(fs, line);
872 }
873#else
788 fs->f->lineinfo[fs->pc - 1] = line; 874 fs->f->lineinfo[fs->pc - 1] = line;
875#endif
789} 876}
790 877
791 878
@@ -797,9 +884,25 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
797 MAX_INT, "code size overflow"); 884 MAX_INT, "code size overflow");
798 f->code[fs->pc] = i; 885 f->code[fs->pc] = i;
799 /* save corresponding line information */ 886 /* save corresponding line information */
887#ifdef LUA_OPTIMIZE_DEBUG
888 /* note that frst time fs->lastline==0 through, so the else branch is taken */
889 if (fs->pc == fs->lineinfoLastPC+1) {
890 if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) {
891 f->packedlineinfo[fs->lastlineOffset]++;
892 } else {
893 generateInfoDeltaLine(fs, line);
894 }
895 } else {
896 /* The last instruction is occasionally overwritten as part of branch optimisation*/
897 lua_assert(fs->pc == fs->lineinfoLastPC); /* panic if its anything other than this !! */
898 luaK_fixline(fs,line);
899 }
900 fs->lineinfoLastPC = fs->pc;
901#else
800 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, 902 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
801 MAX_INT, "code size overflow"); 903 MAX_INT, "code size overflow");
802 f->lineinfo[fs->pc] = line; 904 f->lineinfo[fs->pc] = line;
905#endif
803 return fs->pc++; 906 return fs->pc++;
804} 907}
805 908
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 */
221LUAI_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
249static 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! */
273LUAI_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
193static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 288static 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}
diff --git a/apps/plugins/lua/ldebug.h b/apps/plugins/lua/ldebug.h
index 22226b4096..7aa9f459d5 100644
--- a/apps/plugins/lua/ldebug.h
+++ b/apps/plugins/lua/ldebug.h
@@ -13,7 +13,19 @@
13 13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15 15
16#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 16#ifdef LUA_OPTIMIZE_DEBUG
17# include "lvm.h"
18# define getline(f,pc) (((f)->packedlineinfo) ? luaG_getline((f), pc) : 0)
19# define INFO_FILL_BYTE 0x7F
20# define INFO_DELTA_MASK 0x80
21# define INFO_SIGN_MASK 0x40
22# define INFO_DELTA_6BITS 0x3F
23# define INFO_DELTA_7BITS 0x7F
24# define INFO_MAX_LINECNT 126
25# define lineInfoTop(fs) ((fs)->f->packedlineinfo + (fs)->lastlineOffset)
26#else
27# define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
28#endif
17 29
18#define resethookcount(L) (L->hookcount = L->basehookcount) 30#define resethookcount(L) (L->hookcount = L->basehookcount)
19 31
@@ -30,4 +42,9 @@ LUAI_FUNC void luaG_errormsg (lua_State *L);
30LUAI_FUNC int luaG_checkcode (const Proto *pt); 42LUAI_FUNC int luaG_checkcode (const Proto *pt);
31LUAI_FUNC int luaG_checkopenop (Instruction i); 43LUAI_FUNC int luaG_checkopenop (Instruction i);
32 44
45#ifdef LUA_OPTIMIZE_DEBUG
46LUAI_FUNC int luaG_getline (const Proto *f, int pc);
47LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
48#endif
49
33#endif 50#endif
diff --git a/apps/plugins/lua/ldump.c b/apps/plugins/lua/ldump.c
index 9afba60a37..be7dce3497 100644
--- a/apps/plugins/lua/ldump.c
+++ b/apps/plugins/lua/ldump.c
@@ -113,8 +113,17 @@ static void DumpConstants(const Proto* f, DumpState* D)
113static void DumpDebug(const Proto* f, DumpState* D) 113static void DumpDebug(const Proto* f, DumpState* D)
114{ 114{
115 int i,n; 115 int i,n;
116#ifdef LUA_OPTIMIZE_DEBUG
117 n = (D->strip || f->packedlineinfo == NULL) ? 0: f->sizelineinfo;
118 DumpInt(n,D);
119 if (n)
120 {
121 DumpBlock(f->packedlineinfo, n, D);
122 }
123#else
116 n= (D->strip) ? 0 : f->sizelineinfo; 124 n= (D->strip) ? 0 : f->sizelineinfo;
117 DumpVector(f->lineinfo,n,sizeof(int),D); 125 DumpVector(f->lineinfo,n,sizeof(int),D);
126#endif
118 n= (D->strip) ? 0 : f->sizelocvars; 127 n= (D->strip) ? 0 : f->sizelocvars;
119 DumpInt(n,D); 128 DumpInt(n,D);
120 for (i=0; i<n; i++) 129 for (i=0; i<n; i++)
diff --git a/apps/plugins/lua/lfunc.c b/apps/plugins/lua/lfunc.c
index d2ce63dc4b..ef275cecd2 100644
--- a/apps/plugins/lua/lfunc.c
+++ b/apps/plugins/lua/lfunc.c
@@ -128,12 +128,17 @@ Proto *luaF_newproto (lua_State *L) {
128 f->numparams = 0; 128 f->numparams = 0;
129 f->is_vararg = 0; 129 f->is_vararg = 0;
130 f->maxstacksize = 0; 130 f->maxstacksize = 0;
131 f->lineinfo = NULL;
132 f->sizelocvars = 0; 131 f->sizelocvars = 0;
133 f->locvars = NULL; 132 f->locvars = NULL;
134 f->linedefined = 0; 133 f->linedefined = 0;
135 f->lastlinedefined = 0; 134 f->lastlinedefined = 0;
136 f->source = NULL; 135 f->source = NULL;
136#ifdef LUA_OPTIMIZE_DEBUG
137 f->packedlineinfo = NULL;
138#else
139 f->lineinfo = NULL;
140
141#endif
137 return f; 142 return f;
138} 143}
139 144
@@ -142,7 +147,13 @@ void luaF_freeproto (lua_State *L, Proto *f) {
142 luaM_freearray(L, f->code, f->sizecode, Instruction); 147 luaM_freearray(L, f->code, f->sizecode, Instruction);
143 luaM_freearray(L, f->p, f->sizep, Proto *); 148 luaM_freearray(L, f->p, f->sizep, Proto *);
144 luaM_freearray(L, f->k, f->sizek, TValue); 149 luaM_freearray(L, f->k, f->sizek, TValue);
150#ifdef LUA_OPTIMIZE_DEBUG
151 if (f->packedlineinfo) {
152 luaM_freearray(L, f->packedlineinfo, f->sizelineinfo, unsigned char);
153 }
154#else
145 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 155 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
156#endif
146 luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); 157 luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
147 luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 158 luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
148 luaM_free(L, f); 159 luaM_free(L, f);
diff --git a/apps/plugins/lua/lgc.c b/apps/plugins/lua/lgc.c
index 17b64a103b..2a4d95aba8 100644
--- a/apps/plugins/lua/lgc.c
+++ b/apps/plugins/lua/lgc.c
@@ -318,9 +318,13 @@ static l_mem propagatemark (global_State *g) {
318 return sizeof(Proto) + sizeof(Instruction) * p->sizecode + 318 return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
319 sizeof(Proto *) * p->sizep + 319 sizeof(Proto *) * p->sizep +
320 sizeof(TValue) * p->sizek + 320 sizeof(TValue) * p->sizek +
321 sizeof(int) * p->sizelineinfo +
322 sizeof(LocVar) * p->sizelocvars + 321 sizeof(LocVar) * p->sizelocvars +
323 sizeof(TString *) * p->sizeupvalues; 322 sizeof(TString *) * p->sizeupvalues +
323#ifdef LUA_OPTIMIZE_DEBUG
324 p->sizelineinfo;
325#else
326 sizeof(int) * p->sizelineinfo;
327#endif
324 } 328 }
325 default: lua_assert(0); return 0; 329 default: lua_assert(0); return 0;
326 } 330 }
diff --git a/apps/plugins/lua/lobject.h b/apps/plugins/lua/lobject.h
index 028ff0355b..83651c2c47 100644
--- a/apps/plugins/lua/lobject.h
+++ b/apps/plugins/lua/lobject.h
@@ -240,7 +240,11 @@ typedef struct Proto {
240 TValue *k; /* constants used by the function */ 240 TValue *k; /* constants used by the function */
241 Instruction *code; 241 Instruction *code;
242 struct Proto **p; /* functions defined inside the function */ 242 struct Proto **p; /* functions defined inside the function */
243#ifdef LUA_OPTIMIZE_DEBUG
244 unsigned char *packedlineinfo;
245#else
243 int *lineinfo; /* map from opcodes to source lines */ 246 int *lineinfo; /* map from opcodes to source lines */
247#endif
244 struct LocVar *locvars; /* information about local variables */ 248 struct LocVar *locvars; /* information about local variables */
245 TString **upvalues; /* upvalue names */ 249 TString **upvalues; /* upvalue names */
246 TString *source; 250 TString *source;
diff --git a/apps/plugins/lua/lparser.c b/apps/plugins/lua/lparser.c
index d002e96b86..bb08c51c0b 100644
--- a/apps/plugins/lua/lparser.c
+++ b/apps/plugins/lua/lparser.c
@@ -344,6 +344,11 @@ static void open_func (LexState *ls, FuncState *fs) {
344 fs->bl = NULL; 344 fs->bl = NULL;
345 f->source = ls->source; 345 f->source = ls->source;
346 f->maxstacksize = 2; /* registers 0/1 are always valid */ 346 f->maxstacksize = 2; /* registers 0/1 are always valid */
347#ifdef LUA_OPTIMIZE_DEBUG
348 fs->lastline = 0;
349 fs->lastlineOffset = 0;
350 fs->lineinfoLastPC = -1;
351#endif
347 fs->h = luaH_new(L, 0, 0); 352 fs->h = luaH_new(L, 0, 0);
348 /* anchor table of constants and prototype (to avoid being collected) */ 353 /* anchor table of constants and prototype (to avoid being collected) */
349 sethvalue2s(L, L->top, fs->h); 354 sethvalue2s(L, L->top, fs->h);
@@ -361,8 +366,14 @@ static void close_func (LexState *ls) {
361 luaK_ret(fs, 0, 0); /* final return */ 366 luaK_ret(fs, 0, 0); /* final return */
362 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); 367 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
363 f->sizecode = fs->pc; 368 f->sizecode = fs->pc;
369#ifdef LUA_OPTIMIZE_DEBUG
370 f->packedlineinfo[fs->lastlineOffset+1]=0;
371 luaM_reallocvector(L, f->packedlineinfo, f->sizelineinfo,
372 fs->lastlineOffset+2, unsigned char);
373#else
364 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); 374 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
365 f->sizelineinfo = fs->pc; 375 f->sizelineinfo = fs->pc;
376#endif
366 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); 377 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
367 f->sizek = fs->nk; 378 f->sizek = fs->nk;
368 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); 379 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
@@ -379,6 +390,23 @@ static void close_func (LexState *ls) {
379 L->top -= 2; /* remove table and prototype from the stack */ 390 L->top -= 2; /* remove table and prototype from the stack */
380} 391}
381 392
393#ifdef LUA_OPTIMIZE_DEBUG
394static void compile_stripdebug(lua_State *L, Proto *f) {
395 int level;
396#ifdef LUA_OPTIMIZE_DEBUG_USER
397 lua_pushlightuserdata(L, &luaG_stripdebug);
398 lua_gettable(L, LUA_REGISTRYINDEX);
399 level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1);
400 lua_pop(L, 1);
401#else
402 level = LUA_OPTIMIZE_DEBUG;
403#endif
404
405 if (level > 1) {
406 luaG_stripdebug(L, f, level, 16);
407 }
408}
409#endif
382 410
383Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { 411Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
384 struct LexState lexstate; 412 struct LexState lexstate;
@@ -395,6 +423,9 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
395 check(&lexstate, TK_EOS); 423 check(&lexstate, TK_EOS);
396 close_func(&lexstate); 424 close_func(&lexstate);
397 L->top--; /* remove 'name' from stack */ 425 L->top--; /* remove 'name' from stack */
426#ifdef LUA_OPTIMIZE_DEBUG
427 compile_stripdebug(L, funcstate.f);
428#endif
398 lua_assert(funcstate.prev == NULL); 429 lua_assert(funcstate.prev == NULL);
399 lua_assert(funcstate.f->nups == 0); 430 lua_assert(funcstate.f->nups == 0);
400 lua_assert(lexstate.fs == NULL); 431 lua_assert(lexstate.fs == NULL);
@@ -402,7 +433,6 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
402} 433}
403 434
404 435
405
406/*============================================================*/ 436/*============================================================*/
407/* GRAMMAR RULES */ 437/* GRAMMAR RULES */
408/*============================================================*/ 438/*============================================================*/
diff --git a/apps/plugins/lua/lparser.h b/apps/plugins/lua/lparser.h
index f9b8e24913..a6af9eb94f 100644
--- a/apps/plugins/lua/lparser.h
+++ b/apps/plugins/lua/lparser.h
@@ -72,6 +72,11 @@ typedef struct FuncState {
72 lu_byte nactvar; /* number of active local variables */ 72 lu_byte nactvar; /* number of active local variables */
73 upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ 73 upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
74 unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ 74 unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
75#ifdef LUA_OPTIMIZE_DEBUG
76 int lastline; /* only used during compilation for line info */
77 int lastlineOffset; /* ditto */
78 int lineinfoLastPC; /* ditto */
79#endif
75} FuncState; 80} FuncState;
76 81
77 82
diff --git a/apps/plugins/lua/lua.h b/apps/plugins/lua/lua.h
index a4b73e743e..74331e924f 100644
--- a/apps/plugins/lua/lua.h
+++ b/apps/plugins/lua/lua.h
@@ -94,6 +94,9 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
94#include LUA_USER_H 94#include LUA_USER_H
95#endif 95#endif
96 96
97#if defined(LUA_OPTIMIZE_DEBUG) && LUA_OPTIMIZE_DEBUG == 0
98#undef LUA_OPTIMIZE_DEBUG
99#endif
97 100
98/* type of numbers in Lua */ 101/* type of numbers in Lua */
99typedef LUA_NUMBER lua_Number; 102typedef LUA_NUMBER lua_Number;
diff --git a/apps/plugins/lua/luaconf.h b/apps/plugins/lua/luaconf.h
index 62a3ea0f6b..f7dd99b19e 100644
--- a/apps/plugins/lua/luaconf.h
+++ b/apps/plugins/lua/luaconf.h
@@ -818,5 +818,6 @@ extern long rb_pow(long, long);
818/*else*/ 818/*else*/
819#define LUA_USER_H "lua_user.h" 819#define LUA_USER_H "lua_user.h"
820#define LUA_DISABLE_BYTECODE 820#define LUA_DISABLE_BYTECODE
821#define LUA_OPTIMIZE_DEBUG 2 /* Lua Compact Debug -- Terry Ellison 2015 */
821 822
822#endif 823#endif
diff --git a/apps/plugins/lua/lundump.c b/apps/plugins/lua/lundump.c
index 967b45c94b..13f910edd7 100644
--- a/apps/plugins/lua/lundump.c
+++ b/apps/plugins/lua/lundump.c
@@ -140,9 +140,18 @@ static void LoadDebug(LoadState* S, Proto* f)
140{ 140{
141 int i,n; 141 int i,n;
142 n=LoadInt(S); 142 n=LoadInt(S);
143#ifdef LUA_OPTIMIZE_DEBUG
144 if(n) {
145 f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
146 LoadBlock(S,f->packedlineinfo,n);
147 } else {
148 f->packedlineinfo=NULL;
149 }
150#else
143 f->lineinfo=luaM_newvector(S->L,n,int); 151 f->lineinfo=luaM_newvector(S->L,n,int);
144 f->sizelineinfo=n; 152 f->sizelineinfo=n;
145 LoadVector(S,f->lineinfo,n,sizeof(int)); 153 LoadVector(S,f->lineinfo,n,sizeof(int));
154#endif
146 n=LoadInt(S); 155 n=LoadInt(S);
147 f->locvars=luaM_newvector(S->L,n,LocVar); 156 f->locvars=luaM_newvector(S->L,n,LocVar);
148 f->sizelocvars=n; 157 f->sizelocvars=n;