diff options
Diffstat (limited to 'apps/plugins/lua')
-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); |