diff -urN lua-5.1.4-orig/src/lapi.c lua-5.1.4/src/lapi.c
--- lua-5.1.4-orig/src/lapi.c	2008-07-05 03:41:18 +0900
+++ lua-5.1.4/src/lapi.c	2010-06-14 06:30:02 +0900
@@ -445,7 +445,7 @@
 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
   lua_lock(L);
   luaC_checkGC(L);
-  setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
+  setsvalue2s(L, L->top, luaS_newlstr(L, s, len, 0));
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -996,7 +996,7 @@
     L->top -= (n-1);
   }
   else if (n == 0) {  /* push empty string */
-    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
+    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0, 0));
     api_incr_top(L);
   }
   /* else n == 1; nothing to do */
diff -urN lua-5.1.4-orig/src/llex.c lua-5.1.4/src/llex.c
--- lua-5.1.4-orig/src/llex.c	2007-12-27 22:02:25 +0900
+++ lua-5.1.4/src/llex.c	2010-06-14 06:30:02 +0900
@@ -64,7 +64,7 @@
 void luaX_init (lua_State *L) {
   int i;
   for (i=0; i<NUM_RESERVED; i++) {
-    TString *ts = luaS_new(L, luaX_tokens[i]);
+    TString *ts = luaS_newstatic(L, luaX_tokens[i]);
     luaS_fix(ts);  /* reserved words are never collected */
     lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
     ts->tsv.reserved = cast_byte(i+1);  /* reserved word */
@@ -114,9 +114,9 @@
 }
 
 
-TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
+TString *luaX_newstring_full (LexState *ls, const char *str, size_t l, int is_static) {
   lua_State *L = ls->L;
-  TString *ts = luaS_newlstr(L, str, l);
+  TString *ts = luaS_newlstr(L, str, l, is_static);
   TValue *o = luaH_setstr(L, ls->fs->h, ts);  /* entry for `str' */
   if (ttisnil(o))
     setbvalue(o, 1);  /* make sure `str' will not be collected */
diff -urN lua-5.1.4-orig/src/llex.h lua-5.1.4/src/llex.h
--- lua-5.1.4-orig/src/llex.h	2007-12-27 22:02:25 +0900
+++ lua-5.1.4/src/llex.h	2010-06-14 06:30:02 +0900
@@ -67,10 +67,13 @@
 } LexState;
 
 
+#define luaX_newstring(ls,str,l)	luaX_newstring_full ((ls), (str), (l), 0)
+#define luaX_newstring_literal(ls,str)	luaX_newstring_full ((ls), "" str, (sizeof(str)/sizeof(char))-1, 1)
+
 LUAI_FUNC void luaX_init (lua_State *L);
 LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
                               TString *source);
-LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
+LUAI_FUNC TString *luaX_newstring_full (LexState *ls, const char *str, size_t l, int is_static);
 LUAI_FUNC void luaX_next (LexState *ls);
 LUAI_FUNC void luaX_lookahead (LexState *ls);
 LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
diff -urN lua-5.1.4-orig/src/lobject.c lua-5.1.4/src/lobject.c
--- lua-5.1.4-orig/src/lobject.c	2007-12-27 22:02:25 +0900
+++ lua-5.1.4/src/lobject.c	2010-06-14 06:30:02 +0900
@@ -114,7 +114,7 @@
   for (;;) {
     const char *e = strchr(fmt, '%');
     if (e == NULL) break;
-    setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
+    setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt, 0));
     incr_top(L);
     switch (*(e+1)) {
       case 's': {
diff -urN lua-5.1.4-orig/src/lobject.h lua-5.1.4/src/lobject.h
--- lua-5.1.4-orig/src/lobject.h	2008-08-06 22:29:48 +0900
+++ lua-5.1.4/src/lobject.h	2010-06-14 06:30:36 +0900
@@ -200,6 +200,7 @@
   L_Umaxalign dummy;  /* ensures maximum alignment for strings */
   struct {
     CommonHeader;
+    lu_byte is_static;
     lu_byte reserved;
     unsigned int hash;
     size_t len;
@@ -207,7 +208,7 @@
 } TString;
 
 
-#define getstr(ts)	cast(const char *, (ts) + 1)
+#define getstr(ts)	((ts)->tsv.is_static ? *(cast(const char **, (ts) + 1)) : cast(const char *, (ts) + 1))
 #define svalue(o)       getstr(rawtsvalue(o))
 
 
diff -urN lua-5.1.4-orig/src/lparser.c lua-5.1.4/src/lparser.c
--- lua-5.1.4-orig/src/lparser.c	2007-12-29 00:32:23 +0900
+++ lua-5.1.4/src/lparser.c	2010-06-14 06:30:02 +0900
@@ -154,7 +154,7 @@
 
 
 #define new_localvarliteral(ls,v,n) \
-  new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
+  new_localvar(ls, luaX_newstring_literal(ls, "" v), n)
 
 
 static void new_localvar (LexState *ls, TString *name, int n) {
diff -urN lua-5.1.4-orig/src/lstring.c lua-5.1.4/src/lstring.c
--- lua-5.1.4-orig/src/lstring.c	2007-12-27 22:02:25 +0900
+++ lua-5.1.4/src/lstring.c	2010-06-14 06:32:11 +0900
@@ -48,19 +48,24 @@
 
 
 static TString *newlstr (lua_State *L, const char *str, size_t l,
-                                       unsigned int h) {
+                                       int is_static, unsigned int h) {
   TString *ts;
   stringtable *tb;
-  if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
+  if (!is_static && l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
     luaM_toobig(L);
-  ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
+  ts = cast(TString *, luaM_malloc(L, (is_static ? sizeof(const char *) : (l+1)*sizeof(char))+sizeof(TString)));
   ts->tsv.len = l;
   ts->tsv.hash = h;
   ts->tsv.marked = luaC_white(G(L));
   ts->tsv.tt = LUA_TSTRING;
   ts->tsv.reserved = 0;
-  memcpy(ts+1, str, l*sizeof(char));
-  ((char *)(ts+1))[l] = '\0';  /* ending 0 */
+  ts->tsv.is_static = is_static ? 1 : 0;
+  if (is_static) {
+    *((const char **)(ts+1)) = str;
+  } else {
+    memcpy(ts+1, str, l*sizeof(char));
+    ((char *)(ts+1))[l] = '\0';  /* ending 0 */
+  }
   tb = &G(L)->strt;
   h = lmod(h, tb->size);
   ts->tsv.next = tb->hash[h];  /* chain new entry */
@@ -72,7 +77,7 @@
 }
 
 
-TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
+TString *luaS_newlstr (lua_State *L, const char *str, size_t l, int is_static) {
   GCObject *o;
   unsigned int h = cast(unsigned int, l);  /* seed */
   size_t step = (l>>5)+1;  /* if string is too long, don't hash all its chars */
@@ -89,7 +94,7 @@
       return ts;
     }
   }
-  return newlstr(L, str, l, h);  /* not found */
+  return newlstr(L, str, l, is_static, h);  /* not found */
 }
 
 
diff -urN lua-5.1.4-orig/src/lstring.h lua-5.1.4/src/lstring.h
--- lua-5.1.4-orig/src/lstring.h	2007-12-27 22:02:25 +0900
+++ lua-5.1.4/src/lstring.h	2010-06-14 06:31:39 +0900
@@ -13,19 +13,20 @@
 #include "lstate.h"
 
 
-#define sizestring(s)	(sizeof(union TString)+((s)->len+1)*sizeof(char))
+#define sizestring(s)	(sizeof(union TString)+((s)->is_static ? sizeof(const char *) : ((s)->len+1)*sizeof(char)))
 
 #define sizeudata(u)	(sizeof(union Udata)+(u)->len)
 
-#define luaS_new(L, s)	(luaS_newlstr(L, s, strlen(s)))
+#define luaS_new(L, s)	(luaS_newlstr(L, s, strlen(s), 0))
+#define luaS_newstatic(L, s)	(luaS_newlstr(L, s, strlen(s), 1))
 #define luaS_newliteral(L, s)	(luaS_newlstr(L, "" s, \
-                                 (sizeof(s)/sizeof(char))-1))
+                                 (sizeof(s)/sizeof(char))-1, 1))
 
 #define luaS_fix(s)	l_setbit((s)->tsv.marked, FIXEDBIT)
 
 LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
 LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
-LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l, int is_static);
 
 
 #endif
diff -urN lua-5.1.4-orig/src/ltm.c lua-5.1.4/src/ltm.c
--- lua-5.1.4-orig/src/ltm.c	2007-12-27 22:02:25 +0900
+++ lua-5.1.4/src/ltm.c	2010-06-14 06:30:02 +0900
@@ -37,7 +37,7 @@
   };
   int i;
   for (i=0; i<TM_N; i++) {
-    G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
+    G(L)->tmname[i] = luaS_newstatic(L, luaT_eventname[i]);
     luaS_fix(G(L)->tmname[i]);  /* never collect these names */
   }
 }
diff -urN lua-5.1.4-orig/src/lundump.c lua-5.1.4/src/lundump.c
--- lua-5.1.4-orig/src/lundump.c	2008-04-05 04:51:41 +0900
+++ lua-5.1.4/src/lundump.c	2010-06-14 06:30:02 +0900
@@ -83,7 +83,7 @@
  {
   char* s=luaZ_openspace(S->L,S->b,size);
   LoadBlock(S,s,size);
-  return luaS_newlstr(S->L,s,size-1);		/* remove trailing '\0' */
+  return luaS_newlstr(S->L,s,size-1,0);		/* remove trailing '\0' */
  }
 }
 
diff -urN lua-5.1.4-orig/src/lvm.c lua-5.1.4/src/lvm.c
--- lua-5.1.4-orig/src/lvm.c	2007-12-29 00:32:23 +0900
+++ lua-5.1.4/src/lvm.c	2010-06-14 06:30:02 +0900
@@ -302,7 +302,7 @@
         memcpy(buffer+tl, svalue(top-i), l);
         tl += l;
       }
-      setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
+      setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl, 0));
     }
     total -= n-1;  /* got `n' strings to create 1 new */
     last -= n-1;
