Browse Source

no more L->base + ci->base only for Lua functions (C functions may use
'func')

Roberto Ierusalimschy 16 years ago
parent
commit
9423e22aa3
7 changed files with 81 additions and 80 deletions
  1. 17 13
      lapi.c
  2. 29 26
      ldebug.c
  3. 11 16
      ldo.c
  4. 1 2
      lstate.c
  5. 2 3
      lstate.h
  6. 3 3
      ltests.c
  7. 18 17
      lvm.c

+ 17 - 13
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.76 2009/04/17 22:00:01 roberto Exp $
+** $Id: lapi.c,v 2.76 2009/04/17 22:00:01 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -35,20 +35,21 @@ const char lua_ident[] =
 
 
 
-#define api_checknelems(L, n)	api_check(L, (n) <= (L->top - L->base))
+#define api_checknelems(L,n)  api_check(L, (n) < (L->top - L->ci->func))
 
 #define api_checkvalidindex(L, i)	api_check(L, (i) != luaO_nilobject)
 
 
 static TValue *index2adr (lua_State *L, int idx) {
+  CallInfo *ci = L->ci;
   if (idx > 0) {
-    TValue *o = L->base + (idx - 1);
-    api_check(L, idx <= L->ci->top - L->base);
+    TValue *o = ci->func + idx;
+    api_check(L, idx <= ci->top - (ci->func + 1));
     if (o >= L->top) return cast(TValue *, luaO_nilobject);
     else return o;
   }
   else if (idx > LUA_REGISTRYINDEX) {
-    api_check(L, idx != 0 && -idx <= L->top - L->base);
+    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1));
     return L->top + idx;
   }
   else switch (idx) {  /* pseudo-indices */
@@ -83,13 +84,15 @@ static Table *getcurrenv (lua_State *L) {
 
 LUA_API int lua_checkstack (lua_State *L, int size) {
   int res = 1;
+  CallInfo *ci = L->ci;
   lua_lock(L);
-  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
+  if (size > LUAI_MAXCSTACK ||
+      (L->top - (ci->func + 1) + size) > LUAI_MAXCSTACK)
     res = 0;  /* stack overflow */
   else if (size > 0) {
     luaD_checkstack(L, size);
-    if (L->ci->top < L->top + size)
-      L->ci->top = L->top + size;
+    if (ci->top < L->top + size)
+      ci->top = L->top + size;
   }
   lua_unlock(L);
   return res;
@@ -138,20 +141,21 @@ LUA_API void lua_checkversion_ (lua_State *L, int version) {
 
 
 LUA_API int lua_gettop (lua_State *L) {
-  return cast_int(L->top - L->base);
+  return cast_int(L->top - (L->ci->func + 1));
 }
 
 
 LUA_API void lua_settop (lua_State *L, int idx) {
+  StkId func = L->ci->func;
   lua_lock(L);
   if (idx >= 0) {
-    api_check(L, idx <= L->stack_last - L->base);
-    while (L->top < L->base + idx)
+    api_check(L, idx <= L->stack_last - (func + 1));
+    while (L->top < (func + 1) + idx)
       setnilvalue(L->top++);
-    L->top = L->base + idx;
+    L->top = (func + 1) + idx;
   }
   else {
-    api_check(L, -(idx+1) <= (L->top - L->base));
+    api_check(L, -(idx+1) <= (L->top - (func + 1)));
     L->top += idx+1;  /* `subtract' index (index is negative) */
   }
   lua_unlock(L);

+ 29 - 26
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.49 2009/04/30 17:42:21 roberto Exp roberto $
+** $Id: ldebug.c,v 2.50 2009/05/04 18:26:21 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -103,32 +103,34 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
 }
 
 
-static Proto *getluaproto (CallInfo *ci) {
-  return (isLua(ci) ? ci_func(ci)->l.p : NULL);
-}
-
-
-static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
-  const char *name;
-  Proto *fp = getluaproto(ci);
-  if (fp && (name = luaF_getlocalname(fp, n, currentpc(ci))) != NULL)
-    return name;  /* is a local variable in a Lua function */
-  else {
+static const char *findlocal (lua_State *L, CallInfo *ci, int n,
+                              StkId *pos) {
+  const char *name = NULL;
+  StkId base;
+  if (isLua(ci)) {
+    base = ci->u.l.base;
+    name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci));
+  }
+  else
+    base = ci->func + 1;
+  if (name == NULL) {  /* no 'standard' name? */
     StkId limit = (ci == L->ci) ? L->top : ci->next->func;
-    if (limit - ci->base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
-      return "(*temporary)";
-    else
-      return NULL;
+    if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
+      name = "(*temporary)";  /* generic name for any valid slot */
+    else return NULL;  /* no name */
   }
+  *pos = base + (n - 1);
+  return name;
 }
 
 
 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
   CallInfo *ci = ar->i_ci;
-  const char *name = findlocal(L, ci, n);
+  StkId pos;
+  const char *name = findlocal(L, ci, n, &pos);
   lua_lock(L);
   if (name) {
-    setobj2s(L, L->top, ci->base + (n - 1));
+    setobj2s(L, L->top, pos);
     api_incr_top(L);
   }
   lua_unlock(L);
@@ -138,10 +140,11 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
 
 LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
   CallInfo *ci = ar->i_ci;
-  const char *name = findlocal(L, ci, n);
+  StkId pos;
+  const char *name = findlocal(L, ci, n, &pos);
   lua_lock(L);
   if (name)
-      setobjs2s(L, ci->base + (n - 1), L->top - 1);
+      setobjs2s(L, pos, L->top - 1);
   L->top--;  /* pop value */
   lua_unlock(L);
   return name;
@@ -282,8 +285,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
   Proto *p;
   int lastpc, pc;
   const char *what = NULL;
-  if (!isLua(ci))  /* is not a Lua function? */
-    return NULL;  /* cannot find name for it */
+  lua_assert(isLua(ci));
   p = ci_func(ci)->l.p;
   lastpc = currentpc(ci);
   *name = luaF_getlocalname(p, reg + 1, lastpc);
@@ -418,17 +420,18 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
 /* only ANSI way to check whether a pointer points to an array */
 static int isinstack (CallInfo *ci, const TValue *o) {
   StkId p;
-  for (p = ci->base; p < ci->top; p++)
+  for (p = ci->u.l.base; p < ci->top; p++)
     if (o == p) return 1;
   return 0;
 }
 
 
 void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+  CallInfo *ci = L->ci;
   const char *name = NULL;
   const char *t = luaT_typenames[ttype(o)];
-  const char *kind = (isinstack(L->ci, o)) ?
-                         getobjname(L, L->ci, cast_int(o - L->base), &name) :
+  const char *kind = (isLua(ci) && isinstack(ci, o)) ?
+                         getobjname(L, ci, cast_int(o - ci->u.l.base), &name) :
                          NULL;
   if (kind)
     luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
@@ -469,7 +472,7 @@ static void addinfo (lua_State *L, const char *msg) {
   if (isLua(ci)) {  /* is Lua code? */
     char buff[LUA_IDSIZE];  /* add file:line information */
     int line = currentline(ci);
-    luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
+    luaO_chunkid(buff, getstr(ci_func(ci)->l.p->source), LUA_IDSIZE);
     luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
   }
 }

+ 11 - 16
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.63 2009/04/28 19:04:36 roberto Exp roberto $
+** $Id: ldo.c,v 2.64 2009/05/21 20:06:11 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -123,10 +123,10 @@ static void correctstack (lua_State *L, TValue *oldstack) {
     gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
   for (ci = L->ci; ci != NULL; ci = ci->previous) {
     ci->top = (ci->top - oldstack) + L->stack;
-    ci->base = (ci->base - oldstack) + L->stack;
     ci->func = (ci->func - oldstack) + L->stack;
+    if (isLua(ci))
+      ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
   }
-  L->base = (L->base - oldstack) + L->stack;
 }
 
 
@@ -245,8 +245,8 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
       base = adjust_varargs(L, p, nargs);
     ci = next_ci(L);  /* now 'enter' new function */
     ci->func = func;
-    L->base = ci->base = base;
-    ci->top = L->base + p->maxstacksize;
+    ci->u.l.base = base;
+    ci->top = base + p->maxstacksize;
     lua_assert(ci->top <= L->stack_last);
     ci->u.l.savedpc = p->code;  /* starting point */
     ci->u.l.tailcalls = 0;
@@ -265,7 +265,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
     luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
     ci = next_ci(L);  /* now 'enter' new function */
     ci->func = restorestack(L, funcr);
-    L->base = ci->base = ci->func + 1;
     ci->top = L->top + LUA_MINSTACK;
     lua_assert(ci->top <= L->stack_last);
     ci->callstatus = 0;
@@ -303,7 +302,6 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
   res = ci->func;  /* res == final position of 1st result */
   L->ci = ci = ci->previous;  /* back to caller */
   wanted = ci->nresults;
-  L->base = ci->base;  /* restore base */
   /* move results to correct place */
   for (i = wanted; i != 0 && firstResult < L->top; i--)
     setobjs2s(L, res++, firstResult++);
@@ -378,17 +376,15 @@ static void resume (lua_State *L, void *ud) {
   StkId firstArg = cast(StkId, ud);
   CallInfo *ci = L->ci;
   if (L->status == LUA_OK) {  /* start coroutine? */
-    lua_assert(ci == &L->base_ci && firstArg > L->base);
+    lua_assert(ci == &L->base_ci);
     if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))  /* Lua function? */
       luaV_execute(L);  /* call it */
   }
   else {  /* resuming from previous yield */
     lua_assert(L->status == LUA_YIELD);
     L->status = LUA_OK;
-    if (isLua(ci)) {  /* yielded inside a hook? */
-      L->base = ci->base;  /* just continue its execution */
+    if (isLua(ci))  /* yielded inside a hook? */
       luaV_execute(L);
-    }
     else {  /* 'common' yield */
       G(L)->nCcalls--;  /* finish 'luaD_call' */
       luaD_poscall(L, firstArg);  /* finish 'luaD_precall' */
@@ -399,7 +395,7 @@ static void resume (lua_State *L, void *ud) {
 
 
 static int resume_error (lua_State *L, const char *msg) {
-  L->top = L->ci->base;
+  L->top = L->ci->func + 1;
   setsvalue2s(L, L->top, luaS_new(L, msg));
   incr_top(L);
   lua_unlock(L);
@@ -429,7 +425,6 @@ static int recover (lua_State *L, int status) {
   luaF_close(L, oldtop);
   luaD_seterrorobj(L, status, oldtop);
   L->ci = ci;
-  L->base = ci->base;
   L->allowhook = ci->u.c.old_allowhook;
   L->nny = 0;  /* should be zero to be yieldable */
   restore_stack_limit(L);
@@ -477,10 +472,11 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
   lua_lock(L);
   if (L->nny > 0)
     luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
-  L->base = L->top - nresults;  /* protect stack slots below */
   L->status = LUA_YIELD;
-  if (!isLua(L->ci))  /* not inside a hook? */
+  if (!isLua(L->ci)) {  /* not inside a hook? */
+    L->ci->func = L->top - nresults - 1;  /* protect stack slots below ??? */
     luaD_throw(L, LUA_YIELD);
+  }
   lua_assert(L->ci->callstatus & CIST_HOOKED);  /* must be inside a hook */
   lua_unlock(L);
   return 0;  /* otherwise, return to 'luaD_callhook' */
@@ -501,7 +497,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
     luaF_close(L, oldtop);  /* close possible pending closures */
     luaD_seterrorobj(L, status, oldtop);
     L->ci = old_ci;
-    L->base = old_ci->base;
     L->allowhook = old_allowhooks;
     L->nny = old_nny;
     restore_stack_limit(L);

+ 1 - 2
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.53 2009/04/17 22:00:01 roberto Exp roberto $
+** $Id: lstate.c,v 2.54 2009/04/28 19:04:36 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -86,7 +86,6 @@ static void stack_init (lua_State *L1, lua_State *L) {
   /* initialize first ci */
   L1->ci->func = L1->top;
   setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
-  L1->base = L1->ci->base = L1->top;
   L1->ci->top = L1->top + LUA_MINSTACK;
   L1->ci->callstatus = 0;
 }

+ 2 - 3
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.42 2009/04/17 14:28:06 roberto Exp roberto $
+** $Id: lstate.h,v 2.43 2009/04/17 22:00:01 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -77,7 +77,6 @@ typedef struct stringtable {
 ** informations about a call
 */
 typedef struct CallInfo {
-  StkId base;  /* base for this function */
   StkId func;  /* function index in the stack */
   StkId	top;  /* top for this function */
   struct CallInfo *previous, *next;  /* dynamic call link */
@@ -85,6 +84,7 @@ typedef struct CallInfo {
   lu_byte callstatus;
   union {
     struct {  /* only for Lua functions */
+      StkId base;  /* base for this function */
       const Instruction *savedpc;
       int tailcalls;  /* number of tail calls lost under this entry */
     } l;
@@ -161,7 +161,6 @@ struct lua_State {
   CommonHeader;
   lu_byte status;
   StkId top;  /* first free slot in the stack */
-  StkId base;  /* base of current function */
   global_State *l_G;
   CallInfo *ci;  /* call info for current function */
   int nci;  /* number of total CallInfo structures linked */

+ 3 - 3
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.61 2009/04/17 14:28:06 roberto Exp roberto $
+** $Id: ltests.c,v 2.62 2009/04/17 22:00:01 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -43,7 +43,7 @@ void *l_Trick = 0;
 int islocked = 0;
 
 
-#define obj_at(L,k)	(L->ci->base+(k) - 1)
+#define obj_at(L,k)	(L->ci->func + (k))
 
 
 static void setnameval (lua_State *L, const char *name, int val) {
@@ -514,7 +514,7 @@ static int mem_query (lua_State *L) {
 
 
 static int settrick (lua_State *L) {
-  l_Trick = (L->base)->value.gc;
+  l_Trick = obj_at(L, 1)->value.gc;
   return 0;
 }
 

+ 18 - 17
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.88 2009/05/22 15:19:54 roberto Exp $
+** $Id: lvm.c,v 2.89 2009/05/27 17:11:27 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -357,12 +357,13 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
 */
 void luaV_finishOp (lua_State *L) {
   CallInfo *ci = L->ci;
+  StkId base = ci->u.l.base;
   Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
   switch (GET_OPCODE(inst)) {  /* finish its execution */
     case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
     case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
     case OP_GETGLOBAL: case OP_GETTABLE: case OP_SELF: {
-      setobjs2s(L, ci->base + GETARG_A(inst), --L->top);
+      setobjs2s(L, base + GETARG_A(inst), --L->top);
       break;
     }
     case OP_LE: case OP_LT: case OP_EQ: {
@@ -371,7 +372,7 @@ void luaV_finishOp (lua_State *L) {
       /* metamethod should not be called when operand is K */
       lua_assert(!ISK(GETARG_B(inst)));
       if (GET_OPCODE(inst) == OP_LE &&  /* "<=" using "<" instead? */
-          ttisnil(luaT_gettmbyobj(L, ci->base + GETARG_B(inst), TM_LE)))
+          ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
         res = !res;  /* invert result */
       lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
       if (res != GETARG_A(inst))  /* condition failed? */
@@ -381,14 +382,14 @@ void luaV_finishOp (lua_State *L) {
     case OP_CONCAT: {
       StkId top = L->top - 1;  /* top when 'call_binTM' was called */
       int b = GETARG_B(inst);      /* first element to concatenate */
-      int total = top - 1 - (ci->base + b);  /* elements yet to concatenate */
+      int total = top - 1 - (base + b);  /* elements yet to concatenate */
       setobj2s(L, top - 2, top);  /* put TM result in proper position */
       if (total > 1) {  /* are there elements to concat? */
         L->top = top - 1;  /* top is one after last element (at top-2) */
         luaV_concat(L, total);  /* concat them (may yield again) */
       }
       /* move final result to final position */
-      setobj2s(L, ci->base + GETARG_A(inst), L->top - 1);
+      setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
       L->top = ci->top;  /* restore top */
       break;
     }
@@ -428,7 +429,7 @@ void luaV_finishOp (lua_State *L) {
 #define dojump(i)	{ ci->u.l.savedpc += (i); luai_threadyield(L);}
 
 
-#define Protect(x)	{ {x;}; base = ci->base; }
+#define Protect(x)	{ {x;}; base = ci->u.l.base; }
 
 
 #define arith_op(op,tm) { \
@@ -448,7 +449,7 @@ void luaV_execute (lua_State *L) {
   CallInfo *ci = L->ci;
   LClosure *cl = &clvalue(ci->func)->l;
   TValue *k = cl->p->k;
-  StkId base = ci->base;
+  StkId base = ci->u.l.base;
   lua_assert(isLua(ci));
   /* main loop of interpreter */
   for (;;) {
@@ -461,11 +462,11 @@ void luaV_execute (lua_State *L) {
         ci->u.l.savedpc--;  /* undo increment */
         luaD_throw(L, LUA_YIELD);
       }
-      base = ci->base;
+      base = ci->u.l.base;
     }
     /* warning!! several calls may realloc the stack and invalidate `ra' */
     ra = RA(i);
-    lua_assert(base == ci->base && base == L->base);
+    lua_assert(base == ci->u.l.base);
     lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
     switch (GET_OPCODE(i)) {
       case OP_MOVE: {
@@ -642,7 +643,7 @@ void luaV_execute (lua_State *L) {
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         if (luaD_precall(L, ra, nresults)) {  /* C function? */
           if (nresults >= 0) L->top = ci->top;  /* adjust results */
-          base = ci->base;
+          base = ci->u.l.base;
           continue;
         }
         else {  /* Lua function */
@@ -656,7 +657,7 @@ void luaV_execute (lua_State *L) {
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
         if (luaD_precall(L, ra, LUA_MULTRET)) {  /* C function? */
-          base = ci->base;
+          base = ci->u.l.base;
           continue;
         }
         else {
@@ -666,12 +667,12 @@ void luaV_execute (lua_State *L) {
           StkId nfunc = nci->func;  /* called function index */
           StkId ofunc = oci->func;
           int aux;
-          if (cl->p->sizep > 0) luaF_close(L, oci->base);
-          L->base = oci->base = ofunc + (nci->base - nfunc);
+          if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
+          oci->u.l.base = ofunc + (nci->u.l.base - nfunc);
           for (aux = 0; nfunc+aux < L->top; aux++)  /* move frame down */
             setobjs2s(L, ofunc + aux, nfunc + aux);
           oci->top = L->top = ofunc + aux;  /* correct top */
-          lua_assert(L->top == oci->base + clvalue(ofunc)->l.p->maxstacksize);
+          lua_assert(L->top == oci->u.l.base + clvalue(ofunc)->l.p->maxstacksize);
           oci->u.l.savedpc = nci->u.l.savedpc;
           oci->u.l.tailcalls++;  /* one more call lost */
           ci = L->ci = oci;  /* remove new frame */
@@ -789,7 +790,7 @@ void luaV_execute (lua_State *L) {
       case OP_VARARG: {
         int b = GETARG_B(i) - 1;
         int j;
-        int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
+        int n = cast_int(base - ci->func) - cl->p->numparams - 1;
         if (b == LUA_MULTRET) {
           Protect(luaD_checkstack(L, n));
           ra = RA(i);  /* previous call may change the stack */
@@ -798,7 +799,7 @@ void luaV_execute (lua_State *L) {
         }
         for (j = 0; j < b; j++) {
           if (j < n) {
-            setobjs2s(L, ra + j, ci->base - n + j);
+            setobjs2s(L, ra + j, base - n + j);
           }
           else {
             setnilvalue(ra + j);
@@ -815,7 +816,7 @@ void luaV_execute (lua_State *L) {
     lua_assert(ci == L->ci);
     cl = &clvalue(ci->func)->l;
     k = cl->p->k;
-    base = ci->base;
+    base = ci->u.l.base;
   }
 }