diff options
author | William Wilgus <me.theuser@yahoo.com> | 2019-07-12 05:23:52 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-07-28 15:17:48 +0200 |
commit | 45bd14b392622cb58e967a24e4652c510b3d43e4 (patch) | |
tree | 22bd2e5cafc2d82ecc4773f83de7f86515b4db43 /apps | |
parent | 4beafe16fafc2e5c59734ef065a6f8d23766520d (diff) | |
download | rockbox-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')
-rw-r--r-- | apps/plugins/lua/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/lua/lapi.c | 22 | ||||
-rw-r--r-- | apps/plugins/lua/lauxlib.c | 30 | ||||
-rw-r--r-- | apps/plugins/lua/ldo.c | 21 | ||||
-rw-r--r-- | apps/plugins/lua/lfunc.c | 2 | ||||
-rw-r--r-- | apps/plugins/lua/lgc.c | 60 | ||||
-rw-r--r-- | apps/plugins/lua/lgc.h | 24 | ||||
-rw-r--r-- | apps/plugins/lua/lobject.h | 36 | ||||
-rw-r--r-- | apps/plugins/lua/lparser.c | 6 | ||||
-rw-r--r-- | apps/plugins/lua/lstate.c | 7 | ||||
-rw-r--r-- | apps/plugins/lua/lstate.h | 1 | ||||
-rw-r--r-- | apps/plugins/lua/lstring.c | 28 | ||||
-rw-r--r-- | apps/plugins/lua/ltable.c | 3 | ||||
-rw-r--r-- | apps/plugins/lua/lua_user.c | 18 | ||||
-rw-r--r-- | apps/plugins/lua/lua_user.h | 14 | ||||
-rw-r--r-- | apps/plugins/lua/luaconf.h | 6 | ||||
-rw-r--r-- | apps/plugins/lua/lvm.c | 42 | ||||
-rw-r--r-- | apps/plugins/lua/lzio.h | 2 | ||||
-rw-r--r-- | apps/plugins/lua/rockconf.h | 1 | ||||
-rw-r--r-- | apps/plugins/lua/rocklib.c | 6 | ||||
-rw-r--r-- | apps/plugins/lua/tlsf_helper.c | 4 |
21 files changed, 266 insertions, 68 deletions
diff --git a/apps/plugins/lua/SOURCES b/apps/plugins/lua/SOURCES index 93fa5e9c83..481bf7672f 100644 --- a/apps/plugins/lua/SOURCES +++ b/apps/plugins/lua/SOURCES | |||
@@ -24,6 +24,7 @@ ltable.c | |||
24 | ltablib.c | 24 | ltablib.c |
25 | ltm.c | 25 | ltm.c |
26 | lundump.c | 26 | lundump.c |
27 | lua_user.c | ||
27 | lvm.c | 28 | lvm.c |
28 | lzio.c | 29 | lzio.c |
29 | rockaux.c | 30 | rockaux.c |
diff --git a/apps/plugins/lua/lapi.c b/apps/plugins/lua/lapi.c index 487d6b173a..6426cd94a9 100644 --- a/apps/plugins/lua/lapi.c +++ b/apps/plugins/lua/lapi.c | |||
@@ -547,7 +547,9 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { | |||
547 | lua_lock(L); | 547 | lua_lock(L); |
548 | t = index2adr(L, idx); | 548 | t = index2adr(L, idx); |
549 | api_checkvalidindex(L, t); | 549 | api_checkvalidindex(L, t); |
550 | fixedstack(L); | ||
550 | setsvalue(L, &key, luaS_new(L, k)); | 551 | setsvalue(L, &key, luaS_new(L, k)); |
552 | unfixedstack(L); | ||
551 | luaV_gettable(L, t, &key, L->top); | 553 | luaV_gettable(L, t, &key, L->top); |
552 | api_incr_top(L); | 554 | api_incr_top(L); |
553 | lua_unlock(L); | 555 | lua_unlock(L); |
@@ -656,14 +658,14 @@ LUA_API void lua_settable (lua_State *L, int idx) { | |||
656 | 658 | ||
657 | LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { | 659 | LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { |
658 | StkId t; | 660 | StkId t; |
659 | TValue key; | ||
660 | lua_lock(L); | 661 | lua_lock(L); |
661 | api_checknelems(L, 1); | 662 | api_checknelems(L, 1); |
662 | t = index2adr(L, idx); | 663 | t = index2adr(L, idx); |
663 | api_checkvalidindex(L, t); | 664 | api_checkvalidindex(L, t); |
664 | setsvalue(L, &key, luaS_new(L, k)); | 665 | setsvalue2s(L, L->top, luaS_new(L, k)); |
665 | luaV_settable(L, t, &key, L->top - 1); | 666 | api_incr_top(L); |
666 | L->top--; /* pop value */ | 667 | luaV_settable(L, t, L->top - 1, L->top - 2); |
668 | L->top -= 2; /* pop key and value */ | ||
667 | lua_unlock(L); | 669 | lua_unlock(L); |
668 | } | 670 | } |
669 | 671 | ||
@@ -674,7 +676,9 @@ LUA_API void lua_rawset (lua_State *L, int idx) { | |||
674 | api_checknelems(L, 2); | 676 | api_checknelems(L, 2); |
675 | t = index2adr(L, idx); | 677 | t = index2adr(L, idx); |
676 | api_check(L, ttistable(t)); | 678 | api_check(L, ttistable(t)); |
679 | fixedstack(L); | ||
677 | setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); | 680 | setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); |
681 | unfixedstack(L); | ||
678 | luaC_barriert(L, hvalue(t), L->top-1); | 682 | luaC_barriert(L, hvalue(t), L->top-1); |
679 | L->top -= 2; | 683 | L->top -= 2; |
680 | lua_unlock(L); | 684 | lua_unlock(L); |
@@ -687,7 +691,9 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { | |||
687 | api_checknelems(L, 1); | 691 | api_checknelems(L, 1); |
688 | o = index2adr(L, idx); | 692 | o = index2adr(L, idx); |
689 | api_check(L, ttistable(o)); | 693 | api_check(L, ttistable(o)); |
694 | fixedstack(L); | ||
690 | setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); | 695 | setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); |
696 | unfixedstack(L); | ||
691 | luaC_barriert(L, hvalue(o), L->top-1); | 697 | luaC_barriert(L, hvalue(o), L->top-1); |
692 | L->top--; | 698 | L->top--; |
693 | lua_unlock(L); | 699 | lua_unlock(L); |
@@ -903,11 +909,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
903 | g = G(L); | 909 | g = G(L); |
904 | switch (what) { | 910 | switch (what) { |
905 | case LUA_GCSTOP: { | 911 | case LUA_GCSTOP: { |
906 | g->GCthreshold = MAX_LUMEM; | 912 | set_block_gc(L); |
907 | break; | 913 | break; |
908 | } | 914 | } |
909 | case LUA_GCRESTART: { | 915 | case LUA_GCRESTART: { |
910 | g->GCthreshold = g->totalbytes; | 916 | unset_block_gc(L); |
911 | break; | 917 | break; |
912 | } | 918 | } |
913 | case LUA_GCCOLLECT: { | 919 | case LUA_GCCOLLECT: { |
@@ -924,6 +930,10 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
924 | break; | 930 | break; |
925 | } | 931 | } |
926 | case LUA_GCSTEP: { | 932 | case LUA_GCSTEP: { |
933 | if(is_block_gc(L)) { | ||
934 | res = 1; /* gc is block so we need to pretend that the collection cycle finished. */ | ||
935 | break; | ||
936 | } | ||
927 | lu_mem a = (cast(lu_mem, data) << 10); | 937 | lu_mem a = (cast(lu_mem, data) << 10); |
928 | if (a <= g->totalbytes) | 938 | if (a <= g->totalbytes) |
929 | g->GCthreshold = g->totalbytes - a; | 939 | g->GCthreshold = g->totalbytes - a; |
diff --git a/apps/plugins/lua/lauxlib.c b/apps/plugins/lua/lauxlib.c index 2e4b3b1e3c..acd7e0e636 100644 --- a/apps/plugins/lua/lauxlib.c +++ b/apps/plugins/lua/lauxlib.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include "lstring.h" /* ROCKLUA ADDED */ | 14 | #include "lstring.h" /* ROCKLUA ADDED */ |
15 | 15 | ||
16 | |||
17 | /* This file uses only the official API of Lua. | 16 | /* This file uses only the official API of Lua. |
18 | ** Any function declared here could be written as an application function. | 17 | ** Any function declared here could be written as an application function. |
19 | ** Note ** luaS_newlloc breaks this guarantee ROCKLUA ADDED | 18 | ** Note ** luaS_newlloc breaks this guarantee ROCKLUA ADDED |
@@ -34,7 +33,9 @@ | |||
34 | #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ | 33 | #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ |
35 | lua_gettop(L) + (i) + 1) | 34 | lua_gettop(L) + (i) + 1) |
36 | 35 | ||
37 | 36 | #ifndef LUA_OOM | |
37 | #define LUA_OOM(L) {} | ||
38 | #endif | ||
38 | /* | 39 | /* |
39 | ** {====================================================== | 40 | ** {====================================================== |
40 | ** Error-report functions | 41 | ** Error-report functions |
@@ -756,14 +757,30 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { | |||
756 | 757 | ||
757 | 758 | ||
758 | static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { | 759 | static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { |
759 | (void)ud; | 760 | (void) osize; |
760 | (void)osize; | 761 | lua_State *L = (lua_State *)ud; |
762 | void *nptr; | ||
763 | |||
761 | if (nsize == 0) { | 764 | if (nsize == 0) { |
762 | free(ptr); | 765 | free(ptr); |
763 | return NULL; | 766 | return NULL; |
764 | } | 767 | } |
765 | else | 768 | |
766 | return realloc(ptr, nsize); | 769 | nptr = realloc(ptr, nsize); |
770 | if (nptr == NULL) { | ||
771 | if(L != NULL) | ||
772 | { | ||
773 | luaC_fullgc(L); /* emergency full collection. */ | ||
774 | nptr = realloc(ptr, nsize); /* try allocation again */ | ||
775 | } | ||
776 | |||
777 | if (nptr == NULL) { | ||
778 | LUA_OOM(L); /* if defined.. signal OOM condition */ | ||
779 | nptr = realloc(ptr, nsize); /* try allocation again */ | ||
780 | } | ||
781 | } | ||
782 | |||
783 | return nptr; | ||
767 | } | 784 | } |
768 | 785 | ||
769 | 786 | ||
@@ -779,6 +796,7 @@ static int panic (lua_State *L) { | |||
779 | 796 | ||
780 | LUALIB_API lua_State *luaL_newstate (void) { | 797 | LUALIB_API lua_State *luaL_newstate (void) { |
781 | lua_State *L = lua_newstate(l_alloc, NULL); | 798 | lua_State *L = lua_newstate(l_alloc, NULL); |
799 | lua_setallocf(L, l_alloc, L); /* allocator needs lua_State. */ | ||
782 | if (L) lua_atpanic(L, &panic); | 800 | if (L) lua_atpanic(L, &panic); |
783 | return L; | 801 | return L; |
784 | } | 802 | } |
diff --git a/apps/plugins/lua/ldo.c b/apps/plugins/lua/ldo.c index 43266de95e..7eccc54480 100644 --- a/apps/plugins/lua/ldo.c +++ b/apps/plugins/lua/ldo.c | |||
@@ -51,11 +51,13 @@ struct lua_longjmp { | |||
51 | void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { | 51 | void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { |
52 | switch (errcode) { | 52 | switch (errcode) { |
53 | case LUA_ERRMEM: { | 53 | case LUA_ERRMEM: { |
54 | setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); | 54 | ptrdiff_t oldtopr = savestack(L, oldtop); |
55 | setsvalue2s(L, restorestack(L, oldtopr), luaS_newliteral(L, MEMERRMSG)); | ||
55 | break; | 56 | break; |
56 | } | 57 | } |
57 | case LUA_ERRERR: { | 58 | case LUA_ERRERR: { |
58 | setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); | 59 | ptrdiff_t oldtopr = savestack(L, oldtop); |
60 | setsvalue2s(L, restorestack(L, oldtopr), luaS_newliteral(L, "error in error handling")); | ||
59 | break; | 61 | break; |
60 | } | 62 | } |
61 | case LUA_ERRSYNTAX: | 63 | case LUA_ERRSYNTAX: |
@@ -92,6 +94,8 @@ static void resetstack (lua_State *L, int status) { | |||
92 | 94 | ||
93 | 95 | ||
94 | void luaD_throw (lua_State *L, int errcode) { | 96 | void luaD_throw (lua_State *L, int errcode) { |
97 | unfixedstack(L); /* make sure the fixedstack & block_gc flags get reset. */ | ||
98 | unset_block_gc(L); | ||
95 | if (L->errorJmp) { | 99 | if (L->errorJmp) { |
96 | L->errorJmp->status = errcode; | 100 | L->errorJmp->status = errcode; |
97 | LUAI_THROW(L, L->errorJmp); | 101 | LUAI_THROW(L, L->errorJmp); |
@@ -208,7 +212,9 @@ void luaD_callhook (lua_State *L, int event, int line) { | |||
208 | static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | 212 | static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { |
209 | int i; | 213 | int i; |
210 | int nfixargs = p->numparams; | 214 | int nfixargs = p->numparams; |
215 | #if defined(LUA_COMPAT_VARARG) | ||
211 | Table *htab = NULL; | 216 | Table *htab = NULL; |
217 | #endif | ||
212 | StkId base, fixed; | 218 | StkId base, fixed; |
213 | for (; actual < nfixargs; ++actual) | 219 | for (; actual < nfixargs; ++actual) |
214 | setnilvalue(L->top++); | 220 | setnilvalue(L->top++); |
@@ -219,10 +225,15 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | |||
219 | luaC_checkGC(L); | 225 | luaC_checkGC(L); |
220 | luaD_checkstack(L, p->maxstacksize); | 226 | luaD_checkstack(L, p->maxstacksize); |
221 | htab = luaH_new(L, nvar, 1); /* create `arg' table */ | 227 | htab = luaH_new(L, nvar, 1); /* create `arg' table */ |
228 | sethvalue2s(L, L->top, htab); /* put table on stack */ | ||
229 | incr_top(L); | ||
230 | fixedstack(L); | ||
222 | for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ | 231 | for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ |
223 | setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); | 232 | setobj2n(L, luaH_setnum(L, htab, i+1), L->top - 1 - nvar + i); |
233 | unfixedstack(L); | ||
224 | /* store counter in field `n' */ | 234 | /* store counter in field `n' */ |
225 | setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); | 235 | setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); |
236 | L->top--; /* remove table from stack */ | ||
226 | } | 237 | } |
227 | #endif | 238 | #endif |
228 | /* move fixed parameters to final position */ | 239 | /* move fixed parameters to final position */ |
@@ -232,11 +243,13 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | |||
232 | setobjs2s(L, L->top++, fixed+i); | 243 | setobjs2s(L, L->top++, fixed+i); |
233 | setnilvalue(fixed+i); | 244 | setnilvalue(fixed+i); |
234 | } | 245 | } |
246 | #if defined(LUA_COMPAT_VARARG) | ||
235 | /* add `arg' parameter */ | 247 | /* add `arg' parameter */ |
236 | if (htab) { | 248 | if (htab) { |
237 | sethvalue(L, L->top++, htab); | 249 | sethvalue(L, L->top++, htab); |
238 | lua_assert(iswhite(obj2gco(htab))); | 250 | lua_assert(iswhite(obj2gco(htab))); |
239 | } | 251 | } |
252 | #endif | ||
240 | return base; | 253 | return base; |
241 | } | 254 | } |
242 | 255 | ||
@@ -495,6 +508,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
495 | struct SParser *p = cast(struct SParser *, ud); | 508 | struct SParser *p = cast(struct SParser *, ud); |
496 | int c = luaZ_lookahead(p->z); | 509 | int c = luaZ_lookahead(p->z); |
497 | luaC_checkGC(L); | 510 | luaC_checkGC(L); |
511 | set_block_gc(L); /* stop collector during parsing */ | ||
498 | tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, | 512 | tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, |
499 | &p->buff, p->name); | 513 | &p->buff, p->name); |
500 | cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); | 514 | cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); |
@@ -503,6 +517,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
503 | cl->l.upvals[i] = luaF_newupval(L); | 517 | cl->l.upvals[i] = luaF_newupval(L); |
504 | setclvalue(L, L->top, cl); | 518 | setclvalue(L, L->top, cl); |
505 | incr_top(L); | 519 | incr_top(L); |
520 | unset_block_gc(L); | ||
506 | } | 521 | } |
507 | 522 | ||
508 | 523 | ||
diff --git a/apps/plugins/lua/lfunc.c b/apps/plugins/lua/lfunc.c index 813e88f583..d2ce63dc4b 100644 --- a/apps/plugins/lua/lfunc.c +++ b/apps/plugins/lua/lfunc.c | |||
@@ -66,7 +66,6 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
66 | } | 66 | } |
67 | uv = luaM_new(L, UpVal); /* not found: create a new one */ | 67 | uv = luaM_new(L, UpVal); /* not found: create a new one */ |
68 | uv->tt = LUA_TUPVAL; | 68 | uv->tt = LUA_TUPVAL; |
69 | uv->marked = luaC_white(g); | ||
70 | uv->v = level; /* current value lives in the stack */ | 69 | uv->v = level; /* current value lives in the stack */ |
71 | uv->next = *pp; /* chain it in the proper position */ | 70 | uv->next = *pp; /* chain it in the proper position */ |
72 | *pp = obj2gco(uv); | 71 | *pp = obj2gco(uv); |
@@ -74,6 +73,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
74 | uv->u.l.next = g->uvhead.u.l.next; | 73 | uv->u.l.next = g->uvhead.u.l.next; |
75 | uv->u.l.next->u.l.prev = uv; | 74 | uv->u.l.next->u.l.prev = uv; |
76 | g->uvhead.u.l.next = uv; | 75 | g->uvhead.u.l.next = uv; |
76 | luaC_marknew(L, obj2gco(uv)); | ||
77 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | 77 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); |
78 | return uv; | 78 | return uv; |
79 | } | 79 | } |
diff --git a/apps/plugins/lua/lgc.c b/apps/plugins/lua/lgc.c index 98194c1771..17b64a103b 100644 --- a/apps/plugins/lua/lgc.c +++ b/apps/plugins/lua/lgc.c | |||
@@ -58,6 +58,9 @@ | |||
58 | 58 | ||
59 | #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) | 59 | #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) |
60 | 60 | ||
61 | #ifndef yield | ||
62 | #define yield() {} | ||
63 | #endif | ||
61 | 64 | ||
62 | static void removeentry (Node *n) { | 65 | static void removeentry (Node *n) { |
63 | lua_assert(ttisnil(gval(n))); | 66 | lua_assert(ttisnil(gval(n))); |
@@ -232,8 +235,10 @@ static void traverseclosure (global_State *g, Closure *cl) { | |||
232 | int i; | 235 | int i; |
233 | lua_assert(cl->l.nupvalues == cl->l.p->nups); | 236 | lua_assert(cl->l.nupvalues == cl->l.p->nups); |
234 | markobject(g, cl->l.p); | 237 | markobject(g, cl->l.p); |
235 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ | 238 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ |
236 | markobject(g, cl->l.upvals[i]); | 239 | if(cl->l.upvals[i]) |
240 | markobject(g, cl->l.upvals[i]); | ||
241 | } | ||
237 | } | 242 | } |
238 | } | 243 | } |
239 | 244 | ||
@@ -258,6 +263,7 @@ static void traversestack (global_State *g, lua_State *l) { | |||
258 | CallInfo *ci; | 263 | CallInfo *ci; |
259 | markvalue(g, gt(l)); | 264 | markvalue(g, gt(l)); |
260 | lim = l->top; | 265 | lim = l->top; |
266 | if(l->stack == NULL) return; /* no stack to traverse */ | ||
261 | for (ci = l->base_ci; ci <= l->ci; ci++) { | 267 | for (ci = l->base_ci; ci <= l->ci; ci++) { |
262 | lua_assert(ci->top <= l->stack_last); | 268 | lua_assert(ci->top <= l->stack_last); |
263 | if (lim < ci->top) lim = ci->top; | 269 | if (lim < ci->top) lim = ci->top; |
@@ -266,7 +272,8 @@ static void traversestack (global_State *g, lua_State *l) { | |||
266 | markvalue(g, o); | 272 | markvalue(g, o); |
267 | for (; o <= lim; o++) | 273 | for (; o <= lim; o++) |
268 | setnilvalue(o); | 274 | setnilvalue(o); |
269 | checkstacksizes(l, lim); | 275 | if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */ |
276 | checkstacksizes(l, lim); | ||
270 | } | 277 | } |
271 | 278 | ||
272 | 279 | ||
@@ -419,8 +426,6 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | |||
419 | else { /* must erase `curr' */ | 426 | else { /* must erase `curr' */ |
420 | lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); | 427 | lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); |
421 | *p = curr->gch.next; | 428 | *p = curr->gch.next; |
422 | if (curr == g->rootgc) /* is the first element of the list? */ | ||
423 | g->rootgc = curr->gch.next; /* adjust first */ | ||
424 | freeobj(L, curr); | 429 | freeobj(L, curr); |
425 | } | 430 | } |
426 | } | 431 | } |
@@ -434,6 +439,8 @@ static void checkSizes (lua_State *L) { | |||
434 | if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && | 439 | if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && |
435 | g->strt.size > MINSTRTABSIZE*2) | 440 | g->strt.size > MINSTRTABSIZE*2) |
436 | luaS_resize(L, g->strt.size/2); /* table is too big */ | 441 | luaS_resize(L, g->strt.size/2); /* table is too big */ |
442 | /* it is not safe to re-size the buffer if it is in use. */ | ||
443 | if (luaZ_bufflen(&g->buff) > 0) return; | ||
437 | /* check size of buffer */ | 444 | /* check size of buffer */ |
438 | if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ | 445 | if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ |
439 | size_t newsize = luaZ_sizebuffer(&g->buff) / 2; | 446 | size_t newsize = luaZ_sizebuffer(&g->buff) / 2; |
@@ -552,6 +559,15 @@ static void atomic (lua_State *L) { | |||
552 | g->estimate = g->totalbytes - udsize; /* first estimate */ | 559 | g->estimate = g->totalbytes - udsize; /* first estimate */ |
553 | } | 560 | } |
554 | 561 | ||
562 | static void sweepstrstep (global_State *g, lua_State *L) { | ||
563 | lu_mem old = g->totalbytes; | ||
564 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | ||
565 | if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ | ||
566 | g->gcstate = GCSsweep; /* end sweep-string phase */ | ||
567 | lua_assert(old >= g->totalbytes); | ||
568 | g->estimate -= old - g->totalbytes; | ||
569 | } | ||
570 | |||
555 | 571 | ||
556 | static l_mem singlestep (lua_State *L) { | 572 | static l_mem singlestep (lua_State *L) { |
557 | global_State *g = G(L); | 573 | global_State *g = G(L); |
@@ -570,12 +586,7 @@ static l_mem singlestep (lua_State *L) { | |||
570 | } | 586 | } |
571 | } | 587 | } |
572 | case GCSsweepstring: { | 588 | case GCSsweepstring: { |
573 | lu_mem old = g->totalbytes; | 589 | sweepstrstep(g, L); |
574 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | ||
575 | if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ | ||
576 | g->gcstate = GCSsweep; /* end sweep-string phase */ | ||
577 | lua_assert(old >= g->totalbytes); | ||
578 | g->estimate -= old - g->totalbytes; | ||
579 | return GCSWEEPCOST; | 590 | return GCSWEEPCOST; |
580 | } | 591 | } |
581 | case GCSsweep: { | 592 | case GCSsweep: { |
@@ -609,10 +620,14 @@ static l_mem singlestep (lua_State *L) { | |||
609 | 620 | ||
610 | void luaC_step (lua_State *L) { | 621 | void luaC_step (lua_State *L) { |
611 | global_State *g = G(L); | 622 | global_State *g = G(L); |
623 | if(is_block_gc(L)) return; | ||
624 | set_block_gc(L); | ||
612 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; | 625 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; |
613 | if (lim == 0) | 626 | if (lim == 0) |
614 | lim = (MAX_LUMEM-1)/2; /* no limit */ | 627 | lim = (MAX_LUMEM-1)/2; /* no limit */ |
615 | g->gcdept += g->totalbytes - g->GCthreshold; | 628 | g->gcdept += g->totalbytes - g->GCthreshold; |
629 | if (g->estimate > g->totalbytes) | ||
630 | g->estimate = g->totalbytes; | ||
616 | do { | 631 | do { |
617 | lim -= singlestep(L); | 632 | lim -= singlestep(L); |
618 | if (g->gcstate == GCSpause) | 633 | if (g->gcstate == GCSpause) |
@@ -629,11 +644,23 @@ void luaC_step (lua_State *L) { | |||
629 | else { | 644 | else { |
630 | setthreshold(g); | 645 | setthreshold(g); |
631 | } | 646 | } |
647 | unset_block_gc(L); | ||
632 | } | 648 | } |
633 | 649 | ||
634 | 650 | ||
651 | int luaC_sweepstrgc (lua_State *L) { | ||
652 | global_State *g = G(L); | ||
653 | if (g->gcstate == GCSsweepstring) { | ||
654 | sweepstrstep(g, L); | ||
655 | return (g->gcstate == GCSsweepstring) ? 1 : 0; | ||
656 | } | ||
657 | return 0; | ||
658 | } | ||
659 | |||
635 | void luaC_fullgc (lua_State *L) { | 660 | void luaC_fullgc (lua_State *L) { |
636 | global_State *g = G(L); | 661 | global_State *g = G(L); |
662 | if(is_block_gc(L)) return; | ||
663 | set_block_gc(L); | ||
637 | if (g->gcstate <= GCSpropagate) { | 664 | if (g->gcstate <= GCSpropagate) { |
638 | /* reset sweep marks to sweep all elements (returning them to white) */ | 665 | /* reset sweep marks to sweep all elements (returning them to white) */ |
639 | g->sweepstrgc = 0; | 666 | g->sweepstrgc = 0; |
@@ -649,12 +676,15 @@ void luaC_fullgc (lua_State *L) { | |||
649 | while (g->gcstate != GCSfinalize) { | 676 | while (g->gcstate != GCSfinalize) { |
650 | lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); | 677 | lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); |
651 | singlestep(L); | 678 | singlestep(L); |
679 | yield(); | ||
652 | } | 680 | } |
653 | markroot(L); | 681 | markroot(L); |
654 | while (g->gcstate != GCSpause) { | 682 | while (g->gcstate != GCSpause) { |
655 | singlestep(L); | 683 | singlestep(L); |
684 | yield(); | ||
656 | } | 685 | } |
657 | setthreshold(g); | 686 | setthreshold(g); |
687 | unset_block_gc(L); | ||
658 | } | 688 | } |
659 | 689 | ||
660 | 690 | ||
@@ -682,6 +712,14 @@ void luaC_barrierback (lua_State *L, Table *t) { | |||
682 | } | 712 | } |
683 | 713 | ||
684 | 714 | ||
715 | void luaC_marknew (lua_State *L, GCObject *o) { | ||
716 | global_State *g = G(L); | ||
717 | o->gch.marked = luaC_white(g); | ||
718 | if (g->gcstate == GCSpropagate) | ||
719 | reallymarkobject(g, o); /* mark new objects as gray during propagate state. */ | ||
720 | } | ||
721 | |||
722 | |||
685 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { | 723 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { |
686 | global_State *g = G(L); | 724 | global_State *g = G(L); |
687 | o->gch.next = g->rootgc; | 725 | o->gch.next = g->rootgc; |
diff --git a/apps/plugins/lua/lgc.h b/apps/plugins/lua/lgc.h index 5123ccb479..115008d6be 100644 --- a/apps/plugins/lua/lgc.h +++ b/apps/plugins/lua/lgc.h | |||
@@ -37,12 +37,30 @@ | |||
37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) | 37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) |
38 | 38 | ||
39 | 39 | ||
40 | /* | ||
41 | ** Possible Garbage Collector flags. | ||
42 | ** Layout for bit use in 'gsflags' field in global_State structure. | ||
43 | ** bit 0 - Protect GC from recursive calls. | ||
44 | ** bit 1 - Don't try to shrink string table if EGC was called during a string table resize. | ||
45 | */ | ||
46 | #define GCFlagsNone 0 | ||
47 | #define GCBlockGCBit 0 | ||
48 | #define GCResizingStringsBit 1 | ||
49 | |||
50 | |||
51 | #define is_block_gc(L) testbit(G(L)->gcflags, GCBlockGCBit) | ||
52 | #define set_block_gc(L) l_setbit(G(L)->gcflags, GCBlockGCBit) | ||
53 | #define unset_block_gc(L) resetbit(G(L)->gcflags, GCBlockGCBit) | ||
54 | #define is_resizing_strings_gc(L) testbit(G(L)->gcflags, GCResizingStringsBit) | ||
55 | #define set_resizing_strings_gc(L) l_setbit(G(L)->gcflags, GCResizingStringsBit) | ||
56 | #define unset_resizing_strings_gc(L) resetbit(G(L)->gcflags, GCResizingStringsBit) | ||
40 | 57 | ||
41 | /* | 58 | /* |
42 | ** Layout for bit use in `marked' field: | 59 | ** Layout for bit use in `marked' field: |
43 | ** bit 0 - object is white (type 0) | 60 | ** bit 0 - object is white (type 0) |
44 | ** bit 1 - object is white (type 1) | 61 | ** bit 1 - object is white (type 1) |
45 | ** bit 2 - object is black | 62 | ** bit 2 - object is black |
63 | ** bit 3 - for thread: Don't resize thread's stack | ||
46 | ** bit 3 - for userdata: has been finalized | 64 | ** bit 3 - for userdata: has been finalized |
47 | ** bit 3 - for tables: has weak keys | 65 | ** bit 3 - for tables: has weak keys |
48 | ** bit 4 - for tables: has weak values | 66 | ** bit 4 - for tables: has weak values |
@@ -54,6 +72,7 @@ | |||
54 | #define WHITE0BIT 0 | 72 | #define WHITE0BIT 0 |
55 | #define WHITE1BIT 1 | 73 | #define WHITE1BIT 1 |
56 | #define BLACKBIT 2 | 74 | #define BLACKBIT 2 |
75 | #define FIXEDSTACKBIT 3 | ||
57 | #define FINALIZEDBIT 3 | 76 | #define FINALIZEDBIT 3 |
58 | #define KEYWEAKBIT 3 | 77 | #define KEYWEAKBIT 3 |
59 | #define VALUEWEAKBIT 4 | 78 | #define VALUEWEAKBIT 4 |
@@ -76,6 +95,9 @@ | |||
76 | 95 | ||
77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 96 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
78 | 97 | ||
98 | #define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT) | ||
99 | #define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT) | ||
100 | #define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT) | ||
79 | 101 | ||
80 | #define luaC_checkGC(L) { \ | 102 | #define luaC_checkGC(L) { \ |
81 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ | 103 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ |
@@ -101,6 +123,8 @@ LUAI_FUNC void luaC_callGCTM (lua_State *L); | |||
101 | LUAI_FUNC void luaC_freeall (lua_State *L); | 123 | LUAI_FUNC void luaC_freeall (lua_State *L); |
102 | LUAI_FUNC void luaC_step (lua_State *L); | 124 | LUAI_FUNC void luaC_step (lua_State *L); |
103 | LUAI_FUNC void luaC_fullgc (lua_State *L); | 125 | LUAI_FUNC void luaC_fullgc (lua_State *L); |
126 | LUAI_FUNC int luaC_sweepstrgc (lua_State *L); | ||
127 | LUAI_FUNC void luaC_marknew (lua_State *L, GCObject *o); | ||
104 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | 128 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); |
105 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); | 129 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); |
106 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); | 130 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); |
diff --git a/apps/plugins/lua/lobject.h b/apps/plugins/lua/lobject.h index 26d2a81b49..028ff0355b 100644 --- a/apps/plugins/lua/lobject.h +++ b/apps/plugins/lua/lobject.h | |||
@@ -117,42 +117,48 @@ typedef struct lua_TValue { | |||
117 | #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) | 117 | #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) |
118 | 118 | ||
119 | #define setnvalue(obj,x) \ | 119 | #define setnvalue(obj,x) \ |
120 | { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } | 120 | { lua_Number i_x = (x); TValue *i_o=(obj); i_o->value.n=i_x; i_o->tt=LUA_TNUMBER; } |
121 | 121 | ||
122 | #define setpvalue(obj,x) \ | 122 | #define setpvalue(obj,x) \ |
123 | { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } | 123 | { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; } |
124 | 124 | ||
125 | #define setbvalue(obj,x) \ | 125 | #define setbvalue(obj,x) \ |
126 | { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } | 126 | { int i_x = (x); TValue *i_o=(obj); i_o->value.b=i_x; i_o->tt=LUA_TBOOLEAN; } |
127 | 127 | ||
128 | #define setsvalue(L,obj,x) \ | 128 | #define setsvalue(L,obj,x) \ |
129 | { TValue *i_o=(obj); \ | 129 | { GCObject *i_x = cast(GCObject *, (x)); \ |
130 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ | 130 | TValue *i_o=(obj); \ |
131 | i_o->value.gc=i_x; i_o->tt=LUA_TSTRING; \ | ||
131 | checkliveness(G(L),i_o); } | 132 | checkliveness(G(L),i_o); } |
132 | 133 | ||
133 | #define setuvalue(L,obj,x) \ | 134 | #define setuvalue(L,obj,x) \ |
134 | { TValue *i_o=(obj); \ | 135 | { GCObject *i_x = cast(GCObject *, (x)); \ |
135 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ | 136 | TValue *i_o=(obj); \ |
137 | i_o->value.gc=i_x; i_o->tt=LUA_TUSERDATA; \ | ||
136 | checkliveness(G(L),i_o); } | 138 | checkliveness(G(L),i_o); } |
137 | 139 | ||
138 | #define setthvalue(L,obj,x) \ | 140 | #define setthvalue(L,obj,x) \ |
139 | { TValue *i_o=(obj); \ | 141 | { GCObject *i_x = cast(GCObject *, (x)); \ |
140 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ | 142 | TValue *i_o=(obj); \ |
143 | i_o->value.gc=i_x; i_o->tt=LUA_TTHREAD; \ | ||
141 | checkliveness(G(L),i_o); } | 144 | checkliveness(G(L),i_o); } |
142 | 145 | ||
143 | #define setclvalue(L,obj,x) \ | 146 | #define setclvalue(L,obj,x) \ |
144 | { TValue *i_o=(obj); \ | 147 | { GCObject *i_x = cast(GCObject *, (x)); \ |
145 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ | 148 | TValue *i_o=(obj); \ |
149 | i_o->value.gc=i_x; i_o->tt=LUA_TFUNCTION; \ | ||
146 | checkliveness(G(L),i_o); } | 150 | checkliveness(G(L),i_o); } |
147 | 151 | ||
148 | #define sethvalue(L,obj,x) \ | 152 | #define sethvalue(L,obj,x) \ |
149 | { TValue *i_o=(obj); \ | 153 | { GCObject *i_x = cast(GCObject *, (x)); \ |
150 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ | 154 | TValue *i_o=(obj); \ |
155 | i_o->value.gc=i_x; i_o->tt=LUA_TTABLE; \ | ||
151 | checkliveness(G(L),i_o); } | 156 | checkliveness(G(L),i_o); } |
152 | 157 | ||
153 | #define setptvalue(L,obj,x) \ | 158 | #define setptvalue(L,obj,x) \ |
154 | { TValue *i_o=(obj); \ | 159 | { GCObject *i_x = cast(GCObject *, (x)); \ |
155 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ | 160 | TValue *i_o=(obj); \ |
161 | i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \ | ||
156 | checkliveness(G(L),i_o); } | 162 | checkliveness(G(L),i_o); } |
157 | 163 | ||
158 | 164 | ||
diff --git a/apps/plugins/lua/lparser.c b/apps/plugins/lua/lparser.c index dda7488dca..d002e96b86 100644 --- a/apps/plugins/lua/lparser.c +++ b/apps/plugins/lua/lparser.c | |||
@@ -383,14 +383,18 @@ static void close_func (LexState *ls) { | |||
383 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { | 383 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { |
384 | struct LexState lexstate; | 384 | struct LexState lexstate; |
385 | struct FuncState funcstate; | 385 | struct FuncState funcstate; |
386 | TString *tname = luaS_new(L, name); | ||
387 | setsvalue2s(L, L->top, tname); /* protect name */ | ||
388 | incr_top(L); | ||
386 | lexstate.buff = buff; | 389 | lexstate.buff = buff; |
387 | luaX_setinput(L, &lexstate, z, luaS_new(L, name)); | 390 | luaX_setinput(L, &lexstate, z, tname); |
388 | open_func(&lexstate, &funcstate); | 391 | open_func(&lexstate, &funcstate); |
389 | funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ | 392 | funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ |
390 | luaX_next(&lexstate); /* read first token */ | 393 | luaX_next(&lexstate); /* read first token */ |
391 | chunk(&lexstate); | 394 | chunk(&lexstate); |
392 | check(&lexstate, TK_EOS); | 395 | check(&lexstate, TK_EOS); |
393 | close_func(&lexstate); | 396 | close_func(&lexstate); |
397 | L->top--; /* remove 'name' from stack */ | ||
394 | lua_assert(funcstate.prev == NULL); | 398 | lua_assert(funcstate.prev == NULL); |
395 | lua_assert(funcstate.f->nups == 0); | 399 | lua_assert(funcstate.f->nups == 0); |
396 | lua_assert(lexstate.fs == NULL); | 400 | lua_assert(lexstate.fs == NULL); |
diff --git a/apps/plugins/lua/lstate.c b/apps/plugins/lua/lstate.c index 4313b83a0c..67921d84a1 100644 --- a/apps/plugins/lua/lstate.c +++ b/apps/plugins/lua/lstate.c | |||
@@ -119,6 +119,8 @@ static void close_state (lua_State *L) { | |||
119 | lua_State *luaE_newthread (lua_State *L) { | 119 | lua_State *luaE_newthread (lua_State *L) { |
120 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); | 120 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); |
121 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); | 121 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); |
122 | setthvalue(L, L->top, L1); /* put thread on stack */ | ||
123 | incr_top(L); | ||
122 | preinit_state(L1, G(L)); | 124 | preinit_state(L1, G(L)); |
123 | stack_init(L1, L); /* init stack */ | 125 | stack_init(L1, L); /* init stack */ |
124 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ | 126 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ |
@@ -126,7 +128,8 @@ lua_State *luaE_newthread (lua_State *L) { | |||
126 | L1->basehookcount = L->basehookcount; | 128 | L1->basehookcount = L->basehookcount; |
127 | L1->hook = L->hook; | 129 | L1->hook = L->hook; |
128 | resethookcount(L1); | 130 | resethookcount(L1); |
129 | lua_assert(iswhite(obj2gco(L1))); | 131 | lua_assert(!isdead(G(L), obj2gco(L1))); |
132 | L->top--; /* remove thread from stack */ | ||
130 | return L1; | 133 | return L1; |
131 | } | 134 | } |
132 | 135 | ||
@@ -160,6 +163,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
160 | g->uvhead.u.l.prev = &g->uvhead; | 163 | g->uvhead.u.l.prev = &g->uvhead; |
161 | g->uvhead.u.l.next = &g->uvhead; | 164 | g->uvhead.u.l.next = &g->uvhead; |
162 | g->GCthreshold = 0; /* mark it as unfinished state */ | 165 | g->GCthreshold = 0; /* mark it as unfinished state */ |
166 | g->estimate = 0; | ||
163 | g->strt.size = 0; | 167 | g->strt.size = 0; |
164 | g->strt.nuse = 0; | 168 | g->strt.nuse = 0; |
165 | g->strt.hash = NULL; | 169 | g->strt.hash = NULL; |
@@ -167,6 +171,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
167 | luaZ_initbuffer(L, &g->buff); | 171 | luaZ_initbuffer(L, &g->buff); |
168 | g->panic = NULL; | 172 | g->panic = NULL; |
169 | g->gcstate = GCSpause; | 173 | g->gcstate = GCSpause; |
174 | g->gcflags = GCFlagsNone; | ||
170 | g->rootgc = obj2gco(L); | 175 | g->rootgc = obj2gco(L); |
171 | g->sweepstrgc = 0; | 176 | g->sweepstrgc = 0; |
172 | g->sweepgc = &g->rootgc; | 177 | g->sweepgc = &g->rootgc; |
diff --git a/apps/plugins/lua/lstate.h b/apps/plugins/lua/lstate.h index 94a6249461..82431bc5a9 100644 --- a/apps/plugins/lua/lstate.h +++ b/apps/plugins/lua/lstate.h | |||
@@ -71,6 +71,7 @@ typedef struct global_State { | |||
71 | void *ud; /* auxiliary data to `frealloc' */ | 71 | void *ud; /* auxiliary data to `frealloc' */ |
72 | lu_byte currentwhite; | 72 | lu_byte currentwhite; |
73 | lu_byte gcstate; /* state of garbage collector */ | 73 | lu_byte gcstate; /* state of garbage collector */ |
74 | lu_byte gcflags; /* flags for the garbage collector */ | ||
74 | int sweepstrgc; /* position of sweep in `strt' */ | 75 | int sweepstrgc; /* position of sweep in `strt' */ |
75 | GCObject *rootgc; /* list of all collectable objects */ | 76 | GCObject *rootgc; /* list of all collectable objects */ |
76 | GCObject **sweepgc; /* position of sweep in `rootgc' */ | 77 | GCObject **sweepgc; /* position of sweep in `rootgc' */ |
diff --git a/apps/plugins/lua/lstring.c b/apps/plugins/lua/lstring.c index bf0536e311..6d73f1e9ea 100644 --- a/apps/plugins/lua/lstring.c +++ b/apps/plugins/lua/lstring.c | |||
@@ -22,30 +22,34 @@ | |||
22 | 22 | ||
23 | 23 | ||
24 | void luaS_resize (lua_State *L, int newsize) { | 24 | void luaS_resize (lua_State *L, int newsize) { |
25 | GCObject **newhash; | ||
26 | stringtable *tb; | 25 | stringtable *tb; |
27 | int i; | 26 | int i; |
28 | if (G(L)->gcstate == GCSsweepstring) | ||
29 | return; /* cannot resize during GC traverse */ | ||
30 | newhash = luaM_newvector(L, newsize, GCObject *); | ||
31 | tb = &G(L)->strt; | 27 | tb = &G(L)->strt; |
32 | for (i=0; i<newsize; i++) newhash[i] = NULL; | 28 | if (luaC_sweepstrgc(L) || newsize == tb->size || is_resizing_strings_gc(L)) |
29 | return; /* cannot resize during GC traverse or doesn't need to be resized */ | ||
30 | set_resizing_strings_gc(L); | ||
31 | if (newsize > tb->size) { | ||
32 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | ||
33 | for (i=tb->size; i<newsize; i++) tb->hash[i] = NULL; | ||
34 | } | ||
33 | /* rehash */ | 35 | /* rehash */ |
34 | for (i=0; i<tb->size; i++) { | 36 | for (i=0; i<tb->size; i++) { |
35 | GCObject *p = tb->hash[i]; | 37 | GCObject *p = tb->hash[i]; |
38 | tb->hash[i] = NULL; | ||
36 | while (p) { /* for each node in the list */ | 39 | while (p) { /* for each node in the list */ |
37 | GCObject *next = p->gch.next; /* save next */ | 40 | GCObject *next = p->gch.next; /* save next */ |
38 | unsigned int h = gco2ts(p)->hash; | 41 | unsigned int h = gco2ts(p)->hash; |
39 | int h1 = lmod(h, newsize); /* new position */ | 42 | int h1 = lmod(h, newsize); /* new position */ |
40 | lua_assert(cast_int(h%newsize) == lmod(h, newsize)); | 43 | lua_assert(cast_int(h%newsize) == lmod(h, newsize)); |
41 | p->gch.next = newhash[h1]; /* chain it */ | 44 | p->gch.next = tb->hash[h1]; /* chain it */ |
42 | newhash[h1] = p; | 45 | tb->hash[h1] = p; |
43 | p = next; | 46 | p = next; |
44 | } | 47 | } |
45 | } | 48 | } |
46 | luaM_freearray(L, tb->hash, tb->size, TString *); | 49 | if (newsize < tb->size) |
50 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | ||
47 | tb->size = newsize; | 51 | tb->size = newsize; |
48 | tb->hash = newhash; | 52 | unset_resizing_strings_gc(L); |
49 | } | 53 | } |
50 | 54 | ||
51 | 55 | ||
@@ -55,6 +59,9 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, | |||
55 | stringtable *tb; | 59 | stringtable *tb; |
56 | if (l > ((MAX_SIZET - sizeof(TString))/sizeof(char)) - sizeof("")) | 60 | if (l > ((MAX_SIZET - sizeof(TString))/sizeof(char)) - sizeof("")) |
57 | luaM_toobig(L); | 61 | luaM_toobig(L); |
62 | tb = &G(L)->strt; | ||
63 | if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) | ||
64 | luaS_resize(L, tb->size*2); /* too crowded */ | ||
58 | ts = cast(TString *, luaM_malloc(L, sizetstring(type, l))); | 65 | ts = cast(TString *, luaM_malloc(L, sizetstring(type, l))); |
59 | ts->tsv.len = l; | 66 | ts->tsv.len = l; |
60 | ts->tsv.hash = h; | 67 | ts->tsv.hash = h; |
@@ -70,13 +77,10 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, | |||
70 | memcpy(ts+1, str, l*sizeof(char)); | 77 | memcpy(ts+1, str, l*sizeof(char)); |
71 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ | 78 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ |
72 | } | 79 | } |
73 | tb = &G(L)->strt; | ||
74 | h = lmod(h, tb->size); | 80 | h = lmod(h, tb->size); |
75 | ts->tsv.next = tb->hash[h]; /* chain new entry */ | 81 | ts->tsv.next = tb->hash[h]; /* chain new entry */ |
76 | tb->hash[h] = obj2gco(ts); | 82 | tb->hash[h] = obj2gco(ts); |
77 | tb->nuse++; | 83 | tb->nuse++; |
78 | if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) | ||
79 | luaS_resize(L, tb->size*2); /* too crowded */ | ||
80 | return ts; | 84 | return ts; |
81 | } | 85 | } |
82 | 86 | ||
diff --git a/apps/plugins/lua/ltable.c b/apps/plugins/lua/ltable.c index ec84f4fabc..31162fe7c1 100644 --- a/apps/plugins/lua/ltable.c +++ b/apps/plugins/lua/ltable.c | |||
@@ -358,6 +358,8 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) { | |||
358 | Table *luaH_new (lua_State *L, int narray, int nhash) { | 358 | Table *luaH_new (lua_State *L, int narray, int nhash) { |
359 | Table *t = luaM_new(L, Table); | 359 | Table *t = luaM_new(L, Table); |
360 | luaC_link(L, obj2gco(t), LUA_TTABLE); | 360 | luaC_link(L, obj2gco(t), LUA_TTABLE); |
361 | sethvalue2s(L, L->top, t); /* put table on stack */ | ||
362 | incr_top(L); | ||
361 | t->metatable = NULL; | 363 | t->metatable = NULL; |
362 | t->flags = cast_byte(~0); | 364 | t->flags = cast_byte(~0); |
363 | /* temporary values (kept only if some malloc fails) */ | 365 | /* temporary values (kept only if some malloc fails) */ |
@@ -367,6 +369,7 @@ Table *luaH_new (lua_State *L, int narray, int nhash) { | |||
367 | t->node = cast(Node *, dummynode); | 369 | t->node = cast(Node *, dummynode); |
368 | setarrayvector(L, t, narray); | 370 | setarrayvector(L, t, narray); |
369 | setnodevector(L, t, nhash); | 371 | setnodevector(L, t, nhash); |
372 | L->top--; /* remove table from stack */ | ||
370 | return t; | 373 | return t; |
371 | } | 374 | } |
372 | 375 | ||
diff --git a/apps/plugins/lua/lua_user.c b/apps/plugins/lua/lua_user.c new file mode 100644 index 0000000000..8d77dcdf3f --- /dev/null +++ b/apps/plugins/lua/lua_user.c | |||
@@ -0,0 +1,18 @@ | |||
1 | #include "plugin.h" | ||
2 | #include "lstate.h" | ||
3 | #include LUA_USER_H | ||
4 | |||
5 | /* lua Out Of Memory */ | ||
6 | static struct lua_OOM l_oom = {NULL, 0}; | ||
7 | |||
8 | int set_lua_OOM(lua_State * L) | ||
9 | { | ||
10 | l_oom.L = L; | ||
11 | l_oom.count++; | ||
12 | return 0; | ||
13 | } | ||
14 | |||
15 | struct lua_OOM *get_lua_OOM(void) | ||
16 | { | ||
17 | return &l_oom; | ||
18 | } | ||
diff --git a/apps/plugins/lua/lua_user.h b/apps/plugins/lua/lua_user.h new file mode 100644 index 0000000000..f18f5e9d14 --- /dev/null +++ b/apps/plugins/lua/lua_user.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef _LUA_USER_H_ | ||
2 | #define _LUA_USER_H_ | ||
3 | |||
4 | #define LUA_OOM(L) set_lua_OOM(L) | ||
5 | |||
6 | struct lua_OOM { | ||
7 | lua_State * L; | ||
8 | int count; | ||
9 | }; | ||
10 | |||
11 | int set_lua_OOM(lua_State * L); | ||
12 | |||
13 | struct lua_OOM* get_lua_OOM(void); | ||
14 | #endif | ||
diff --git a/apps/plugins/lua/luaconf.h b/apps/plugins/lua/luaconf.h index 582968d423..62a3ea0f6b 100644 --- a/apps/plugins/lua/luaconf.h +++ b/apps/plugins/lua/luaconf.h | |||
@@ -810,7 +810,13 @@ extern long rb_pow(long, long); | |||
810 | /*Rocklua functions*/ | 810 | /*Rocklua functions*/ |
811 | #include "rockconf.h" | 811 | #include "rockconf.h" |
812 | 812 | ||
813 | /* heap */ | ||
814 | #undef LUAI_GCPAUSE /*200*/ | ||
815 | #define LUAI_GCPAUSE 125 | ||
816 | #define MINSTRTABSIZE 512 /*32*/ | ||
817 | |||
813 | /*else*/ | 818 | /*else*/ |
819 | #define LUA_USER_H "lua_user.h" | ||
814 | #define LUA_DISABLE_BYTECODE | 820 | #define LUA_DISABLE_BYTECODE |
815 | 821 | ||
816 | #endif | 822 | #endif |
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) { | |||
134 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | 135 | void 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 | } |
diff --git a/apps/plugins/lua/lzio.h b/apps/plugins/lua/lzio.h index 9aa9e4b537..cb32e6abc4 100644 --- a/apps/plugins/lua/lzio.h +++ b/apps/plugins/lua/lzio.h | |||
@@ -27,7 +27,7 @@ typedef struct Mbuffer { | |||
27 | size_t buffsize; | 27 | size_t buffsize; |
28 | } Mbuffer; | 28 | } Mbuffer; |
29 | 29 | ||
30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) | 30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->n = 0, (buff)->buffsize = 0) |
31 | 31 | ||
32 | #define luaZ_buffer(buff) ((buff)->buffer) | 32 | #define luaZ_buffer(buff) ((buff)->buffer) |
33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) | 33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) |
diff --git a/apps/plugins/lua/rockconf.h b/apps/plugins/lua/rockconf.h index 89ab82e377..6a1141f86a 100644 --- a/apps/plugins/lua/rockconf.h +++ b/apps/plugins/lua/rockconf.h | |||
@@ -63,6 +63,7 @@ long lpow(long x, long y); | |||
63 | #define strcmp rb->strcmp | 63 | #define strcmp rb->strcmp |
64 | #define strcpy rb->strcpy | 64 | #define strcpy rb->strcpy |
65 | #define strlen rb->strlen | 65 | #define strlen rb->strlen |
66 | #define yield() rb->yield() | ||
66 | 67 | ||
67 | #endif /* _ROCKCONF_H_ */ | 68 | #endif /* _ROCKCONF_H_ */ |
68 | 69 | ||
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c index d1ef3adaaf..c266516602 100644 --- a/apps/plugins/lua/rocklib.c +++ b/apps/plugins/lua/rocklib.c | |||
@@ -304,7 +304,7 @@ RB_WRAP(playlist) | |||
304 | break; | 304 | break; |
305 | } | 305 | } |
306 | 306 | ||
307 | rb->yield(); | 307 | yield(); |
308 | lua_pushinteger(L, result); | 308 | lua_pushinteger(L, result); |
309 | return 1; | 309 | return 1; |
310 | } | 310 | } |
@@ -382,7 +382,7 @@ RB_WRAP(audio) | |||
382 | return 1; | 382 | return 1; |
383 | } | 383 | } |
384 | 384 | ||
385 | rb->yield(); | 385 | yield(); |
386 | lua_pushinteger(L, status); /* return previous (or current) audio status */ | 386 | lua_pushinteger(L, status); /* return previous (or current) audio status */ |
387 | return 1; | 387 | return 1; |
388 | } | 388 | } |
@@ -502,7 +502,7 @@ RB_WRAP(pcm) | |||
502 | break; | 502 | break; |
503 | } | 503 | } |
504 | 504 | ||
505 | rb->yield(); | 505 | yield(); |
506 | return 1; | 506 | return 1; |
507 | } | 507 | } |
508 | 508 | ||
diff --git a/apps/plugins/lua/tlsf_helper.c b/apps/plugins/lua/tlsf_helper.c index edf32eecf9..097d39c8e4 100644 --- a/apps/plugins/lua/tlsf_helper.c +++ b/apps/plugins/lua/tlsf_helper.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "plugin.h" | 21 | #include "plugin.h" |
22 | #include <tlsf.h> | 22 | #include <tlsf.h> |
23 | #include "lua.h" | ||
23 | 24 | ||
24 | void *get_new_area(size_t *size) | 25 | void *get_new_area(size_t *size) |
25 | { | 26 | { |
@@ -36,7 +37,8 @@ void *get_new_area(size_t *size) | |||
36 | return pluginbuf_ptr; | 37 | return pluginbuf_ptr; |
37 | } | 38 | } |
38 | 39 | ||
39 | if (audiobuf_ptr == NULL) | 40 | /* only grab the next area if lua already tried + failed to garbage collect*/ |
41 | if (audiobuf_ptr == NULL && (get_lua_OOM())->count > 0) | ||
40 | { | 42 | { |
41 | /* grab audiobuffer */ | 43 | /* grab audiobuffer */ |
42 | audiobuf_ptr = rb->plugin_get_audio_buffer(size); | 44 | audiobuf_ptr = rb->plugin_get_audio_buffer(size); |