lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Here's an update. iFollowing a suggestion from Mike Pall, I changed the
patch so that now it reverts, rather than tries to merge, the
L->baseCcalls related changes introduced in Lua 5.1.3.

Attached now are _two_ patches against the original patch file:
http://lua-users.org/files/wiki_insecure/users/VeLoSo/lua5.1-rvm.patch.

The first just changes line numberings in the original patch, so can be
relied on to be harmless. The second contains all the other changes
needed. I think these are all straightforward, except for the
L->baseCcalls stuff. That still needs review.

Also, there was a 

 if (L->nCcalls >= LUAI_MAXCCALLS)
    return resume_error(L, "C stack overflow");

introduced to ldo.c: resume_error in the changes between 5.1 and 5.1.4.
Following the lead of the Coco patch, I removed this too. But I'm really
not sure whether that's right.


On Tue, Sep 08, 2009 at 09:03:06AM -0400, Jim Pryor wrote:

> > I'm also trying to build and try out the RVM patch. It doesn't patch
> > cleanly against the Lua 5.1.4 sources, so I'm going and cleaning it up
> > by hand. Mostly this is straightforward. There are a few spots where I'm
> > stuck though: the Lua 5.1.4 sources have changed
> > from what the RVM patch is trying to replace. I'm not familiar with
> > these sources yet, so don't know what's the right merge.
> > 
> > The wiki says that Greg Falcon aka VeLoSo has taken over maintenance of
> > the RVM patch. Is there any version floating around against the current
> > Lua sources? Is noone using this patch anymore? From what I've seen on
> > the mailing list it looks that, though there's no development happening
> > on it, it's still regarded as a solid and viable option?
> 
> OK, I've done the grunt work of updating the Resumable VM patch against the
> Lua5.1.4 sources. What I've ended up with compiles and runs the test/
> directory in the Lua5.1.4 sources without crashing. But it needs some
> code review! I'm new to Lua and in some places I had to make an educated
> guess about how to merge the rvm patch against the Lua5.1->Lua5.1.4
> changes. Someone who really understands the source should look this
> over.
> 
> I've made it easy for you. Attached are three patches _against the
> Lua5.1 rvm patch on the wiki_. That's right, they're patches against the
> patch file at
> http://lua-users.org/files/wiki_insecure/users/VeLoSo/lua5.1-rvm.patch.
> 
> The first patch just changes some line numbers. I'm sure this is
> harmless.
> 
> The second patch...

-- 
Jim Pryor
jim@jimpryor.net
--- lua5.1-rvm.patch	2009-09-12 14:46:47.526451362 -0400
+++ lua5.1-rvm-renumbered	2009-09-12 14:12:00.296260931 -0400
@@ -1,7 +1,7 @@
-diff -ruN oldsrc/lapi.c newsrc/lapi.c
---- oldsrc/lapi.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lapi.c	2006-04-15 23:44:03.000000000 -0500
-@@ -283,7 +283,9 @@
+diff -Naurp lua-5.1.4/src/lapi.c lua-5.1.4-rvm/src/lapi.c
+--- lua-5.1.4/src/lapi.c	2008-07-04 14:41:18.000000000 -0400
++++ lua-5.1.4-rvm/src/lapi.c	2009-09-12 13:43:55.216447167 -0400
+@@ -290,7 +290,9 @@ LUA_API int lua_equal (lua_State *L, int
    lua_lock(L);  /* may call tag method */
    o1 = index2adr(L, index1);
    o2 = index2adr(L, index2);
@@ -12,7 +12,7 @@
    lua_unlock(L);
    return i;
  }
-@@ -295,8 +297,10 @@
+@@ -302,8 +304,10 @@ LUA_API int lua_lessthan (lua_State *L, 
    lua_lock(L);  /* may call tag method */
    o1 = index2adr(L, index1);
    o2 = index2adr(L, index2);
@@ -25,7 +25,7 @@
    lua_unlock(L);
    return i;
  }
-@@ -529,7 +533,9 @@
+@@ -536,7 +540,9 @@ LUA_API void lua_gettable (lua_State *L,
    lua_lock(L);
    t = index2adr(L, idx);
    api_checkvalidindex(L, t);
@@ -36,7 +36,7 @@
    lua_unlock(L);
  }
  
-@@ -541,7 +547,9 @@
+@@ -548,7 +554,9 @@ LUA_API void lua_getfield (lua_State *L,
    t = index2adr(L, idx);
    api_checkvalidindex(L, t);
    setsvalue(L, &key, luaS_new(L, k));
@@ -47,7 +47,7 @@
    api_incr_top(L);
    lua_unlock(L);
  }
-@@ -641,7 +649,9 @@
+@@ -648,7 +656,9 @@ LUA_API void lua_settable (lua_State *L,
    api_checknelems(L, 2);
    t = index2adr(L, idx);
    api_checkvalidindex(L, t);
@@ -58,7 +58,7 @@
    L->top -= 2;  /* pop index and value */
    lua_unlock(L);
  }
-@@ -655,7 +665,9 @@
+@@ -662,7 +672,9 @@ LUA_API void lua_setfield (lua_State *L,
    t = index2adr(L, idx);
    api_checkvalidindex(L, t);
    setsvalue(L, &key, luaS_new(L, k));
@@ -69,7 +69,7 @@
    L->top--;  /* pop value */
    lua_unlock(L);
  }
-@@ -758,22 +770,29 @@
+@@ -765,22 +777,29 @@ LUA_API int lua_setfenv (lua_State *L, i
  */
  
  
@@ -109,7 +109,7 @@
    lua_unlock(L);
  }
  
-@@ -788,31 +807,36 @@
+@@ -795,31 +814,36 @@ struct CallS {  /* data to `f_call' */
  };
  
  
@@ -163,7 +163,7 @@
    lua_unlock(L);
    return status;
  }
-@@ -827,7 +851,7 @@
+@@ -834,7 +858,7 @@ struct CCallS {  /* data to `f_Ccall' */
  };
  
  
@@ -172,7 +172,7 @@
    struct CCallS *c = cast(struct CCallS *, ud);
    Closure *cl;
    cl = luaF_newCclosure(L, 0, getcurrenv(L));
-@@ -836,7 +860,8 @@
+@@ -843,7 +867,8 @@ static void f_Ccall (lua_State *L, void 
    api_incr_top(L);
    setpvalue(L->top, c->ud);  /* push only argument */
    api_incr_top(L);
@@ -182,7 +182,7 @@
  }
  
  
-@@ -846,7 +871,7 @@
+@@ -853,7 +878,7 @@ LUA_API int lua_cpcall (lua_State *L, lu
    lua_lock(L);
    c.func = func;
    c.ud = ud;
@@ -191,7 +191,7 @@
    lua_unlock(L);
    return status;
  }
-@@ -954,7 +979,7 @@
+@@ -964,7 +989,7 @@ LUA_API int lua_gc (lua_State *L, int wh
  LUA_API int lua_error (lua_State *L) {
    lua_lock(L);
    api_checknelems(L, 1);
@@ -200,7 +200,7 @@
    lua_unlock(L);
    return 0;  /* to avoid warnings */
  }
-@@ -982,7 +1007,9 @@
+@@ -992,7 +1017,9 @@ LUA_API void lua_concat (lua_State *L, i
    api_checknelems(L, n);
    if (n >= 2) {
      luaC_checkGC(L);
@@ -211,9 +211,9 @@
      L->top -= (n-1);
    }
    else if (n == 0) {  /* push empty string */
-diff -ruN oldsrc/lbaselib.c newsrc/lbaselib.c
---- oldsrc/lbaselib.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lbaselib.c	2006-04-15 23:44:03.000000000 -0500
+diff -Naurp lua-5.1.4/src/lbaselib.c lua-5.1.4-rvm/src/lbaselib.c
+--- lua-5.1.4/src/lbaselib.c	2008-02-14 11:46:22.000000000 -0500
++++ lua-5.1.4-rvm/src/lbaselib.c	2009-09-12 13:43:55.223113658 -0400
 @@ -30,13 +30,18 @@
  */
  static int luaB_print (lua_State *L) {
@@ -235,7 +235,7 @@
      s = lua_tostring(L, -1);  /* get result */
      if (s == NULL)
        return luaL_error(L, LUA_QL("tostring") " must return a string to "
-@@ -323,11 +328,12 @@
+@@ -323,11 +328,12 @@ static int luaB_load (lua_State *L) {
  
  
  static int luaB_dofile (lua_State *L) {
@@ -253,7 +253,7 @@
  }
  
  
-@@ -369,32 +375,53 @@
+@@ -371,32 +377,53 @@ static int luaB_select (lua_State *L) {
  }
  
  
@@ -324,7 +324,7 @@
    switch (lua_type(L, 1)) {
      case LUA_TNUMBER:
        lua_pushstring(L, lua_tostring(L, 1));
-@@ -466,6 +493,7 @@
+@@ -468,6 +495,7 @@ static const luaL_Reg base_funcs[] = {
    {"tostring", luaB_tostring},
    {"type", luaB_type},
    {"unpack", luaB_unpack},
@@ -332,7 +332,7 @@
    {"xpcall", luaB_xpcall},
    {NULL, NULL}
  };
-@@ -482,6 +510,7 @@
+@@ -520,6 +548,7 @@ static int auxresume (lua_State *L, lua_
    if (!lua_checkstack(co, narg))
      luaL_error(L, "too many arguments to resume");
    if (lua_status(co) == 0 && lua_gettop(co) == 0) {
@@ -340,7 +340,7 @@
      lua_pushliteral(L, "cannot resume dead coroutine");
      return -1;  /* error flag */
    }
-@@ -489,13 +518,16 @@
+@@ -528,13 +557,16 @@ static int auxresume (lua_State *L, lua_
    status = lua_resume(co, narg);
    if (status == 0 || status == LUA_YIELD) {
      int nres = lua_gettop(co);
@@ -358,7 +358,7 @@
      return -1;  /* error flag */
    }
  }
-@@ -506,16 +538,10 @@
+@@ -545,16 +577,10 @@ static int luaB_coresume (lua_State *L) 
    int r;
    luaL_argcheck(L, co, 1, "coroutine expected");
    r = auxresume(L, co, lua_gettop(L) - 1);
@@ -377,7 +377,7 @@
  }
  
  
-@@ -536,8 +562,7 @@
+@@ -575,8 +601,7 @@ static int luaB_auxwrap (lua_State *L) {
  
  static int luaB_cocreate (lua_State *L) {
    lua_State *NL = lua_newthread(L);
@@ -387,10 +387,10 @@
    lua_pushvalue(L, 1);  /* move function to top */
    lua_xmove(L, NL, 1);  /* move function from L to NL */
    return 1;
-diff -ruN oldsrc/ldebug.c newsrc/ldebug.c
---- oldsrc/ldebug.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/ldebug.c	2006-04-15 23:44:03.000000000 -0500
-@@ -36,8 +36,8 @@
+diff -Naurp lua-5.1.4/src/ldebug.c lua-5.1.4-rvm/src/ldebug.c
+--- lua-5.1.4/src/ldebug.c	2008-05-08 12:56:26.000000000 -0400
++++ lua-5.1.4-rvm/src/ldebug.c	2009-09-12 13:43:55.226829075 -0400
+@@ -36,8 +36,8 @@ static const char *getfuncname (lua_Stat
  static int currentpc (lua_State *L, CallInfo *ci) {
    if (!isLua(ci)) return -1;  /* function is not a Lua function? */
    if (ci == L->ci)
@@ -401,7 +401,7 @@
  }
  
  
-@@ -597,24 +597,11 @@
+@@ -615,24 +615,11 @@ static void addinfo (lua_State *L, const
  }
  
  
@@ -427,10 +427,10 @@
 +  luaD_throw(L, LUA_ERRRUN);
  }
  
-diff -ruN oldsrc/ldebug.h newsrc/ldebug.h
---- oldsrc/ldebug.h	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/ldebug.h	2006-04-15 23:44:03.000000000 -0500
-@@ -26,7 +26,6 @@
+diff -Naurp lua-5.1.4/src/ldebug.h lua-5.1.4-rvm/src/ldebug.h
+--- lua-5.1.4/src/ldebug.h	2007-12-27 08:02:25.000000000 -0500
++++ lua-5.1.4-rvm/src/ldebug.h	2009-09-12 13:43:55.230162251 -0400
+@@ -26,7 +26,6 @@ LUAI_FUNC void luaG_aritherror (lua_Stat
  LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
                                               const TValue *p2);
  LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
@@ -438,10 +438,10 @@
  LUAI_FUNC int luaG_checkcode (const Proto *pt);
  LUAI_FUNC int luaG_checkopenop (Instruction i);
  
-diff -ruN oldsrc/ldo.c newsrc/ldo.c
---- oldsrc/ldo.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/ldo.c	2006-04-15 23:44:03.000000000 -0500
-@@ -58,6 +58,10 @@
+diff -Naurp lua-5.1.4/src/ldo.c lua-5.1.4-rvm/src/ldo.c
+--- lua-5.1.4/src/ldo.c	2008-01-18 17:31:22.000000000 -0500
++++ lua-5.1.4-rvm/src/ldo.c	2009-09-12 13:43:55.236828601 -0400
+@@ -58,6 +58,10 @@ void luaD_seterrorobj (lua_State *L, int
        setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
        break;
      }
@@ -452,7 +452,7 @@
      case LUA_ERRSYNTAX:
      case LUA_ERRRUN: {
        setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
-@@ -83,18 +87,34 @@
+@@ -83,18 +87,34 @@ static void resetstack (lua_State *L, in
    L->base = L->ci->base;
    luaF_close(L, L->base);  /* close eventual pending closures */
    luaD_seterrorobj(L, status, L->base);
@@ -493,7 +493,7 @@
    }
    else {
      L->status = cast_byte(errcode);
-@@ -114,12 +134,84 @@
+@@ -114,12 +134,84 @@ int luaD_rawrunprotected (lua_State *L, 
    lj.previous = L->errorJmp;  /* chain new error handler */
    L->errorJmp = &lj;
    LUAI_TRY(L, &lj,
@@ -579,7 +579,7 @@
  /* }====================================================== */
  
  
-@@ -180,10 +272,11 @@
+@@ -180,10 +272,11 @@ static CallInfo *growCI (lua_State *L) {
  
  void luaD_callhook (lua_State *L, int event, int line) {
    lua_Hook hook = L->hook;
@@ -592,7 +592,7 @@
      ar.event = event;
      ar.currentline = line;
      if (event == LUA_HOOKTAILRET)
-@@ -193,14 +286,22 @@
+@@ -193,14 +286,22 @@ void luaD_callhook (lua_State *L, int ev
      luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
      L->ci->top = L->top + LUA_MINSTACK;
      lua_assert(L->ci->top <= L->stack_last);
@@ -618,7 +618,7 @@
    }
  }
  
-@@ -262,17 +363,17 @@
+@@ -262,17 +363,17 @@ static StkId tryfuncTM (lua_State *L, St
  
  
  int luaD_precall (lua_State *L, StkId func, int nresults) {
@@ -641,7 +641,7 @@
      luaD_checkstack(L, p->maxstacksize);
      func = restorestack(L, funcr);
      if (!p->is_vararg) {  /* no varargs? */
-@@ -290,16 +391,18 @@
+@@ -290,16 +391,18 @@ int luaD_precall (lua_State *L, StkId fu
      L->base = ci->base = base;
      ci->top = L->base + p->maxstacksize;
      lua_assert(ci->top <= L->stack_last);
@@ -664,7 +664,7 @@
      }
      return PCRLUA;
    }
-@@ -312,11 +415,13 @@
+@@ -312,11 +415,13 @@ int luaD_precall (lua_State *L, StkId fu
      L->base = ci->base = ci->func + 1;
      ci->top = L->top + LUA_MINSTACK;
      lua_assert(ci->top <= L->stack_last);
@@ -680,7 +680,7 @@
      lua_lock(L);
      if (n < 0)  /* yielding? */
        return PCRYIELD;
-@@ -349,7 +454,7 @@
+@@ -349,7 +454,7 @@ int luaD_poscall (lua_State *L, StkId fi
    res = ci->func;  /* res == final position of 1st result */
    wanted = ci->nresults;
    L->base = (ci - 1)->base;  /* restore base */
@@ -689,7 +689,7 @@
    /* move results to correct place */
    for (i = wanted; i != 0 && firstResult < L->top; i--)
      setobjs2s(L, res++, firstResult++);
-@@ -366,41 +471,51 @@
+@@ -366,41 +471,51 @@ int luaD_poscall (lua_State *L, StkId fi
  ** When returns, all the results are on the stack, starting at the original
  ** function position.
  */ 
@@ -767,7 +767,7 @@
  }
  
  
-@@ -414,67 +529,61 @@
+@@ -415,67 +529,61 @@ static int resume_error (lua_State *L, c
  
  
  LUA_API int lua_resume (lua_State *L, int nargs) {
@@ -875,7 +875,7 @@
  /*
  ** Execute a protected parser.
  */
-@@ -484,12 +593,13 @@
+@@ -487,12 +593,13 @@ struct SParser {  /* data to `f_parser' 
    const char *name;
  };
  
@@ -890,7 +890,7 @@
    luaC_checkGC(L);
    tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
                                                               &p->buff, p->name);
-@@ -499,6 +609,7 @@
+@@ -502,6 +609,7 @@ static void f_parser (lua_State *L, void
      cl->l.upvals[i] = luaF_newupval(L);
    setclvalue(L, L->top, cl);
    incr_top(L);
@@ -898,7 +898,7 @@
  }
  
  
-@@ -507,7 +618,8 @@
+@@ -510,7 +618,8 @@ int luaD_protectedparser (lua_State *L, 
    int status;
    p.z = z; p.name = name;
    luaZ_initbuffer(L, &p.buff);
@@ -908,9 +908,9 @@
    luaZ_freebuffer(L, &p.buff);
    return status;
  }
-diff -ruN oldsrc/ldo.h newsrc/ldo.h
---- oldsrc/ldo.h	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/ldo.h	2006-04-15 23:44:03.000000000 -0500
+diff -Naurp lua-5.1.4/src/ldo.h lua-5.1.4-rvm/src/ldo.h
+--- lua-5.1.4/src/ldo.h	2007-12-27 08:02:25.000000000 -0500
++++ lua-5.1.4-rvm/src/ldo.h	2009-09-12 13:43:55.240162196 -0400
 @@ -31,18 +31,30 @@
  /* results from luaD_precall */
  #define PCRLUA		0	/* initiated a call to a Lua function */
@@ -948,7 +948,7 @@
  LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
  LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
  LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
-@@ -50,6 +62,13 @@
+@@ -50,6 +62,13 @@ LUAI_FUNC void luaD_growstack (lua_State
  
  LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
  LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
@@ -962,10 +962,10 @@
  
  LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
  
-diff -ruN oldsrc/lgc.c newsrc/lgc.c
---- oldsrc/lgc.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lgc.c	2006-04-15 23:44:03.000000000 -0500
-@@ -455,15 +455,12 @@
+diff -Naurp lua-5.1.4/src/lgc.c lua-5.1.4-rvm/src/lgc.c
+--- lua-5.1.4/src/lgc.c	2007-12-27 08:02:25.000000000 -0500
++++ lua-5.1.4-rvm/src/lgc.c	2009-09-12 13:43:55.243495581 -0400
+@@ -457,15 +457,12 @@ static void GCTM (lua_State *L) {
    makewhite(g, o);
    tm = fasttm(L, udata->uv.metatable, TM_GC);
    if (tm != NULL) {
@@ -982,10 +982,10 @@
      g->GCthreshold = oldt;  /* restore threshold */
    }
  }
-diff -ruN oldsrc/lstate.c newsrc/lstate.c
---- oldsrc/lstate.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lstate.c	2006-04-15 23:44:03.000000000 -0500
-@@ -55,6 +55,7 @@
+diff -Naurp lua-5.1.4/src/lstate.c lua-5.1.4-rvm/src/lstate.c
+--- lua-5.1.4/src/lstate.c	2008-01-03 10:20:39.000000000 -0500
++++ lua-5.1.4-rvm/src/lstate.c	2009-09-12 13:43:55.246828966 -0400
+@@ -55,6 +55,7 @@ static void stack_init (lua_State *L1, l
    setnilvalue(L1->top++);  /* `function' entry for this `ci' */
    L1->base = L1->ci->base = L1->top;
    L1->ci->top = L1->top + LUA_MINSTACK;
@@ -993,7 +993,7 @@
  }
  
  
-@@ -67,7 +68,7 @@
+@@ -67,7 +68,7 @@ static void freestack (lua_State *L, lua
  /*
  ** open parts that may cause memory-allocation errors
  */
@@ -1002,7 +1002,7 @@
    global_State *g = G(L);
    UNUSED(ud);
    stack_init(L, L);  /* init stack */
-@@ -78,6 +79,7 @@
+@@ -78,6 +79,7 @@ static void f_luaopen (lua_State *L, voi
    luaX_init(L);
    luaS_fix(luaS_newliteral(L, MEMERRMSG));
    g->GCthreshold = 4*g->totalbytes;
@@ -1010,7 +1010,7 @@
  }
  
  
-@@ -89,15 +91,13 @@
+@@ -89,15 +91,13 @@ static void preinit_state (lua_State *L,
    L->hook = NULL;
    L->hookmask = 0;
    L->basehookcount = 0;
@@ -1028,7 +1028,7 @@
    setnilvalue(gt(L));
  }
  
-@@ -190,9 +190,10 @@
+@@ -190,9 +190,10 @@ LUA_API lua_State *lua_newstate (lua_All
  }
  
  
@@ -1040,7 +1040,7 @@
  }
  
  
-@@ -202,9 +203,9 @@
+@@ -201,11 +202,11 @@ LUA_API void lua_close (lua_State *L) {
    lua_lock(L);
    luaF_close(L, L->stack);  /* close all upvalues for this thread */
    luaC_separateudata(L, 1);  /* separate udata that have GC metamethods */
@@ -1051,10 +1051,12 @@
      L->base = L->top = L->ci->base;
      L->nCcalls = 0;
    } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
-diff -ruN oldsrc/lstate.h newsrc/lstate.h
---- oldsrc/lstate.h	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lstate.h	2006-04-15 23:44:03.000000000 -0500
-@@ -48,10 +48,12 @@
+   lua_assert(G(L)->tmudata == NULL);
+   luai_userstateclose(L);
+diff -Naurp lua-5.1.4/src/lstate.h lua-5.1.4-rvm/src/lstate.h
+--- lua-5.1.4/src/lstate.h	2008-01-03 10:20:39.000000000 -0500
++++ lua-5.1.4-rvm/src/lstate.h	2009-09-12 13:43:55.250162141 -0400
+@@ -48,10 +48,12 @@ typedef struct stringtable {
  typedef struct CallInfo {
    StkId base;  /* base for this function */
    StkId func;  /* function index in the stack */
@@ -1070,7 +1072,7 @@
  } CallInfo;
  
  
-@@ -100,21 +102,19 @@
+@@ -100,21 +102,19 @@ typedef struct global_State {
  struct lua_State {
    CommonHeader;
    lu_byte status;
@@ -1096,7 +1098,7 @@
    int hookcount;
    lua_Hook hook;
    TValue l_gt;  /* table of globals */
-@@ -122,7 +122,7 @@
+@@ -123,7 +122,7 @@ struct lua_State {
    GCObject *openupval;  /* list of open upvalues in this stack */
    GCObject *gclist;
    struct lua_longjmp *errorJmp;  /* current error recover point */
@@ -1105,9 +1107,9 @@
  };
  
  
-diff -ruN oldsrc/ltablib.c newsrc/ltablib.c
---- oldsrc/ltablib.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/ltablib.c	2006-04-15 23:44:03.000000000 -0500
+diff -Naurp lua-5.1.4/src/ltablib.c lua-5.1.4-rvm/src/ltablib.c
+--- lua-5.1.4/src/ltablib.c	2008-02-14 11:46:58.000000000 -0500
++++ lua-5.1.4-rvm/src/ltablib.c	2009-09-12 13:43:55.253495596 -0400
 @@ -20,14 +20,22 @@
  
  
@@ -1134,7 +1136,7 @@
      if (!lua_isnil(L, -1))
        return 1;
      lua_pop(L, 1);  /* remove nil result */
-@@ -37,6 +45,7 @@
+@@ -37,6 +45,7 @@ static int foreachi (lua_State *L) {
  
  
  static int foreach (lua_State *L) {
@@ -1142,7 +1144,7 @@
    luaL_checktype(L, 1, LUA_TTABLE);
    luaL_checktype(L, 2, LUA_TFUNCTION);
    lua_pushnil(L);  /* first key */
-@@ -44,7 +53,8 @@
+@@ -44,7 +53,8 @@ static int foreach (lua_State *L) {
      lua_pushvalue(L, 2);  /* function */
      lua_pushvalue(L, -3);  /* key */
      lua_pushvalue(L, -3);  /* value */
@@ -1152,10 +1154,10 @@
      if (!lua_isnil(L, -1))
        return 1;
      lua_pop(L, 2);  /* remove value and result */
-diff -ruN oldsrc/luaconf.h newsrc/luaconf.h
---- oldsrc/luaconf.h	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/luaconf.h	2006-04-15 23:44:03.000000000 -0500
-@@ -580,7 +580,7 @@
+diff -Naurp lua-5.1.4/src/luaconf.h lua-5.1.4-rvm/src/luaconf.h
+--- lua-5.1.4/src/luaconf.h	2008-02-11 11:25:08.000000000 -0500
++++ lua-5.1.4-rvm/src/luaconf.h	2009-09-12 13:43:55.256828841 -0400
+@@ -607,7 +607,7 @@ union luai_Cast { double l_d; long l_l; 
  /* C++ exceptions */
  #define LUAI_THROW(L,c)	throw(c)
  #define LUAI_TRY(L,c,a)	try { a } catch(...) \
@@ -1164,9 +1166,9 @@
  #define luai_jmpbuf	int  /* dummy variable */
  
  #elif defined(LUA_USE_ULONGJMP)
-diff -ruN oldsrc/lua.h newsrc/lua.h
---- oldsrc/lua.h	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lua.h	2006-04-15 23:44:03.000000000 -0500
+diff -Naurp lua-5.1.4/src/lua.h lua-5.1.4-rvm/src/lua.h
+--- lua-5.1.4/src/lua.h	2008-08-06 09:30:12.000000000 -0400
++++ lua-5.1.4-rvm/src/lua.h	2009-09-12 13:43:55.260162296 -0400
 @@ -16,7 +16,7 @@
  #include "luaconf.h"
  
@@ -1176,7 +1178,7 @@
  #define LUA_VERSION_NUM	501
  #define LUA_COPYRIGHT	"Copyright (C) 1994-2006 Lua.org, PUC-Rio"
  #define LUA_AUTHORS 	"R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
-@@ -44,6 +44,7 @@
+@@ -45,6 +45,7 @@
  #define LUA_ERRSYNTAX	3
  #define LUA_ERRMEM	4
  #define LUA_ERRERR	5
@@ -1184,7 +1186,7 @@
  
  
  typedef struct lua_State lua_State;
-@@ -197,22 +198,37 @@
+@@ -198,22 +199,37 @@ LUA_API int   (lua_setfenv) (lua_State *
  /*
  ** `load' and `call' functions (load and run Lua code)
  */
@@ -1225,10 +1227,10 @@
  /*
  ** garbage-collection function and options
  */
-diff -ruN oldsrc/lvm.c newsrc/lvm.c
---- oldsrc/lvm.c	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lvm.c	2006-04-15 23:44:03.000000000 -0500
-@@ -57,10 +57,10 @@
+diff -Naurp lua-5.1.4/src/lvm.c lua-5.1.4-rvm/src/lvm.c
+--- lua-5.1.4/src/lvm.c	2007-12-28 10:32:23.000000000 -0500
++++ lua-5.1.4-rvm/src/lvm.c	2009-09-12 13:43:55.263495541 -0400
+@@ -57,10 +57,10 @@ int luaV_tostring (lua_State *L, StkId o
  }
  
  
@@ -1242,7 +1244,7 @@
    if (mask > LUA_MASKLINE) {  /* instruction-hook set? */
      if (L->hookcount == 0) {
        resethookcount(L);
-@@ -76,6 +76,7 @@
+@@ -74,6 +74,7 @@ static void traceexec (lua_State *L, con
      if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
        luaD_callhook(L, LUA_HOOKLINE, newline);
    }
@@ -1250,7 +1252,7 @@
  }
  
  
-@@ -87,7 +88,7 @@
+@@ -85,7 +86,7 @@ static void callTMres (lua_State *L, Stk
    setobj2s(L, L->top+2, p2);  /* 2nd argument */
    luaD_checkstack(L, 3);
    L->top += 3;
@@ -1259,7 +1261,7 @@
    res = restorestack(L, result);
    L->top--;
    setobjs2s(L, res, L->top);
-@@ -103,7 +104,7 @@
+@@ -101,7 +102,7 @@ static void callTM (lua_State *L, const 
    setobj2s(L, L->top+3, p3);  /* 3th argument */
    luaD_checkstack(L, 4);
    L->top += 4;
@@ -1268,7 +1270,7 @@
  }
  
  
-@@ -282,8 +283,11 @@
+@@ -280,8 +281,11 @@ void luaV_concat (lua_State *L, int tota
      StkId top = L->base + last + 1;
      int n = 2;  /* number of elements handled in this pass (at least 2) */
      if (!tostring(L, top-2) || !tostring(L, top-1)) {
@@ -1280,7 +1282,7 @@
      } else if (tsvalue(top-1)->len > 0) {  /* if len=0, do nothing */
        /* at least two string values; get as many as possible */
        size_t tl = tsvalue(top-1)->len;
-@@ -354,7 +358,7 @@
+@@ -354,7 +358,7 @@ static void Arith (lua_State *L, StkId r
  #define dojump(L,pc,i)	{(pc) += (i); luai_threadyield(L);}
  
  
@@ -1289,7 +1291,7 @@
  
  
  #define arith_op(op,tm) { \
-@@ -370,13 +374,14 @@
+@@ -370,13 +374,14 @@ static void Arith (lua_State *L, StkId r
  
  
  
@@ -1306,7 +1308,7 @@
    cl = &clvalue(L->ci->func)->l;
    base = L->base;
    k = cl->p->k;
-@@ -385,14 +390,8 @@
+@@ -386,14 +391,8 @@ void luaV_execute (lua_State *L, int nex
      const Instruction i = *pc++;
      StkId ra;
      if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
@@ -1323,7 +1325,7 @@
      /* warning!! several calls may realloc the stack and invalidate `ra' */
      ra = RA(i);
      lua_assert(base == L->base && L->base == L->ci->base);
-@@ -582,7 +581,7 @@
+@@ -583,7 +582,7 @@ void luaV_execute (lua_State *L, int nex
          int b = GETARG_B(i);
          int nresults = GETARG_C(i) - 1;
          if (b != 0) L->top = ra+b;  /* else previous instruction set top */
@@ -1332,7 +1334,7 @@
          switch (luaD_precall(L, ra, nresults)) {
            case PCRLUA: {
              nexeccalls++;
-@@ -595,14 +594,14 @@
+@@ -596,14 +595,14 @@ void luaV_execute (lua_State *L, int nex
              continue;
            }
            default: {
@@ -1349,7 +1351,7 @@
          lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
          switch (luaD_precall(L, ra, LUA_MULTRET)) {
            case PCRLUA: {
-@@ -617,7 +616,7 @@
+@@ -618,7 +617,7 @@ void luaV_execute (lua_State *L, int nex
                setobjs2s(L, func+aux, pfunc+aux);
              ci->top = L->top = func+aux;  /* correct top */
              lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
@@ -1358,7 +1360,7 @@
              ci->tailcalls++;  /* one more call lost */
              L->ci--;  /* remove new frame */
              goto reentry;
-@@ -627,7 +626,7 @@
+@@ -628,7 +627,7 @@ void luaV_execute (lua_State *L, int nex
              continue;
            }
            default: {
@@ -1367,7 +1369,7 @@
            }
          }
        }
-@@ -635,14 +634,13 @@
+@@ -636,14 +635,13 @@ void luaV_execute (lua_State *L, int nex
          int b = GETARG_B(i);
          if (b != 0) L->top = ra+b-1;
          if (L->openupval) luaF_close(L, base);
@@ -1385,7 +1387,7 @@
            goto reentry;
          }
        }
-@@ -662,7 +660,7 @@
+@@ -663,7 +661,7 @@ void luaV_execute (lua_State *L, int nex
          const TValue *init = ra;
          const TValue *plimit = ra+1;
          const TValue *pstep = ra+2;
@@ -1394,7 +1396,7 @@
          if (!tonumber(init, ra))
            luaG_runerror(L, LUA_QL("for") " initial value must be a number");
          else if (!tonumber(plimit, ra+1))
-@@ -679,7 +677,7 @@
+@@ -680,7 +678,7 @@ void luaV_execute (lua_State *L, int nex
          setobjs2s(L, cb+1, ra+1);
          setobjs2s(L, cb, ra);
          L->top = cb+3;  /* func. + 2 args (state and index) */
@@ -1403,7 +1405,7 @@
          L->top = L->ci->top;
          cb = RA(i) + 3;  /* previous call may change the stack */
          if (!ttisnil(cb)) {  /* continue loop? */
-@@ -760,3 +758,56 @@
+@@ -761,3 +759,56 @@ void luaV_execute (lua_State *L, int nex
    }
  }
  
@@ -1460,9 +1462,9 @@
 +             GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL);
 +}
 +
-diff -ruN oldsrc/lvm.h newsrc/lvm.h
---- oldsrc/lvm.h	2006-04-15 23:40:17.000000000 -0500
-+++ newsrc/lvm.h	2006-04-15 23:44:03.000000000 -0500
+diff -Naurp lua-5.1.4/src/lvm.h lua-5.1.4-rvm/src/lvm.h
+--- lua-5.1.4/src/lvm.h	2007-12-27 08:02:25.000000000 -0500
++++ lua-5.1.4-rvm/src/lvm.h	2009-09-12 13:43:55.266828996 -0400
 @@ -21,6 +21,9 @@
  #define equalobj(L,o1,o2) \
  	(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
@@ -1473,7 +1475,7 @@
  
  LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
  LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
-@@ -30,7 +33,8 @@
+@@ -30,7 +33,8 @@ LUAI_FUNC void luaV_gettable (lua_State 
                                              StkId val);
  LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
                                              StkId val);
--- lua5.1-rvm.patch	2009-09-12 14:47:33.206030054 -0400
+++ lua5.1-rvm-unsure	2009-09-12 14:37:04.103228089 -0400
@@ -335,17 +335,14 @@
 @@ -520,6 +548,7 @@ static int auxresume (lua_State *L, lua_
    if (!lua_checkstack(co, narg))
      luaL_error(L, "too many arguments to resume");
-   if (lua_status(co) == 0 && lua_gettop(co) == 0) {
+   if (status != CO_SUS) {
 +    lua_pushboolean(L, 0);
-     lua_pushliteral(L, "cannot resume dead coroutine");
+     lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
      return -1;  /* error flag */
    }
-@@ -528,13 +557,16 @@ static int auxresume (lua_State *L, lua_
-   status = lua_resume(co, narg);
-   if (status == 0 || status == LUA_YIELD) {
+@@ -530,11 +559,14 @@ static int auxresume (lua_State *L, lua_
      int nres = lua_gettop(co);
--    if (!lua_checkstack(L, nres))
-+    if (!lua_checkstack(L, nres+1))
+     if (!lua_checkstack(L, nres + 1))
        luaL_error(L, "too many results to resume");
 +    lua_pushboolean(L, 1);
      lua_xmove(co, L, nres);  /* move yielded values */
@@ -456,7 +453,7 @@
    L->base = L->ci->base;
    luaF_close(L, L->base);  /* close eventual pending closures */
    luaD_seterrorobj(L, status, L->base);
--  L->nCcalls = 0;
+-  L->nCcalls = L->baseCcalls;
 -  L->allowhook = 1;
 +  L->nCcalls = LUA_NOYIELD | LUA_NOVPCALL;
    restore_stack_limit(L);
@@ -689,7 +686,7 @@
    /* move results to correct place */
    for (i = wanted; i != 0 && firstResult < L->top; i--)
      setobjs2s(L, res++, firstResult++);
-@@ -366,41 +471,51 @@ int luaD_poscall (lua_State *L, StkId fi
+@@ -366,42 +471,51 @@ int luaD_poscall (lua_State *L, StkId fi
  ** When returns, all the results are on the stack, starting at the original
  ** function position.
  */ 
@@ -721,12 +718,14 @@
 -static void resume (lua_State *L, void *ud) {
 -  StkId firstArg = cast(StkId, ud);
 -  CallInfo *ci = L->ci;
--  if (L->status != LUA_YIELD) {  /* start coroutine */
+-  if (L->status == 0) {  /* start coroutine? */
 -    lua_assert(ci == L->base_ci && firstArg > L->base);
 -    if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
 -      return;
 -  }
 -  else {  /* resuming from previous yield */
+-    lua_assert(L->status == LUA_YIELD);
+-    L->status = 0;
 -    if (!f_isLua(ci)) {  /* `common' yield? */
 -      /* finish interrupted execution of `OP_CALL' */
 -      lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -752,7 +751,6 @@
 -      L->base = L->ci->base;
 +    L->base = L->ci->base;  /* restore invariant */
    }
--  L->status = 0;
 -  luaV_execute(L, cast_int(L->ci - L->base_ci));
 +  return f_continue(L, (void *)(ptrdiff_t)0);  /* resume remaining frames */
 +}
@@ -767,7 +765,7 @@
  }
  
  
-@@ -415,67 +529,61 @@ static int resume_error (lua_State *L, c
+@@ -415,69 +529,61 @@ static int resume_error (lua_State *L, c
  
  
  LUA_API int lua_resume (lua_State *L, int nargs) {
@@ -775,10 +773,7 @@
 +  void *ud;
    int status;
    lua_lock(L);
--  if (L->status != LUA_YIELD) {
--    if (L->status != 0)
--      return resume_error(L, "cannot resume dead coroutine");
--    else if (L->ci != L->base_ci)
+-  if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
 +  switch (L->status) {
 +  case LUA_YIELD:
 +    pf = f_coresume;
@@ -794,6 +789,8 @@
 +  default:
 +    return resume_error(L, "cannot resume dead coroutine");
 +  }
+-  if (L->nCcalls >= LUAI_MAXCCALLS)
+-    return resume_error(L, "C stack overflow");
 +  lua_assert(cast(StkId, ud) >= L->base);
 +  for (;;) {
 +    L->nCcalls = 0;
@@ -807,17 +804,21 @@
 +    }
 +    pf = f_continue;
 +    ud = (void *)(ptrdiff_t)0;  /* (void *)saveci(L, L->base_ci); */
-   }
++  }
 -  luai_userstateresume(L, nargs);
--  lua_assert(L->errfunc == 0 && L->nCcalls == 0);
+-  lua_assert(L->errfunc == 0);
+-  L->baseCcalls = ++L->nCcalls;
 -  status = luaD_rawrunprotected(L, resume, L->top - nargs);
 -  if (status != 0) {  /* error? */
 -    L->status = cast_byte(status);  /* mark thread as `dead' */
 -    luaD_seterrorobj(L, status, L->top);
 -    L->ci->top = L->top;
 -  }
--  else
+-  else {
+-    lua_assert(L->nCcalls == L->baseCcalls);
 -    status = L->status;
+-  }
+-  --L->nCcalls;
 +  L->nCcalls = LUA_NOYIELD | LUA_NOVPCALL;
 +  L->status = status;
    lua_unlock(L);
@@ -829,7 +830,7 @@
 -  luai_userstateyield(L, nresults);
 +LUA_API int lua_vyield (lua_State *L, int nresults, void *ctx) {
    lua_lock(L);
--  if (L->nCcalls > 0)
+-  if (L->nCcalls > L->baseCcalls)
 -    luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
 -  L->base = L->top - nresults;  /* protect stack slots below */
 -  L->status = LUA_YIELD;
@@ -1018,7 +1019,7 @@
    resethookcount(L);
    L->openupval = NULL;
    L->size_ci = 0;
--  L->nCcalls = 0;
+-  L->nCcalls = L->baseCcalls = 0;
 +  L->nCcalls = LUA_NOYIELD | LUA_NOVPCALL;
    L->status = 0;
    L->base_ci = L->ci = NULL;
@@ -1049,7 +1050,8 @@
      L->ci = L->base_ci;
 +    L->ci->errfunc = 0;  /* no error function during GC metamethods */
      L->base = L->top = L->ci->base;
-     L->nCcalls = 0;
+-    L->nCcalls = L->baseCcalls = 0;
++    L->nCcalls = 0;
    } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
    lua_assert(G(L)->tmudata == NULL);
    luai_userstateclose(L);
@@ -1072,7 +1074,7 @@
  } CallInfo;
  
  
-@@ -100,21 +102,19 @@ typedef struct global_State {
+@@ -100,22 +102,19 @@ typedef struct global_State {
  struct lua_State {
    CommonHeader;
    lu_byte status;
@@ -1091,10 +1093,11 @@
 -  int stacksize;
    int size_ci;  /* size of array `base_ci' */
 -  unsigned short nCcalls;  /* number of nested C calls */
++  unsigned short nCcalls;  /* number of nested C calls + callflags */
+-  unsigned short baseCcalls;  /* nested C calls when resuming coroutine */
 -  lu_byte hookmask;
 -  lu_byte allowhook;
 -  int basehookcount;
-+  unsigned short nCcalls;  /* number of nested C calls + callflags */
    int hookcount;
    lua_Hook hook;
    TValue l_gt;  /* table of globals */
@@ -1169,14 +1172,16 @@
 diff -Naurp lua-5.1.4/src/lua.h lua-5.1.4-rvm/src/lua.h
 --- lua-5.1.4/src/lua.h	2008-08-06 09:30:12.000000000 -0400
 +++ lua-5.1.4-rvm/src/lua.h	2009-09-12 13:43:55.260162296 -0400
-@@ -16,7 +16,7 @@
+@@ -16,8 +16,8 @@
  #include "luaconf.h"
  
  
 -#define LUA_VERSION	"Lua 5.1"
+-#define LUA_RELEASE	"Lua 5.1.4"
 +#define LUA_VERSION	"Lua 5.1+rvm"
++#define LUA_RELEASE	"Lua 5.1.4+rvm"
  #define LUA_VERSION_NUM	501
- #define LUA_COPYRIGHT	"Copyright (C) 1994-2006 Lua.org, PUC-Rio"
+ #define LUA_COPYRIGHT	"Copyright (C) 1994-2008 Lua.org, PUC-Rio"
  #define LUA_AUTHORS 	"R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
 @@ -45,6 +45,7 @@
  #define LUA_ERRSYNTAX	3
@@ -1241,9 +1246,9 @@
 -  L->savedpc = pc;
 +  const Instruction *oldpc = GETPC(L);
 +  SAVEPC(L, pc);
-   if (mask > LUA_MASKLINE) {  /* instruction-hook set? */
-     if (L->hookcount == 0) {
-       resethookcount(L);
+   if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
+     resethookcount(L);
+     luaD_callhook(L, LUA_HOOKCOUNT, -1);
 @@ -74,6 +74,7 @@ static void traceexec (lua_State *L, con
      if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
        luaD_callhook(L, LUA_HOOKLINE, newline);
@@ -1273,15 +1278,15 @@
 @@ -280,8 +281,11 @@ void luaV_concat (lua_State *L, int tota
      StkId top = L->base + last + 1;
      int n = 2;  /* number of elements handled in this pass (at least 2) */
-     if (!tostring(L, top-2) || !tostring(L, top-1)) {
+     if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
 +      setpvalue(L->top, (void *)(ptrdiff_t)(last - 1));  /* for luaV_resume */
 +      L->top++;
        if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
          luaG_concaterror(L, top-2, top-1);
 +      L->top--;
-     } else if (tsvalue(top-1)->len > 0) {  /* if len=0, do nothing */
-       /* at least two string values; get as many as possible */
-       size_t tl = tsvalue(top-1)->len;
+     } else if (tsvalue(top-1)->len == 0)  /* second op is empty? */
+       (void)tostring(L, top - 2);  /* result is first op (as string) */
+     else {
 @@ -354,7 +358,7 @@ static void Arith (lua_State *L, StkId r
  #define dojump(L,pc,i)	{(pc) += (i); luai_threadyield(L);}
  
@@ -1291,7 +1296,7 @@
  
  
  #define arith_op(op,tm) { \
-@@ -370,13 +374,14 @@ static void Arith (lua_State *L, StkId r
+@@ -370,14 +374,15 @@ static void Arith (lua_State *L, StkId r
  
  
  
@@ -1303,6 +1308,7 @@
    const Instruction *pc;
 +  int nexeccalls = 1;
   reentry:  /* entry point */
+   lua_assert(isLua(L->ci));
 -  pc = L->savedpc;
 +  pc = GETPC(L);
    cl = &clvalue(L->ci->func)->l;