From 8f837e83b20f3c409ba187765c2bf5aefc111923 Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Thu, 7 Mar 2002 15:14:29 -0300
Subject: using `ci->top' to control acceptable indices in C calls

---
 ldo.c    | 36 +++++++++++++++++++++---------------
 lgc.c    | 16 +++++++++-------
 lstate.c |  3 ++-
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/ldo.c b/ldo.c
index 2c2a28cd..ed18aec7 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.154 2002/01/11 20:27:41 roberto Exp $
+** $Id: ldo.c,v 1.160 2002/02/14 21:40:13 roberto Exp $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -86,7 +86,7 @@ void luaD_growstack (lua_State *L, int n) {
   else {
     if (n <= L->stacksize && 2*L->stacksize < LUA_MAXSTACK)  /* can double? */
       luaD_reallocstack(L, 2*L->stacksize);
-   else if (L->stacksize+n <= LUA_MAXSTACK)  /* no overflow? */
+   else if ((L->top - L->stack) + n <= LUA_MAXSTACK)  /* no overflow? */
       luaD_reallocstack(L, LUA_MAXSTACK);
    else {
       /* resize to maximum + some extra space to handle error */
@@ -108,7 +108,7 @@ static void luaD_openstack (lua_State *L, StkId pos) {
 
 
 static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
-  L->ci->top = L->top;
+  StkId top = L->top;
   luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
   L->allowhooks = 0;  /* cannot call hooks inside a hook */
   lua_unlock(L);
@@ -116,7 +116,7 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
   lua_lock(L);
   lua_assert(L->allowhooks == 0);
   L->allowhooks = 1;
-  L->top = L->ci->top;
+  L->top = top;
 }
 
 
@@ -137,6 +137,7 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
     ar.event = event;
     ar._ci = L->ci - L->base_ci;
     L->ci->pc = NULL;  /* function is not active */
+    L->ci->top = L->top + LUA_MINSTACK;
     dohook(L, &ar, callhook);
   }
 }
@@ -186,6 +187,19 @@ static void adjust_varargs (lua_State *L, int nfixargs) {
 }
 
 
+static StkId tryfuncTM (lua_State *L, StkId func) {
+  const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
+  if (ttype(tm) != LUA_TFUNCTION) {
+    L->ci--;  /* undo increment (no function here) */
+    luaG_typeerror(L, func, "call");
+  }
+  luaD_openstack(L, func);
+  func = L->ci->base - 1;  /* previous call may change stack */
+  setobj(func, tm);  /* tag method is the new function to be called */
+  return func;
+}
+
+
 StkId luaD_precall (lua_State *L, StkId func) {
   CallInfo *ci;
   LClosure *cl;
@@ -193,17 +207,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
   ci = L->ci;
   ci->base = func+1;
   ci->pc = NULL;
-  if (ttype(func) != LUA_TFUNCTION) {
-    /* `func' is not a function; check the `function' tag method */
-    const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
-    if (ttype(tm) != LUA_TFUNCTION) {
-      L->ci--;  /* undo increment (no function here) */
-      luaG_typeerror(L, func, "call");
-    }
-    luaD_openstack(L, func);
-    func = ci->base - 1;  /* previous call may change stack */
-    setobj(func, tm);  /* tag method is the new function to be called */
-  }
+  if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
+    func = tryfuncTM(L, func);  /* check the `function' tag method */
   cl = &clvalue(func)->l;
   if (L->callhook) {
     luaD_callHook(L, L->callhook, "call");
@@ -226,6 +231,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
   else {  /* if is a C function, call it */
     int n;
     luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
+    ci->top = L->top + LUA_MINSTACK;
     lua_unlock(L);
 #if LUA_COMPATUPVALUES
     lua_pushupvalues(L);
diff --git a/lgc.c b/lgc.c
index 884f689f..1088cb23 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.128 2002/03/04 21:32:34 roberto Exp roberto $
+** $Id: lgc.c,v 1.129 2002/03/05 16:22:54 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -122,12 +122,12 @@ static void reallymarkobject (GCState *st, TObject *o) {
 }
 
 
-static void checkstacksizes (lua_State *L) {
+static void checkstacksizes (lua_State *L, StkId max) {
   int used = L->ci - L->base_ci;  /* number of `ci' in use */
   if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
     luaD_reallocCI(L, L->size_ci/2);  /* still big enough... */
-  used = L->top - L->stack;  /* part of stack in use */
-  if (2*(used+MAXSTACK) < L->stacksize && 2*BASIC_STACK_SIZE < L->stacksize)
+  used = max - L->stack;  /* part of stack in use */
+  if (4*used < L->stacksize && 2*BASIC_STACK_SIZE < L->stacksize)
     luaD_reallocstack(L, L->stacksize/2);  /* still big enough... */
 }
 
@@ -136,6 +136,7 @@ static void markstacks (GCState *st) {
   lua_State *L1 = st->L;
   do {  /* for each thread */
     StkId o, lim;
+    CallInfo *ci;
     if (L1->base_ci == NULL) {  /* incomplete state? */
       lua_assert(L1 != st->L);
       L1 = L1->next;
@@ -144,10 +145,11 @@ static void markstacks (GCState *st) {
     }
     for (o=L1->stack; o<L1->top; o++)
       markobject(st, o);
-    lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK
-                                                     : L1->stack_last;
+    lim = o;
+    for (ci = L1->base_ci; ci <= L1->ci; ci++)
+      if (lim < ci->top) lim = ci->top;
     for (; o<=lim; o++) setnilvalue(o);
-    checkstacksizes(L1);
+    checkstacksizes(L1, lim);
     lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
     L1 = L1->next;
   } while (L1 != st->L);
diff --git a/lstate.c b/lstate.c
index ea625ccc..45a0cec9 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.84 2002/02/14 21:40:13 roberto Exp roberto $
+** $Id: lstate.c,v 1.85 2002/03/05 16:22:54 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -33,6 +33,7 @@ static void stack_init (lua_State *L, lua_State *OL) {
   L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo);
   L->ci = L->base_ci;
   L->ci->base = L->top;
+  L->ci->top = L->top;
   L->ci->pc = NULL;
   L->size_ci = BASIC_CI_SIZE;
   L->end_ci = L->base_ci + L->size_ci;
-- 
cgit v1.2.3-55-g6feb