summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c44
-rw-r--r--lapi.h8
-rw-r--r--ldebug.c17
-rw-r--r--ldo.c21
-rw-r--r--ldo.h4
-rw-r--r--lgc.c76
-rw-r--r--lgc.h4
-rw-r--r--llex.c7
-rw-r--r--lmem.c25
-rw-r--r--lobject.c12
-rw-r--r--lparser.c26
-rw-r--r--lstate.c21
-rw-r--r--lstate.h4
-rw-r--r--lstring.c9
-rw-r--r--ltable.c16
-rw-r--r--ltable.h5
-rw-r--r--ltests.c19
-rw-r--r--lvm.c23
-rw-r--r--makefile2
19 files changed, 190 insertions, 153 deletions
diff --git a/lapi.c b/lapi.c
index 0fa66eb4..e992d27e 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.54 2006/06/02 15:34:00 roberto Exp roberto $ 2** $Id: lapi.c,v 2.55 2006/06/07 12:37:17 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -42,9 +42,6 @@ const char lua_ident[] =
42 42
43#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) 43#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
44 44
45#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
46
47
48 45
49static TValue *index2adr (lua_State *L, int idx) { 46static TValue *index2adr (lua_State *L, int idx) {
50 if (idx > 0) { 47 if (idx > 0) {
@@ -86,12 +83,6 @@ static Table *getcurrenv (lua_State *L) {
86} 83}
87 84
88 85
89void luaA_pushobject (lua_State *L, const TValue *o) {
90 setobj2s(L, L->top, o);
91 api_incr_top(L);
92}
93
94
95LUA_API int lua_checkstack (lua_State *L, int size) { 86LUA_API int lua_checkstack (lua_State *L, int size) {
96 int res; 87 int res;
97 lua_lock(L); 88 lua_lock(L);
@@ -133,19 +124,6 @@ LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
133} 124}
134 125
135 126
136LUA_API lua_State *lua_newthread (lua_State *L) {
137 lua_State *L1;
138 lua_lock(L);
139 luaC_checkGC(L);
140 L1 = luaE_newthread(L);
141 setthvalue(L, L->top, L1);
142 api_incr_top(L);
143 lua_unlock(L);
144 luai_userstatethread(L, L1);
145 return L1;
146}
147
148
149 127
150/* 128/*
151** basic stack manipulation 129** basic stack manipulation
@@ -539,13 +517,12 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
539 517
540LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { 518LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
541 StkId t; 519 StkId t;
542 TValue key;
543 lua_lock(L); 520 lua_lock(L);
544 t = index2adr(L, idx); 521 t = index2adr(L, idx);
545 api_checkvalidindex(L, t); 522 api_checkvalidindex(L, t);
546 setsvalue(L, &key, luaS_new(L, k)); 523 setsvalue2s(L, L->top, luaS_new(L, k));
547 luaV_gettable(L, t, &key, L->top);
548 api_incr_top(L); 524 api_incr_top(L);
525 luaV_gettable(L, t, L->top - 1, L->top - 1);
549 lua_unlock(L); 526 lua_unlock(L);
550} 527}
551 528
@@ -572,10 +549,14 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
572 549
573 550
574LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { 551LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
552 Table *t;
575 lua_lock(L); 553 lua_lock(L);
576 luaC_checkGC(L); 554 luaC_checkGC(L);
577 sethvalue(L, L->top, luaH_new(L, narray, nrec)); 555 t = luaH_new(L);
556 sethvalue(L, L->top, t);
578 api_incr_top(L); 557 api_incr_top(L);
558 if (narray > 0 || nrec > 0)
559 luaH_resize(L, t, narray, nrec);
579 lua_unlock(L); 560 lua_unlock(L);
580} 561}
581 562
@@ -652,14 +633,13 @@ LUA_API void lua_settable (lua_State *L, int idx) {
652 633
653LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { 634LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
654 StkId t; 635 StkId t;
655 TValue key;
656 lua_lock(L); 636 lua_lock(L);
657 api_checknelems(L, 1); 637 api_checknelems(L, 1);
658 t = index2adr(L, idx); 638 t = index2adr(L, idx);
659 api_checkvalidindex(L, t); 639 api_checkvalidindex(L, t);
660 setsvalue(L, &key, luaS_new(L, k)); 640 setsvalue2s(L, L->top++, luaS_new(L, k));
661 luaV_settable(L, t, &key, L->top - 1); 641 luaV_settable(L, t, L->top - 1, L->top - 2);
662 L->top--; /* pop value */ 642 L->top -= 2; /* pop value and key */
663 lua_unlock(L); 643 lua_unlock(L);
664} 644}
665 645
@@ -907,7 +887,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
907 break; 887 break;
908 } 888 }
909 case LUA_GCCOLLECT: { 889 case LUA_GCCOLLECT: {
910 luaC_fullgc(L); 890 luaC_fullgc(L, 0);
911 break; 891 break;
912 } 892 }
913 case LUA_GCCOUNT: { 893 case LUA_GCCOUNT: {
diff --git a/lapi.h b/lapi.h
index bb522de5..b9ca73bf 100644
--- a/lapi.h
+++ b/lapi.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $ 2** $Id: lapi.h,v 2.2 2005/04/25 19:24:10 roberto Exp roberto $
3** Auxiliary functions from Lua API 3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -8,9 +8,9 @@
8#define lapi_h 8#define lapi_h
9 9
10 10
11#include "lobject.h" 11#include "llimits.h"
12#include "lstate.h"
12 13
13 14#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top);}
14LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
15 15
16#endif 16#endif
diff --git a/ldebug.c b/ldebug.c
index 4fa42ac9..66a32f37 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.28 2005/11/01 16:08:52 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.29 2005/12/22 16:19:56 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -128,8 +128,10 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
128 CallInfo *ci = L->base_ci + ar->i_ci; 128 CallInfo *ci = L->base_ci + ar->i_ci;
129 const char *name = findlocal(L, ci, n); 129 const char *name = findlocal(L, ci, n);
130 lua_lock(L); 130 lua_lock(L);
131 if (name) 131 if (name) {
132 luaA_pushobject(L, ci->base + (n - 1)); 132 setobj2s(L, L->top, ci->base + (n - 1));
133 api_incr_top(L);
134 }
133 lua_unlock(L); 135 lua_unlock(L);
134 return name; 136 return name;
135} 137}
@@ -177,16 +179,17 @@ static void info_tailcall (lua_Debug *ar) {
177static void collectvalidlines (lua_State *L, Closure *f) { 179static void collectvalidlines (lua_State *L, Closure *f) {
178 if (f == NULL || f->c.isC) { 180 if (f == NULL || f->c.isC) {
179 setnilvalue(L->top); 181 setnilvalue(L->top);
182 incr_top(L);
180 } 183 }
181 else { 184 else {
182 Table *t = luaH_new(L, 0, 0);
183 int *lineinfo = f->l.p->lineinfo;
184 int i; 185 int i;
186 int *lineinfo = f->l.p->lineinfo;
187 Table *t = luaH_new(L);
188 sethvalue(L, L->top, t);
189 incr_top(L);
185 for (i=0; i<f->l.p->sizelineinfo; i++) 190 for (i=0; i<f->l.p->sizelineinfo; i++)
186 setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); 191 setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
187 sethvalue(L, L->top, t);
188 } 192 }
189 incr_top(L);
190} 193}
191 194
192 195
diff --git a/ldo.c b/ldo.c
index d7a587e9..6ce1e519 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $ 2** $Id: ldo.c,v 2.38 2006/06/05 19:36:14 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -81,7 +81,7 @@ static void restore_stack_limit (lua_State *L) {
81static void resetstack (lua_State *L, int status) { 81static void resetstack (lua_State *L, int status) {
82 L->ci = L->base_ci; 82 L->ci = L->base_ci;
83 L->base = L->ci->base; 83 L->base = L->ci->base;
84 luaF_close(L, L->base); /* close eventual pending closures */ 84 luaF_close(L, L->base); /* close possible pending closures */
85 luaD_seterrorobj(L, status, L->base); 85 luaD_seterrorobj(L, status, L->base);
86 L->nCcalls = 0; 86 L->nCcalls = 0;
87 L->allowhook = 1; 87 L->allowhook = 1;
@@ -217,11 +217,13 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
217 int nvar = actual - nfixargs; /* number of extra arguments */ 217 int nvar = actual - nfixargs; /* number of extra arguments */
218 lua_assert(p->is_vararg & VARARG_HASARG); 218 lua_assert(p->is_vararg & VARARG_HASARG);
219 luaC_checkGC(L); 219 luaC_checkGC(L);
220 htab = luaH_new(L, nvar, 1); /* create `arg' table */ 220 htab = luaH_new(L); /* create `arg' table */
221 sethvalue(L, L->top++, htab);
221 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ 222 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
222 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); 223 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i - 1);
223 /* store counter in field `n' */ 224 /* store counter in field `n' */
224 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); 225 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
226 L->top--;
225 } 227 }
226#endif 228#endif
227 /* move fixed parameters to final position */ 229 /* move fixed parameters to final position */
@@ -332,7 +334,7 @@ static StkId callrethooks (lua_State *L, StkId firstResult) {
332 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 334 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
333 luaD_callhook(L, LUA_HOOKRET, -1); 335 luaD_callhook(L, LUA_HOOKRET, -1);
334 if (f_isLua(L->ci)) { /* Lua function? */ 336 if (f_isLua(L->ci)) { /* Lua function? */
335 while (L->ci->tailcalls--) /* call hook for eventual tail calls */ 337 while (L->ci->tailcalls--) /* call hook for possible tail calls */
336 luaD_callhook(L, LUA_HOOKTAILRET, -1); 338 luaD_callhook(L, LUA_HOOKTAILRET, -1);
337 } 339 }
338 return restorestack(L, fr); 340 return restorestack(L, fr);
@@ -461,7 +463,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
461 status = luaD_rawrunprotected(L, func, u); 463 status = luaD_rawrunprotected(L, func, u);
462 if (status != 0) { /* an error occurred? */ 464 if (status != 0) { /* an error occurred? */
463 StkId oldtop = restorestack(L, old_top); 465 StkId oldtop = restorestack(L, old_top);
464 luaF_close(L, oldtop); /* close eventual pending closures */ 466 luaF_close(L, oldtop); /* close possible pending closures */
465 luaD_seterrorobj(L, status, oldtop); 467 luaD_seterrorobj(L, status, oldtop);
466 L->nCcalls = oldnCcalls; 468 L->nCcalls = oldnCcalls;
467 L->ci = restoreci(L, old_ci); 469 L->ci = restoreci(L, old_ci);
@@ -494,12 +496,13 @@ static void f_parser (lua_State *L, void *ud) {
494 luaC_checkGC(L); 496 luaC_checkGC(L);
495 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, 497 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
496 &p->buff, p->name); 498 &p->buff, p->name);
499 setptvalue2s(L, L->top, tf);
500 incr_top(L);
497 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 501 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
498 cl->l.p = tf; 502 cl->l.p = tf;
499 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ 503 setclvalue(L, L->top - 1, cl);
504 for (i = 0; i < tf->nups; i++) /* initialize upvalues */
500 cl->l.upvals[i] = luaF_newupval(L); 505 cl->l.upvals[i] = luaF_newupval(L);
501 setclvalue(L, L->top, cl);
502 incr_top(L);
503} 506}
504 507
505 508
diff --git a/ldo.h b/ldo.h
index 5aa65480..f7e0ce09 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 2.6 2005/08/22 19:58:29 roberto Exp roberto $ 2** $Id: ldo.h,v 2.7 2005/08/24 16:15:49 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,7 +19,7 @@
19 else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); 19 else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
20 20
21 21
22#define incr_top(L) {luaD_checkstack(L,1); L->top++;} 22#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
23 23
24#define savestack(L,p) ((char *)(p) - (char *)L->stack) 24#define savestack(L,p) ((char *)(p) - (char *)L->stack)
25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
diff --git a/lgc.c b/lgc.c
index 935d8c1b..93316741 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $ 2** $Id: lgc.c,v 2.38 2006/05/24 14:34:06 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -52,7 +52,7 @@
52#define markvalue(g,o) { checkconsistency(o); \ 52#define markvalue(g,o) { checkconsistency(o); \
53 if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } 53 if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
54 54
55#define markobject(g,t) { if (iswhite(obj2gco(t))) \ 55#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \
56 reallymarkobject(g, obj2gco(t)); } 56 reallymarkobject(g, obj2gco(t)); }
57 57
58 58
@@ -76,7 +76,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
76 case LUA_TUSERDATA: { 76 case LUA_TUSERDATA: {
77 Table *mt = gco2u(o)->metatable; 77 Table *mt = gco2u(o)->metatable;
78 gray2black(o); /* udata are never gray */ 78 gray2black(o); /* udata are never gray */
79 if (mt) markobject(g, mt); 79 markobject(g, mt);
80 markobject(g, gco2u(o)->env); 80 markobject(g, gco2u(o)->env);
81 return; 81 return;
82 } 82 }
@@ -160,8 +160,7 @@ static int traversetable (global_State *g, Table *h) {
160 int weakkey = 0; 160 int weakkey = 0;
161 int weakvalue = 0; 161 int weakvalue = 0;
162 const TValue *mode; 162 const TValue *mode;
163 if (h->metatable) 163 markobject(g, h->metatable);
164 markobject(g, h->metatable);
165 mode = gfasttm(g, h->metatable, TM_MODE); 164 mode = gfasttm(g, h->metatable, TM_MODE);
166 if (mode && ttisstring(mode)) { /* is there a weak mode? */ 165 if (mode && ttisstring(mode)) { /* is there a weak mode? */
167 weakkey = (strchr(svalue(mode), 'k') != NULL); 166 weakkey = (strchr(svalue(mode), 'k') != NULL);
@@ -209,10 +208,8 @@ static void traverseproto (global_State *g, Proto *f) {
209 if (f->upvalues[i]) 208 if (f->upvalues[i])
210 stringmark(f->upvalues[i]); 209 stringmark(f->upvalues[i]);
211 } 210 }
212 for (i=0; i<f->sizep; i++) { /* mark nested protos */ 211 for (i=0; i<f->sizep; i++) /* mark nested protos */
213 if (f->p[i]) 212 markobject(g, f->p[i]);
214 markobject(g, f->p[i]);
215 }
216 for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */ 213 for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
217 if (f->locvars[i].varname) 214 if (f->locvars[i].varname)
218 stringmark(f->locvars[i].varname); 215 stringmark(f->locvars[i].varname);
@@ -256,6 +253,8 @@ static void checkstacksizes (lua_State *L, StkId max) {
256static void traversestack (global_State *g, lua_State *l) { 253static void traversestack (global_State *g, lua_State *l) {
257 StkId o, lim; 254 StkId o, lim;
258 CallInfo *ci; 255 CallInfo *ci;
256 if (l->stack == NULL || l->base_ci == NULL)
257 return; /* stack not completely built yet */
259 markvalue(g, gt(l)); 258 markvalue(g, gt(l));
260 lim = l->top; 259 lim = l->top;
261 for (ci = l->base_ci; ci <= l->ci; ci++) { 260 for (ci = l->base_ci; ci <= l->ci; ci++) {
@@ -266,7 +265,8 @@ static void traversestack (global_State *g, lua_State *l) {
266 markvalue(g, o); 265 markvalue(g, o);
267 for (; o <= lim; o++) 266 for (; o <= lim; o++)
268 setnilvalue(o); 267 setnilvalue(o);
269 checkstacksizes(l, lim); 268 if (!g->emergencygc) /* cannot change stack in emergency... */
269 checkstacksizes(l, lim); /* ...(interpreter does not expect that change) */
270} 270}
271 271
272 272
@@ -442,11 +442,9 @@ static void checkSizes (lua_State *L) {
442} 442}
443 443
444 444
445static void GCTM (lua_State *L) { 445static Udata *udata2finalize (global_State *g) {
446 global_State *g = G(L);
447 GCObject *o = g->tmudata->gch.next; /* get first element */ 446 GCObject *o = g->tmudata->gch.next; /* get first element */
448 Udata *udata = rawgco2u(o); 447 Udata *udata = rawgco2u(o);
449 const TValue *tm;
450 /* remove udata from `tmudata' */ 448 /* remove udata from `tmudata' */
451 if (o == g->tmudata) /* last element? */ 449 if (o == g->tmudata) /* last element? */
452 g->tmudata = NULL; 450 g->tmudata = NULL;
@@ -455,7 +453,14 @@ static void GCTM (lua_State *L) {
455 udata->uv.next = g->mainthread->next; /* return it to `root' list */ 453 udata->uv.next = g->mainthread->next; /* return it to `root' list */
456 g->mainthread->next = o; 454 g->mainthread->next = o;
457 makewhite(g, o); 455 makewhite(g, o);
458 tm = fasttm(L, udata->uv.metatable, TM_GC); 456 return udata;
457}
458
459
460static void GCTM (lua_State *L) {
461 global_State *g = G(L);
462 Udata *udata = udata2finalize(g);
463 const TValue *tm = fasttm(L, udata->uv.metatable, TM_GC);
459 if (tm != NULL) { 464 if (tm != NULL) {
460 lu_byte oldah = L->allowhook; 465 lu_byte oldah = L->allowhook;
461 lu_mem oldt = g->GCthreshold; 466 lu_mem oldt = g->GCthreshold;
@@ -475,8 +480,17 @@ static void GCTM (lua_State *L) {
475** Call all GC tag methods 480** Call all GC tag methods
476*/ 481*/
477void luaC_callGCTM (lua_State *L) { 482void luaC_callGCTM (lua_State *L) {
478 while (G(L)->tmudata) 483 global_State *g = G(L);
484 GCObject *last = g->tmudata;
485 GCObject *curr;
486 if (last == NULL) return; /* empty list? */
487 do {
488 curr = g->tmudata->gch.next; /* element to be collected */
479 GCTM(L); 489 GCTM(L);
490 } while (curr != last); /* go only until original last */
491 /* do not finalize new udata created during previous finalizations */
492 while (g->tmudata)
493 udata2finalize(g); /* simply remove them from list */
480} 494}
481 495
482 496
@@ -493,7 +507,7 @@ void luaC_freeall (lua_State *L) {
493static void markmt (global_State *g) { 507static void markmt (global_State *g) {
494 int i; 508 int i;
495 for (i=0; i<NUM_TAGS; i++) 509 for (i=0; i<NUM_TAGS; i++)
496 if (g->mt[i]) markobject(g, g->mt[i]); 510 markobject(g, g->mt[i]);
497} 511}
498 512
499 513
@@ -553,6 +567,10 @@ static void atomic (lua_State *L) {
553} 567}
554 568
555 569
570#define correctestimate(g,s) {lu_mem old = g->totalbytes; s; \
571 lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes;}
572
573
556static l_mem singlestep (lua_State *L) { 574static l_mem singlestep (lua_State *L) {
557 global_State *g = G(L); 575 global_State *g = G(L);
558 /*lua_checkmemory(L);*/ 576 /*lua_checkmemory(L);*/
@@ -570,23 +588,15 @@ static l_mem singlestep (lua_State *L) {
570 } 588 }
571 } 589 }
572 case GCSsweepstring: { 590 case GCSsweepstring: {
573 lu_mem old = g->totalbytes; 591 correctestimate(g, sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]));
574 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
575 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ 592 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
576 g->gcstate = GCSsweep; /* end sweep-string phase */ 593 g->gcstate = GCSsweep; /* end sweep-string phase */
577 lua_assert(old >= g->totalbytes);
578 g->estimate -= old - g->totalbytes;
579 return GCSWEEPCOST; 594 return GCSWEEPCOST;
580 } 595 }
581 case GCSsweep: { 596 case GCSsweep: {
582 lu_mem old = g->totalbytes; 597 correctestimate(g, g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX));
583 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); 598 if (*g->sweepgc == NULL) /* nothing more to sweep? */
584 if (*g->sweepgc == NULL) { /* nothing more to sweep? */
585 checkSizes(L);
586 g->gcstate = GCSfinalize; /* end sweep phase */ 599 g->gcstate = GCSfinalize; /* end sweep phase */
587 }
588 lua_assert(old >= g->totalbytes);
589 g->estimate -= old - g->totalbytes;
590 return GCSWEEPMAX*GCSWEEPCOST; 600 return GCSWEEPMAX*GCSWEEPCOST;
591 } 601 }
592 case GCSfinalize: { 602 case GCSfinalize: {
@@ -597,6 +607,7 @@ static l_mem singlestep (lua_State *L) {
597 return GCFINALIZECOST; 607 return GCFINALIZECOST;
598 } 608 }
599 else { 609 else {
610 correctestimate(g, checkSizes(L));
600 g->gcstate = GCSpause; /* end collection */ 611 g->gcstate = GCSpause; /* end collection */
601 g->gcdept = 0; 612 g->gcdept = 0;
602 return 0; 613 return 0;
@@ -610,6 +621,7 @@ static l_mem singlestep (lua_State *L) {
610void luaC_step (lua_State *L) { 621void luaC_step (lua_State *L) {
611 global_State *g = G(L); 622 global_State *g = G(L);
612 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; 623 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
624 lua_assert(!g->emergencygc);
613 if (lim == 0) 625 if (lim == 0)
614 lim = (MAX_LUMEM-1)/2; /* no limit */ 626 lim = (MAX_LUMEM-1)/2; /* no limit */
615 g->gcdept += g->totalbytes - g->GCthreshold; 627 g->gcdept += g->totalbytes - g->GCthreshold;
@@ -633,8 +645,10 @@ void luaC_step (lua_State *L) {
633} 645}
634 646
635 647
636void luaC_fullgc (lua_State *L) { 648void luaC_fullgc (lua_State *L, int isemergency) {
649 int stopstate;
637 global_State *g = G(L); 650 global_State *g = G(L);
651 g->emergencygc = isemergency;
638 if (g->gcstate <= GCSpropagate) { 652 if (g->gcstate <= GCSpropagate) {
639 /* reset sweep marks to sweep all elements (returning them to white) */ 653 /* reset sweep marks to sweep all elements (returning them to white) */
640 g->sweepstrgc = 0; 654 g->sweepstrgc = 0;
@@ -652,10 +666,12 @@ void luaC_fullgc (lua_State *L) {
652 singlestep(L); 666 singlestep(L);
653 } 667 }
654 markroot(L); 668 markroot(L);
655 while (g->gcstate != GCSpause) { 669 /* do not run finalizers during emergency GC */
670 stopstate = isemergency ? GCSfinalize : GCSpause;
671 while (g->gcstate != stopstate)
656 singlestep(L); 672 singlestep(L);
657 }
658 setthreshold(g); 673 setthreshold(g);
674 g->emergencygc = 0;
659} 675}
660 676
661 677
diff --git a/lgc.h b/lgc.h
index 6079c03d..bc220345 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.14 2005/06/07 18:53:45 roberto Exp roberto $ 2** $Id: lgc.h,v 2.15 2005/08/24 16:15:49 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -100,7 +100,7 @@ LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
100LUAI_FUNC void luaC_callGCTM (lua_State *L); 100LUAI_FUNC void luaC_callGCTM (lua_State *L);
101LUAI_FUNC void luaC_freeall (lua_State *L); 101LUAI_FUNC void luaC_freeall (lua_State *L);
102LUAI_FUNC void luaC_step (lua_State *L); 102LUAI_FUNC void luaC_step (lua_State *L);
103LUAI_FUNC void luaC_fullgc (lua_State *L); 103LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
104LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); 104LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
105LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); 105LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
106LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); 106LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
diff --git a/llex.c b/llex.c
index 6a8c158e..056bbbdb 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 2.19 2006/02/06 18:28:16 roberto Exp roberto $ 2** $Id: llex.c,v 2.20 2006/03/09 18:14:31 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -116,10 +116,13 @@ void luaX_syntaxerror (LexState *ls, const char *msg) {
116 116
117TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 117TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
118 lua_State *L = ls->L; 118 lua_State *L = ls->L;
119 TValue *o; /* entry for `str' */
119 TString *ts = luaS_newlstr(L, str, l); 120 TString *ts = luaS_newlstr(L, str, l);
120 TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ 121 setsvalue2s(L, L->top++, ts); /* anchor string */
122 o = luaH_setstr(L, ls->fs->h, ts);
121 if (ttisnil(o)) 123 if (ttisnil(o))
122 setbvalue(o, 1); /* make sure `str' will not be collected */ 124 setbvalue(o, 1); /* make sure `str' will not be collected */
125 L->top--;
123 return ts; 126 return ts;
124} 127}
125 128
diff --git a/lmem.c b/lmem.c
index 1a3e25c4..fb383d3e 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.69 2005/02/23 17:30:22 roberto Exp roberto $ 2** $Id: lmem.c,v 1.70 2005/12/26 13:35:47 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -14,6 +14,7 @@
14 14
15#include "ldebug.h" 15#include "ldebug.h"
16#include "ldo.h" 16#include "ldo.h"
17#include "lgc.h"
17#include "lmem.h" 18#include "lmem.h"
18#include "lobject.h" 19#include "lobject.h"
19#include "lstate.h" 20#include "lstate.h"
@@ -74,13 +75,25 @@ void *luaM_toobig (lua_State *L) {
74** generic allocation routine. 75** generic allocation routine.
75*/ 76*/
76void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 77void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
78 void *newblock;
77 global_State *g = G(L); 79 global_State *g = G(L);
78 lua_assert((osize == 0) == (block == NULL)); 80 lua_assert((osize == 0) == (block == NULL));
79 block = (*g->frealloc)(g->ud, block, osize, nsize); 81#if defined(HARDMEMTESTS)
80 if (block == NULL && nsize > 0) 82 if (nsize > osize && g->GCthreshold != MAX_LUMEM)
81 luaD_throw(L, LUA_ERRMEM); 83 luaC_fullgc(L, 1); /* force a GC whenever possible */
82 lua_assert((nsize == 0) == (block == NULL)); 84#endif
85 newblock = (*g->frealloc)(g->ud, block, osize, nsize);
86 if (newblock == NULL && nsize > 0) {
87 lua_assert(nsize > osize); /* cannot fail when shrinking a block */
88 if (g->GCthreshold != MAX_LUMEM) {
89 luaC_fullgc(L, 1); /* try to free some memory... */
90 newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
91 }
92 if (newblock == NULL)
93 luaD_throw(L, LUA_ERRMEM);
94 }
95 lua_assert((nsize == 0) == (newblock == NULL));
83 g->totalbytes = (g->totalbytes - osize) + nsize; 96 g->totalbytes = (g->totalbytes - osize) + nsize;
84 return block; 97 return newblock;
85} 98}
86 99
diff --git a/lobject.c b/lobject.c
index a7ee87a6..2d8475b3 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.21 2006/01/10 12:50:00 roberto Exp roberto $ 2** $Id: lobject.c,v 2.22 2006/02/10 17:43:52 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -34,20 +34,20 @@ const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
34*/ 34*/
35int luaO_int2fb (unsigned int x) { 35int luaO_int2fb (unsigned int x) {
36 int e = 0; /* expoent */ 36 int e = 0; /* expoent */
37 while (x >= 16) { 37 if (x < 8) return x;
38 while (x >= 0x10) {
38 x = (x+1) >> 1; 39 x = (x+1) >> 1;
39 e++; 40 e++;
40 } 41 }
41 if (x < 8) return x; 42 return ((e+1) << 3) | (cast_int(x) - 8);
42 else return ((e+1) << 3) | (cast_int(x) - 8);
43} 43}
44 44
45 45
46/* converts back */ 46/* converts back */
47int luaO_fb2int (int x) { 47int luaO_fb2int (int x) {
48 int e = (x >> 3) & 31; 48 int e = (x >> 3) & 0x1f;
49 if (e == 0) return x; 49 if (e == 0) return x;
50 else return ((x & 7)+8) << (e - 1); 50 else return ((x & 7) + 8) << (e - 1);
51} 51}
52 52
53 53
diff --git a/lparser.c b/lparser.c
index d10fcb59..07511fdf 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.42 2006/06/05 15:57:59 roberto Exp roberto $ 2** $Id: lparser.c,v 2.43 2006/06/22 16:12:59 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -308,7 +308,7 @@ static void leaveblock (FuncState *fs) {
308 308
309 309
310static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { 310static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
311 FuncState *fs = ls->fs; 311 FuncState *fs = ls->fs->prev;
312 Proto *f = fs->f; 312 Proto *f = fs->f;
313 int oldsize = f->sizep; 313 int oldsize = f->sizep;
314 int i; 314 int i;
@@ -327,8 +327,7 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
327 327
328static void open_func (LexState *ls, FuncState *fs) { 328static void open_func (LexState *ls, FuncState *fs) {
329 lua_State *L = ls->L; 329 lua_State *L = ls->L;
330 Proto *f = luaF_newproto(L); 330 Proto *f;
331 fs->f = f;
332 fs->prev = ls->fs; /* linked list of funcstates */ 331 fs->prev = ls->fs; /* linked list of funcstates */
333 fs->ls = ls; 332 fs->ls = ls;
334 fs->L = L; 333 fs->L = L;
@@ -342,12 +341,15 @@ static void open_func (LexState *ls, FuncState *fs) {
342 fs->nlocvars = 0; 341 fs->nlocvars = 0;
343 fs->nactvar = 0; 342 fs->nactvar = 0;
344 fs->bl = NULL; 343 fs->bl = NULL;
345 f->source = ls->source; 344 fs->h = luaH_new(L);
346 f->maxstacksize = 2; /* registers 0/1 are always valid */ 345 /* anchor table of constants (to avoid being collected) */
347 fs->h = luaH_new(L, 0, 0);
348 /* anchor table of constants and prototype (to avoid being collected) */
349 sethvalue2s(L, L->top, fs->h); 346 sethvalue2s(L, L->top, fs->h);
350 incr_top(L); 347 incr_top(L);
348 f = luaF_newproto(L);
349 fs->f = f;
350 f->source = ls->source;
351 f->maxstacksize = 2; /* registers 0/1 are always valid */
352 /* anchor prototype (to avoid being collected) */
351 setptvalue2s(L, L->top, f); 353 setptvalue2s(L, L->top, f);
352 incr_top(L); 354 incr_top(L);
353} 355}
@@ -383,14 +385,18 @@ static void close_func (LexState *ls) {
383Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { 385Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
384 struct LexState lexstate; 386 struct LexState lexstate;
385 struct FuncState funcstate; 387 struct FuncState funcstate;
388 TString *tname = luaS_new(L, name);
389 setsvalue2s(L, L->top, tname); /* protect name */
390 incr_top(L);
386 lexstate.buff = buff; 391 lexstate.buff = buff;
387 luaX_setinput(L, &lexstate, z, luaS_new(L, name)); 392 luaX_setinput(L, &lexstate, z, tname);
388 open_func(&lexstate, &funcstate); 393 open_func(&lexstate, &funcstate);
389 funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ 394 funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
390 luaX_next(&lexstate); /* read first token */ 395 luaX_next(&lexstate); /* read first token */
391 chunk(&lexstate); 396 chunk(&lexstate);
392 check(&lexstate, TK_EOS); 397 check(&lexstate, TK_EOS);
393 close_func(&lexstate); 398 close_func(&lexstate);
399 L->top--;
394 lua_assert(funcstate.prev == NULL); 400 lua_assert(funcstate.prev == NULL);
395 lua_assert(funcstate.f->nups == 0); 401 lua_assert(funcstate.f->nups == 0);
396 lua_assert(lexstate.fs == NULL); 402 lua_assert(lexstate.fs == NULL);
@@ -588,8 +594,8 @@ static void body (LexState *ls, expdesc *e, int needself, int line) {
588 chunk(ls); 594 chunk(ls);
589 new_fs.f->lastlinedefined = ls->linenumber; 595 new_fs.f->lastlinedefined = ls->linenumber;
590 check_match(ls, TK_END, TK_FUNCTION, line); 596 check_match(ls, TK_END, TK_FUNCTION, line);
591 close_func(ls);
592 pushclosure(ls, &new_fs, e); 597 pushclosure(ls, &new_fs, e);
598 close_func(ls);
593} 599}
594 600
595 601
diff --git a/lstate.c b/lstate.c
index 8da02ed5..c9aebcba 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.35 2005/10/06 20:46:25 roberto Exp roberto $ 2** $Id: lstate.c,v 2.36 2006/05/24 14:15:50 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -12,6 +12,7 @@
12 12
13#include "lua.h" 13#include "lua.h"
14 14
15#include "lapi.h"
15#include "ldebug.h" 16#include "ldebug.h"
16#include "ldo.h" 17#include "ldo.h"
17#include "lfunc.h" 18#include "lfunc.h"
@@ -71,8 +72,8 @@ static void f_luaopen (lua_State *L, void *ud) {
71 global_State *g = G(L); 72 global_State *g = G(L);
72 UNUSED(ud); 73 UNUSED(ud);
73 stack_init(L, L); /* init stack */ 74 stack_init(L, L); /* init stack */
74 sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 75 sethvalue(L, gt(L), luaH_new(L)); /* table of globals */
75 sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ 76 sethvalue(L, registry(L), luaH_new(L)); /* registry */
76 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 77 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
77 luaT_init(L); 78 luaT_init(L);
78 luaX_init(L); 79 luaX_init(L);
@@ -116,9 +117,14 @@ static void close_state (lua_State *L) {
116} 117}
117 118
118 119
119lua_State *luaE_newthread (lua_State *L) { 120LUA_API lua_State *lua_newthread (lua_State *L) {
120 lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 121 lua_State *L1;
122 lua_lock(L);
123 luaC_checkGC(L);
124 L1 = tostate(luaM_malloc(L, state_size(lua_State)));
121 luaC_link(L, obj2gco(L1), LUA_TTHREAD); 125 luaC_link(L, obj2gco(L1), LUA_TTHREAD);
126 setthvalue(L, L->top, L1);
127 api_incr_top(L);
122 preinit_state(L1, G(L)); 128 preinit_state(L1, G(L));
123 stack_init(L1, L); /* init stack */ 129 stack_init(L1, L); /* init stack */
124 setobj2n(L, gt(L1), gt(L)); /* share table of globals */ 130 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
@@ -127,6 +133,8 @@ lua_State *luaE_newthread (lua_State *L) {
127 L1->hook = L->hook; 133 L1->hook = L->hook;
128 resethookcount(L1); 134 resethookcount(L1);
129 lua_assert(iswhite(obj2gco(L1))); 135 lua_assert(iswhite(obj2gco(L1)));
136 lua_unlock(L);
137 luai_userstatethread(L, L1);
130 return L1; 138 return L1;
131} 139}
132 140
@@ -152,6 +160,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
152 L->tt = LUA_TTHREAD; 160 L->tt = LUA_TTHREAD;
153 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 161 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
154 L->marked = luaC_white(g); 162 L->marked = luaC_white(g);
163 g->emergencygc = 0;
155 set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 164 set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
156 preinit_state(L, g); 165 preinit_state(L, g);
157 g->frealloc = f; 166 g->frealloc = f;
@@ -159,7 +168,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
159 g->mainthread = L; 168 g->mainthread = L;
160 g->uvhead.u.l.prev = &g->uvhead; 169 g->uvhead.u.l.prev = &g->uvhead;
161 g->uvhead.u.l.next = &g->uvhead; 170 g->uvhead.u.l.next = &g->uvhead;
162 g->GCthreshold = 0; /* mark it as unfinished state */ 171 g->GCthreshold = MAX_LUMEM; /* no GC while building state */
163 g->strt.size = 0; 172 g->strt.size = 0;
164 g->strt.nuse = 0; 173 g->strt.nuse = 0;
165 g->strt.hash = NULL; 174 g->strt.hash = NULL;
diff --git a/lstate.h b/lstate.h
index 1ed893b4..89fc82d1 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.23 2005/07/09 13:22:34 roberto Exp roberto $ 2** $Id: lstate.h,v 2.24 2006/02/06 18:27:59 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -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 emergencygc; /* true when collect was trigged by alloc error */
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' */
@@ -161,7 +162,6 @@ union GCObject {
161#define obj2gco(v) (cast(GCObject *, (v))) 162#define obj2gco(v) (cast(GCObject *, (v)))
162 163
163 164
164LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
165LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 165LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
166 166
167#endif 167#endif
diff --git a/lstring.c b/lstring.c
index 08dbe87f..dc1a780d 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.7 2005/02/18 12:40:02 roberto Exp roberto $ 2** $Id: lstring.c,v 2.8 2005/12/22 16:19:56 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -50,9 +50,11 @@ void luaS_resize (lua_State *L, int newsize) {
50static TString *newlstr (lua_State *L, const char *str, size_t l, 50static TString *newlstr (lua_State *L, const char *str, size_t l,
51 unsigned int h) { 51 unsigned int h) {
52 TString *ts; 52 TString *ts;
53 stringtable *tb; 53 stringtable *tb = &G(L)->strt;
54 if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 54 if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
55 luaM_toobig(L); 55 luaM_toobig(L);
56 if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
57 luaS_resize(L, tb->size*2); /* too crowded */
56 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); 58 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
57 ts->tsv.len = l; 59 ts->tsv.len = l;
58 ts->tsv.hash = h; 60 ts->tsv.hash = h;
@@ -61,13 +63,10 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
61 ts->tsv.reserved = 0; 63 ts->tsv.reserved = 0;
62 memcpy(ts+1, str, l*sizeof(char)); 64 memcpy(ts+1, str, l*sizeof(char));
63 ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 65 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
64 tb = &G(L)->strt;
65 h = lmod(h, tb->size); 66 h = lmod(h, tb->size);
66 ts->tsv.next = tb->hash[h]; /* chain new entry */ 67 ts->tsv.next = tb->hash[h]; /* chain new entry */
67 tb->hash[h] = obj2gco(ts); 68 tb->hash[h] = obj2gco(ts);
68 tb->nuse++; 69 tb->nuse++;
69 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
70 luaS_resize(L, tb->size*2); /* too crowded */
71 return ts; 70 return ts;
72} 71}
73 72
diff --git a/ltable.c b/ltable.c
index b68d1486..b3ad833c 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.31 2006/01/10 13:13:06 roberto Exp roberto $ 2** $Id: ltable.c,v 2.32 2006/01/18 11:49:02 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -294,7 +294,7 @@ static void setnodevector (lua_State *L, Table *t, int size) {
294} 294}
295 295
296 296
297static void resize (lua_State *L, Table *t, int nasize, int nhsize) { 297void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
298 int i; 298 int i;
299 int oldasize = t->sizearray; 299 int oldasize = t->sizearray;
300 int oldhsize = t->lsizenode; 300 int oldhsize = t->lsizenode;
@@ -326,7 +326,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
326 326
327void luaH_resizearray (lua_State *L, Table *t, int nasize) { 327void luaH_resizearray (lua_State *L, Table *t, int nasize) {
328 int nsize = (t->node == dummynode) ? 0 : sizenode(t); 328 int nsize = (t->node == dummynode) ? 0 : sizenode(t);
329 resize(L, t, nasize, nsize); 329 luaH_resize(L, t, nasize, nsize);
330} 330}
331 331
332 332
@@ -345,7 +345,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
345 /* compute new size for array part */ 345 /* compute new size for array part */
346 na = computesizes(nums, &nasize); 346 na = computesizes(nums, &nasize);
347 /* resize the table to new computed sizes */ 347 /* resize the table to new computed sizes */
348 resize(L, t, nasize, totaluse - na); 348 luaH_resize(L, t, nasize, totaluse - na);
349} 349}
350 350
351 351
@@ -355,18 +355,14 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
355*/ 355*/
356 356
357 357
358Table *luaH_new (lua_State *L, int narray, int nhash) { 358Table *luaH_new (lua_State *L) {
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 t->metatable = NULL; 361 t->metatable = NULL;
362 t->flags = cast_byte(~0); 362 t->flags = cast_byte(~0);
363 /* temporary values (kept only if some malloc fails) */
364 t->array = NULL; 363 t->array = NULL;
365 t->sizearray = 0; 364 t->sizearray = 0;
366 t->lsizenode = 0; 365 setnodevector(L, t, 0);
367 t->node = cast(Node *, dummynode);
368 setarrayvector(L, t, narray);
369 setnodevector(L, t, nhash);
370 return t; 366 return t;
371} 367}
372 368
diff --git a/ltable.h b/ltable.h
index e87597fd..60569fd0 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 2.9 2006/01/10 12:51:53 roberto Exp roberto $ 2** $Id: ltable.h,v 2.10 2006/01/10 13:13:06 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,7 +24,8 @@ LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
24LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); 24LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
25LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 25LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
26LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 26LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
27LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); 27LUAI_FUNC Table *luaH_new (lua_State *L);
28LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
28LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 29LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
29LUAI_FUNC void luaH_free (lua_State *L, Table *t); 30LUAI_FUNC void luaH_free (lua_State *L, Table *t);
30LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 31LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
diff --git a/ltests.c b/ltests.c
index 7ae9ba6f..151e1f4c 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp roberto $ 2** $Id: ltests.c,v 2.37 2006/06/05 19:35:57 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -55,6 +55,12 @@ static void setnameval (lua_State *L, const char *name, int val) {
55} 55}
56 56
57 57
58static void pushobject (lua_State *L, const TValue *o) {
59 setobj2s(L, L->top, o);
60 api_incr_top(L);
61}
62
63
58/* 64/*
59** {====================================================================== 65** {======================================================================
60** Controlled version for realloc. 66** Controlled version for realloc.
@@ -108,7 +114,8 @@ static void freeblock (Memcontrol *mc, void *block, size_t size) {
108 114
109void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { 115void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) {
110 Memcontrol *mc = cast(Memcontrol *, ud); 116 Memcontrol *mc = cast(Memcontrol *, ud);
111 lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); 117 lua_assert((oldsize == 0) ? block == NULL :
118 block && checkblocksize(block, oldsize));
112 if (mc->memlimit == 0) { /* first time? */ 119 if (mc->memlimit == 0) { /* first time? */
113 char *limit = getenv("MEMLIMIT"); /* initialize memory limit */ 120 char *limit = getenv("MEMLIMIT"); /* initialize memory limit */
114 mc->memlimit = limit ? strtoul(limit, NULL, 10) : ULONG_MAX; 121 mc->memlimit = limit ? strtoul(limit, NULL, 10) : ULONG_MAX;
@@ -447,7 +454,7 @@ static int listk (lua_State *L) {
447 p = clvalue(obj_at(L, 1))->l.p; 454 p = clvalue(obj_at(L, 1))->l.p;
448 lua_createtable(L, p->sizek, 0); 455 lua_createtable(L, p->sizek, 0);
449 for (i=0; i<p->sizek; i++) { 456 for (i=0; i<p->sizek; i++) {
450 luaA_pushobject(L, p->k+i); 457 pushobject(L, p->k+i);
451 lua_rawseti(L, -2, i+1); 458 lua_rawseti(L, -2, i+1);
452 } 459 }
453 return 1; 460 return 1;
@@ -573,18 +580,18 @@ static int table_query (lua_State *L) {
573 } 580 }
574 else if (i < t->sizearray) { 581 else if (i < t->sizearray) {
575 lua_pushinteger(L, i); 582 lua_pushinteger(L, i);
576 luaA_pushobject(L, &t->array[i]); 583 pushobject(L, &t->array[i]);
577 lua_pushnil(L); 584 lua_pushnil(L);
578 } 585 }
579 else if ((i -= t->sizearray) < sizenode(t)) { 586 else if ((i -= t->sizearray) < sizenode(t)) {
580 if (!ttisnil(gval(gnode(t, i))) || 587 if (!ttisnil(gval(gnode(t, i))) ||
581 ttisnil(gkey(gnode(t, i))) || 588 ttisnil(gkey(gnode(t, i))) ||
582 ttisnumber(gkey(gnode(t, i)))) { 589 ttisnumber(gkey(gnode(t, i)))) {
583 luaA_pushobject(L, key2tval(gnode(t, i))); 590 pushobject(L, key2tval(gnode(t, i)));
584 } 591 }
585 else 592 else
586 lua_pushliteral(L, "<undef>"); 593 lua_pushliteral(L, "<undef>");
587 luaA_pushobject(L, gval(gnode(t, i))); 594 pushobject(L, gval(gnode(t, i)));
588 if (gnext(&t->node[i])) 595 if (gnext(&t->node[i]))
589 lua_pushinteger(L, gnext(&t->node[i]) - t->node); 596 lua_pushinteger(L, gnext(&t->node[i]) - t->node);
590 else 597 else
diff --git a/lvm.c b/lvm.c
index 6c92567f..50ffdfdc 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.62 2006/01/23 19:51:43 roberto Exp roberto $ 2** $Id: lvm.c,v 2.63 2006/06/05 15:58:59 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -85,8 +85,8 @@ static void callTMres (lua_State *L, StkId res, const TValue *f,
85 setobj2s(L, L->top, f); /* push function */ 85 setobj2s(L, L->top, f); /* push function */
86 setobj2s(L, L->top+1, p1); /* 1st argument */ 86 setobj2s(L, L->top+1, p1); /* 1st argument */
87 setobj2s(L, L->top+2, p2); /* 2nd argument */ 87 setobj2s(L, L->top+2, p2); /* 2nd argument */
88 luaD_checkstack(L, 3);
89 L->top += 3; 88 L->top += 3;
89 luaD_checkstack(L, 0);
90 luaD_call(L, L->top - 3, 1); 90 luaD_call(L, L->top - 3, 1);
91 res = restorestack(L, result); 91 res = restorestack(L, result);
92 L->top--; 92 L->top--;
@@ -101,8 +101,8 @@ static void callTM (lua_State *L, const TValue *f, const TValue *p1,
101 setobj2s(L, L->top+1, p1); /* 1st argument */ 101 setobj2s(L, L->top+1, p1); /* 1st argument */
102 setobj2s(L, L->top+2, p2); /* 2nd argument */ 102 setobj2s(L, L->top+2, p2); /* 2nd argument */
103 setobj2s(L, L->top+3, p3); /* 3th argument */ 103 setobj2s(L, L->top+3, p3); /* 3th argument */
104 luaD_checkstack(L, 4);
105 L->top += 4; 104 L->top += 4;
105 luaD_checkstack(L, 0);
106 luaD_call(L, L->top - 4, 0); 106 luaD_call(L, L->top - 4, 0);
107} 107}
108 108
@@ -455,9 +455,12 @@ void luaV_execute (lua_State *L, int nexeccalls) {
455 continue; 455 continue;
456 } 456 }
457 case OP_NEWTABLE: { 457 case OP_NEWTABLE: {
458 int b = GETARG_B(i); 458 int asize = luaO_fb2int(GETARG_B(i));
459 int c = GETARG_C(i); 459 int nsize = luaO_fb2int(GETARG_C(i));
460 sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); 460 Table *t = luaH_new(L);
461 sethvalue(L, ra, t);
462 if (asize > 0 || nsize > 0)
463 luaH_resize(L, t, asize, nsize);
461 Protect(luaC_checkGC(L)); 464 Protect(luaC_checkGC(L));
462 continue; 465 continue;
463 } 466 }
@@ -695,10 +698,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
695 int c = GETARG_C(i); 698 int c = GETARG_C(i);
696 int last; 699 int last;
697 Table *h; 700 Table *h;
698 if (n == 0) { 701 if (n == 0) n = cast_int(L->top - ra) - 1;
699 n = cast_int(L->top - ra) - 1;
700 L->top = L->ci->top;
701 }
702 if (c == 0) c = cast_int(*pc++); 702 if (c == 0) c = cast_int(*pc++);
703 runtime_check(L, ttistable(ra)); 703 runtime_check(L, ttistable(ra));
704 h = hvalue(ra); 704 h = hvalue(ra);
@@ -710,6 +710,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
710 setobj2t(L, luaH_setnum(L, h, last--), val); 710 setobj2t(L, luaH_setnum(L, h, last--), val);
711 luaC_barriert(L, h, val); 711 luaC_barriert(L, h, val);
712 } 712 }
713 L->top = L->ci->top; /* correct top (in case of previous open call) */
713 continue; 714 continue;
714 } 715 }
715 case OP_CLOSE: { 716 case OP_CLOSE: {
@@ -724,6 +725,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
724 nup = p->nups; 725 nup = p->nups;
725 ncl = luaF_newLclosure(L, nup, cl->env); 726 ncl = luaF_newLclosure(L, nup, cl->env);
726 ncl->l.p = p; 727 ncl->l.p = p;
728 setclvalue(L, ra, ncl);
727 for (j=0; j<nup; j++, pc++) { 729 for (j=0; j<nup; j++, pc++) {
728 if (GET_OPCODE(*pc) == OP_GETUPVAL) 730 if (GET_OPCODE(*pc) == OP_GETUPVAL)
729 ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; 731 ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
@@ -732,7 +734,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
732 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); 734 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
733 } 735 }
734 } 736 }
735 setclvalue(L, ra, ncl);
736 Protect(luaC_checkGC(L)); 737 Protect(luaC_checkGC(L));
737 continue; 738 continue;
738 } 739 }
diff --git a/makefile b/makefile
index d57ecbad..c157b46f 100644
--- a/makefile
+++ b/makefile
@@ -9,7 +9,7 @@ CWARNS= -pedantic -Waggregate-return -Wcast-align \
9 -Wsign-compare -Wstrict-prototypes -Wundef -Wwrite-strings 9 -Wsign-compare -Wstrict-prototypes -Wundef -Wwrite-strings
10# -Wcast-qual 10# -Wcast-qual
11 11
12# -DEXTERNMEMCHECK -DHARDSTACKTESTS 12# -DEXTERNMEMCHECK -DHARDSTACKTESTS -DHARDMEMTESTS
13# -g -DLUA_USER_H='"ltests.h"' 13# -g -DLUA_USER_H='"ltests.h"'
14# -fomit-frame-pointer #-pg -malign-double 14# -fomit-frame-pointer #-pg -malign-double
15TESTS= -g -DLUA_USER_H='"ltests.h"' 15TESTS= -g -DLUA_USER_H='"ltests.h"'