summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lvm.c
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2019-07-12 05:23:52 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2019-07-28 15:17:48 +0200
commit45bd14b392622cb58e967a24e4652c510b3d43e4 (patch)
tree22bd2e5cafc2d82ecc4773f83de7f86515b4db43 /apps/plugins/lua/lvm.c
parent4beafe16fafc2e5c59734ef065a6f8d23766520d (diff)
downloadrockbox-45bd14b392622cb58e967a24e4652c510b3d43e4.tar.gz
rockbox-45bd14b392622cb58e967a24e4652c510b3d43e4.zip
Lua Add Emergency Garbage Collector
Derivative of work by RobertGabrielJakabosky http://lua-users.org/wiki/EmergencyGarbageCollector I've only implemented the not enough memory part and expanded this idea to adding a mechanism to signal the OOM condition of the plugin buffer which allows us to only grab the playback buffer after garbage collection fails (SO THE MUSIC KEEPS PLAYING AS LONG AS POSSIBLE) Change-Id: I684fb98b540ffc01f7ba324ab5b761ceb59b9f9b
Diffstat (limited to 'apps/plugins/lua/lvm.c')
-rw-r--r--apps/plugins/lua/lvm.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/apps/plugins/lua/lvm.c b/apps/plugins/lua/lvm.c
index 35a931d7a1..4979b6a88e 100644
--- a/apps/plugins/lua/lvm.c
+++ b/apps/plugins/lua/lvm.c
@@ -49,9 +49,10 @@ int luaV_tostring (lua_State *L, StkId obj) {
49 return 0; 49 return 0;
50 else { 50 else {
51 char s[LUAI_MAXNUMBER2STR]; 51 char s[LUAI_MAXNUMBER2STR];
52 ptrdiff_t objr = savestack(L, obj);
52 lua_Number n = nvalue(obj); 53 lua_Number n = nvalue(obj);
53 lua_number2str(s, n); 54 lua_number2str(s, n);
54 setsvalue2s(L, obj, luaS_new(L, s)); 55 setsvalue2s(L, restorestack(L, objr), luaS_new(L, s));
55 return 1; 56 return 1;
56 } 57 }
57} 58}
@@ -134,6 +135,9 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
134void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { 135void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
135 int loop; 136 int loop;
136 TValue temp; 137 TValue temp;
138 setnilvalue(L->top);
139 L->top++;
140 fixedstack(L);
137 for (loop = 0; loop < MAXTAGLOOP; loop++) { 141 for (loop = 0; loop < MAXTAGLOOP; loop++) {
138 const TValue *tm; 142 const TValue *tm;
139 if (ttistable(t)) { /* `t' is a table? */ 143 if (ttistable(t)) { /* `t' is a table? */
@@ -141,6 +145,8 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
141 TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ 145 TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
142 if (!ttisnil(oldval) || /* result is no nil? */ 146 if (!ttisnil(oldval) || /* result is no nil? */
143 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ 147 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
148 L->top--;
149 unfixedstack(L);
144 setobj2t(L, oldval, val); 150 setobj2t(L, oldval, val);
145 h->flags = 0; 151 h->flags = 0;
146 luaC_barriert(L, h, val); 152 luaC_barriert(L, h, val);
@@ -151,12 +157,15 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
151 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 157 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
152 luaG_typeerror(L, t, "index"); 158 luaG_typeerror(L, t, "index");
153 if (ttisfunction(tm)) { 159 if (ttisfunction(tm)) {
160 L->top--;
161 unfixedstack(L);
154 callTM(L, tm, t, key, val); 162 callTM(L, tm, t, key, val);
155 return; 163 return;
156 } 164 }
157 /* else repeat with `tm' */ 165 /* else repeat with `tm' */
158 setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ 166 setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */
159 t = &temp; 167 t = &temp;
168 setobj2s(L, L->top-1, t); /* need to protect value from EGC. */
160 } 169 }
161 luaG_runerror(L, "loop in settable"); 170 luaG_runerror(L, "loop in settable");
162} 171}
@@ -284,8 +293,11 @@ void luaV_concat (lua_State *L, int total, int last) {
284 StkId top = L->base + last + 1; 293 StkId top = L->base + last + 1;
285 int n = 2; /* number of elements handled in this pass (at least 2) */ 294 int n = 2; /* number of elements handled in this pass (at least 2) */
286 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { 295 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
287 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) 296 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) {
297 /* restore 'top' pointer, since stack might have been reallocted */
298 top = L->base + last + 1;
288 luaG_concaterror(L, top-2, top-1); 299 luaG_concaterror(L, top-2, top-1);
300 }
289 } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ 301 } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
290 (void)tostring(L, top - 2); /* result is first op (as string) */ 302 (void)tostring(L, top - 2); /* result is first op (as string) */
291 else { 303 else {
@@ -293,12 +305,14 @@ void luaV_concat (lua_State *L, int total, int last) {
293 size_t tl = tsvalue(top-1)->len; 305 size_t tl = tsvalue(top-1)->len;
294 char *buffer; 306 char *buffer;
295 int i; 307 int i;
308 fixedstack(L);
296 /* collect total length */ 309 /* collect total length */
297 for (n = 1; n < total && tostring(L, top-n-1); n++) { 310 for (n = 1; n < total && tostring(L, top-n-1); n++) {
298 size_t l = tsvalue(top-n-1)->len; 311 size_t l = tsvalue(top-n-1)->len;
299 if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); 312 if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
300 tl += l; 313 tl += l;
301 } 314 }
315 G(L)->buff.n = tl;
302 buffer = luaZ_openspace(L, &G(L)->buff, tl); 316 buffer = luaZ_openspace(L, &G(L)->buff, tl);
303 tl = 0; 317 tl = 0;
304 for (i=n; i>0; i--) { /* concat all strings */ 318 for (i=n; i>0; i--) { /* concat all strings */
@@ -307,6 +321,8 @@ void luaV_concat (lua_State *L, int total, int last) {
307 tl += l; 321 tl += l;
308 } 322 }
309 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); 323 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
324 luaZ_resetbuffer(&G(L)->buff);
325 unfixedstack(L);
310 } 326 }
311 total -= n-1; /* got `n' strings to create 1 new */ 327 total -= n-1; /* got `n' strings to create 1 new */
312 last -= n-1; 328 last -= n-1;
@@ -332,8 +348,13 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
332 default: lua_assert(0); break; 348 default: lua_assert(0); break;
333 } 349 }
334 } 350 }
335 else if (!call_binTM(L, rb, rc, ra, op)) 351 else {
336 luaG_aritherror(L, rb, rc); 352 ptrdiff_t br = savestack(L, rb);
353 ptrdiff_t cr = savestack(L, rc);
354 if (!call_binTM(L, rb, rc, ra, op)) {
355 luaG_aritherror(L, restorestack(L, br), restorestack(L, cr));
356 }
357 }
337} 358}
338 359
339 360
@@ -461,7 +482,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
461 case OP_NEWTABLE: { 482 case OP_NEWTABLE: {
462 int b = GETARG_B(i); 483 int b = GETARG_B(i);
463 int c = GETARG_C(i); 484 int c = GETARG_C(i);
464 sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); 485 Table *h;
486 Protect(h = luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
487 sethvalue(L, RA(i), h);
465 Protect(luaC_checkGC(L)); 488 Protect(luaC_checkGC(L));
466 continue; 489 continue;
467 } 490 }
@@ -547,9 +570,10 @@ void luaV_execute (lua_State *L, int nexeccalls) {
547 break; 570 break;
548 } 571 }
549 default: { /* try metamethod */ 572 default: { /* try metamethod */
573 ptrdiff_t br = savestack(L, rb);
550 Protect( 574 Protect(
551 if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) 575 if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
552 luaG_typeerror(L, rb, "get length of"); 576 luaG_typeerror(L, restorestack(L, br), "get length of");
553 ) 577 )
554 } 578 }
555 } 579 }
@@ -723,6 +747,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
723 int c = GETARG_C(i); 747 int c = GETARG_C(i);
724 int last; 748 int last;
725 Table *h; 749 Table *h;
750 fixedstack(L);
726 if (n == 0) { 751 if (n == 0) {
727 n = cast_int(L->top - ra) - 1; 752 n = cast_int(L->top - ra) - 1;
728 L->top = L->ci->top; 753 L->top = L->ci->top;
@@ -738,6 +763,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
738 setobj2t(L, luaH_setnum(L, h, last--), val); 763 setobj2t(L, luaH_setnum(L, h, last--), val);
739 luaC_barriert(L, h, val); 764 luaC_barriert(L, h, val);
740 } 765 }
766 unfixedstack(L);
741 continue; 767 continue;
742 } 768 }
743 case OP_CLOSE: { 769 case OP_CLOSE: {
@@ -750,7 +776,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
750 int nup, j; 776 int nup, j;
751 p = cl->p->p[GETARG_Bx(i)]; 777 p = cl->p->p[GETARG_Bx(i)];
752 nup = p->nups; 778 nup = p->nups;
779 fixedstack(L);
753 ncl = luaF_newLclosure(L, nup, cl->env); 780 ncl = luaF_newLclosure(L, nup, cl->env);
781 setclvalue(L, ra, ncl);
754 ncl->l.p = p; 782 ncl->l.p = p;
755 for (j=0; j<nup; j++, pc++) { 783 for (j=0; j<nup; j++, pc++) {
756 if (GET_OPCODE(*pc) == OP_GETUPVAL) 784 if (GET_OPCODE(*pc) == OP_GETUPVAL)
@@ -760,7 +788,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
760 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); 788 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
761 } 789 }
762 } 790 }
763 setclvalue(L, ra, ncl); 791 unfixedstack(L);
764 Protect(luaC_checkGC(L)); 792 Protect(luaC_checkGC(L));
765 continue; 793 continue;
766 } 794 }