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