Index: src/lua/ldo.c
===================================================================
--- src/lua/ldo.c	(revision 521)
+++ src/lua/ldo.c	(working copy)
@@ -92,6 +92,8 @@
 
 
 void luaD_throw (lua_State *L, int errcode) {
+  unfixedstack(L); /* make sure the fixedstack & block_gc flags get reset. */
+  unset_block_gc(L);
   if (L->errorJmp) {
     L->errorJmp->status = errcode;
     LUAI_THROW(L, L->errorJmp);
Index: src/lua/lvm.c
===================================================================
--- src/lua/lvm.c	(revision 521)
+++ src/lua/lvm.c	(working copy)
@@ -152,6 +152,10 @@
 
 void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
   int loop;
+  TValue temp;
+  setnilvalue(L->top);
+  L->top++;
+  fixedstack(L);
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     const TValue *tm;
     if (ttistable(t) || ttisrotable(t)) {  /* `t' is a table? */
@@ -160,6 +164,8 @@
       if ((oldval && !ttisnil(oldval)) ||  /* result is no nil? */
           (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */
         if(oldval) {
+          L->top--;
+          unfixedstack(L);
           setobj2t(L, oldval, val);
           luaC_barriert(L, (Table*)h, val);
         }
@@ -170,10 +176,15 @@
     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
       luaG_typeerror(L, t, "index");
     if (ttisfunction(tm) || ttislightfunction(tm)) {
+      L->top--;
+      unfixedstack(L);
       callTM(L, tm, t, key, val);
       return;
     }
-    t = tm;  /* else repeat with `tm' */ 
+    /* else repeat with `tm' */
+    setobj(L, &temp, tm);  /* avoid pointing inside table (may rehash) */
+    t = &temp;
+    setobj2s(L, L->top-1, t);  /* need to protect value from EGC. */
   }
   luaG_runerror(L, "loop in settable");
 }
@@ -300,6 +311,8 @@
 
 
 void luaV_concat (lua_State *L, int total, int last) {
+  lu_mem max_sizet = MAX_SIZET;
+  if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit;
   do {
     StkId top = L->base + last + 1;
     int n = 2;  /* number of elements handled in this pass (at least 2) */
@@ -313,10 +326,11 @@
       size_t tl = tsvalue(top-1)->len;
       char *buffer;
       int i;
+      fixedstack(L);
       /* collect total length */
       for (n = 1; n < total && tostring(L, top-n-1); n++) {
         size_t l = tsvalue(top-n-1)->len;
-        if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
+        if (l >= max_sizet - tl) luaG_runerror(L, "string length overflow");
         tl += l;
       }
       G(L)->buff.n = tl;
@@ -329,6 +343,7 @@
       }
       setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
       luaZ_resetbuffer(&G(L)->buff);
+      unfixedstack(L);
     }
     total -= n-1;  /* got `n' strings to create 1 new */
     last -= n-1;
Index: src/lua/lgc.c
===================================================================
--- src/lua/lgc.c	(revision 521)
+++ src/lua/lgc.c	(working copy)
@@ -269,7 +269,8 @@
     markvalue(g, o);
   for (; o <= lim; o++)
     setnilvalue(o);
-  checkstacksizes(l, lim);
+  if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */
+    checkstacksizes(l, lim);
 }
 
 
@@ -435,13 +436,12 @@
   if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
       g->strt.size > MINSTRTABSIZE*2)
     luaS_resize(L, g->strt.size/2);  /* table is too big */
+  /* it is not safe to re-size the buffer if it is in use. */
+  if (luaZ_bufflen(&g->buff) > 0) return;
   /* check size of buffer */
   if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) {  /* buffer too big? */
     size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
-    /* make sure newsize is larger then the buffer's in use size. */
-    newsize = (luaZ_bufflen(&g->buff) > newsize) ? luaZ_bufflen(&g->buff) : newsize;
-    if(newsize < luaZ_sizebuffer(&g->buff))
-      luaZ_resizebuffer(L, &g->buff, newsize);
+    luaZ_resizebuffer(L, &g->buff, newsize);
   }
 }
 
Index: src/lua/lgc.h
===================================================================
--- src/lua/lgc.h	(revision 521)
+++ src/lua/lgc.h	(working copy)
@@ -41,6 +41,7 @@
 ** Possible Garbage Collector flags.
 ** Layout for bit use in 'gsflags' field in global_State structure.
 ** bit 0 - Protect GC from recursive calls.
+** bit 1 - Don't try to shrink string table if EGC was called during a string table resize.
 */
 #define GCFlagsNone          0
 #define GCBlockGCBit         0
@@ -59,6 +60,7 @@
 ** bit 0 - object is white (type 0)
 ** bit 1 - object is white (type 1)
 ** bit 2 - object is black
+** bit 3 - for thread: Don't resize thread's stack
 ** bit 3 - for userdata: has been finalized
 ** bit 3 - for tables: has weak keys
 ** bit 4 - for tables: has weak values
@@ -70,6 +72,7 @@
 #define WHITE0BIT	0
 #define WHITE1BIT	1
 #define BLACKBIT	2
+#define FIXEDSTACKBIT	3
 #define FINALIZEDBIT	3
 #define KEYWEAKBIT	3
 #define VALUEWEAKBIT	4
@@ -92,6 +95,9 @@
 
 #define luaC_white(g)	cast(lu_byte, (g)->currentwhite & WHITEBITS)
 
+#define isfixedstack(x)	testbit((x)->marked, FIXEDSTACKBIT)
+#define fixedstack(x)	l_setbit((x)->marked, FIXEDSTACKBIT)
+#define unfixedstack(x)	resetbit((x)->marked, FIXEDSTACKBIT)
 
 #define luaC_checkGC(L) { \
   condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
Index: src/lua/lzio.h
===================================================================
--- src/lua/lzio.h	(revision 521)
+++ src/lua/lzio.h	(working copy)
@@ -27,7 +27,7 @@
   size_t buffsize;
 } Mbuffer;
 
-#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
+#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->n = 0, (buff)->buffsize = 0)
 
 #define luaZ_buffer(buff)	((buff)->buffer)
 #define luaZ_sizebuffer(buff)	((buff)->buffsize)
Index: src/lua/lobject.h
===================================================================
--- src/lua/lobject.h	(revision 521)
+++ src/lua/lobject.h	(working copy)
@@ -120,48 +120,54 @@
 #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
 
 #define setnvalue(obj,x) \
-  { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
+  { lua_Number i_x = (x); TValue *i_o=(obj); i_o->value.n=i_x; i_o->tt=LUA_TNUMBER; }
 
 #define setpvalue(obj,x) \
-  { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
+  { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; }
   
 #define setrvalue(obj,x) \
-  { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TROTABLE; }
+  { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TROTABLE; }
   
 #define setfvalue(obj,x) \
-  { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTFUNCTION; }
+  { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; }
 
 #define setbvalue(obj,x) \
-  { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
+  { int i_x = (x); TValue *i_o=(obj); i_o->value.b=i_x; i_o->tt=LUA_TBOOLEAN; }
 
 #define setsvalue(L,obj,x) \
-  { TValue *i_o=(obj); \
-    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TSTRING; \
     checkliveness(G(L),i_o); }
 
 #define setuvalue(L,obj,x) \
-  { TValue *i_o=(obj); \
-    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TUSERDATA; \
     checkliveness(G(L),i_o); }
 
 #define setthvalue(L,obj,x) \
-  { TValue *i_o=(obj); \
-    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TTHREAD; \
     checkliveness(G(L),i_o); }
 
 #define setclvalue(L,obj,x) \
-  { TValue *i_o=(obj); \
-    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TFUNCTION; \
     checkliveness(G(L),i_o); }
 
 #define sethvalue(L,obj,x) \
-  { TValue *i_o=(obj); \
-    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TTABLE; \
     checkliveness(G(L),i_o); }
 
 #define setptvalue(L,obj,x) \
-  { TValue *i_o=(obj); \
-    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \
     checkliveness(G(L),i_o); }
 
 
