From 7178a5e34aa56c09a01a6664bb7a61c6771700d4 Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 7 Feb 2001 16:13:49 -0200
Subject: new way to handle top x L->top

---
 lapi.c   |  10 +--
 lcode.c  |  39 ++++++-----
 ldebug.c |  18 ++---
 ldebug.h |   4 +-
 ldo.c    |  11 +---
 ldo.h    |   3 +-
 lgc.c    |   9 ++-
 lvm.c    | 227 ++++++++++++++++++++++++++++-----------------------------------
 lvm.h    |  12 ++--
 9 files changed, 153 insertions(+), 180 deletions(-)

diff --git a/lapi.c b/lapi.c
index 387f7a21..e58fe789 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.124 2001/02/01 16:03:38 roberto Exp roberto $
+** $Id: lapi.c,v 1.125 2001/02/02 15:13:05 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -208,7 +208,7 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
   o1 = luaA_indexAcceptable(L, index1);
   o2 = luaA_indexAcceptable(L, index2);
   i = (o1 == NULL || o2 == NULL) ? 0  /* index out-of-range */
-                                 : luaV_lessthan(L, o1, o2, L->top);
+                                 : luaV_lessthan(L, o1, o2);
   LUA_UNLOCK(L);
   return i;
 }
@@ -364,7 +364,7 @@ LUA_API void lua_gettable (lua_State *L, int index) {
   StkId t;
   LUA_LOCK(L);
   t = Index(L, index);
-  luaV_gettable(L, t, L->top, L->top-1);
+  luaV_gettable(L, t, L->top-1, L->top-1);
   LUA_UNLOCK(L);
 }
 
@@ -433,7 +433,7 @@ LUA_API void lua_newtable (lua_State *L) {
 
 LUA_API void lua_setglobal (lua_State *L, const char *name) {
   LUA_LOCK(L);
-  luaV_setglobal(L, luaS_new(L, name), L->top);
+  luaV_setglobal(L, luaS_new(L, name), L->top - 1);
   L->top--;  /* remove element from the top */
   LUA_UNLOCK(L);
 }
@@ -443,7 +443,7 @@ LUA_API void lua_settable (lua_State *L, int index) {
   StkId t;
   LUA_LOCK(L);
   t = Index(L, index);
-  luaV_settable(L, t, L->top - 2, L->top);
+  luaV_settable(L, t, L->top - 2, L->top - 1);
   L->top -= 2;  /* pop index and value */
   LUA_UNLOCK(L);
 }
diff --git a/lcode.c b/lcode.c
index 8fb0f70c..321af3c9 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 roberto Exp roberto $
+** $Id: lcode.c,v 1.59 2001/01/29 15:26:40 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -460,25 +460,26 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
 int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
   Proto *f;
   Instruction i = previous_instruction(fs);
-  int delta = (int)luaK_opproperties[o].push - (int)luaK_opproperties[o].pop;
+  int push = (int)luaK_opproperties[o].push;
+  int pop = (int)luaK_opproperties[o].pop;
   int optm = 0;  /* 1 when there is an optimization */
   switch (o) {
     case OP_CLOSURE: {
-      delta = -arg2+1;
+      pop = arg2;
       break;
     }
     case OP_SETTABLE: {
-      delta = -arg2;
+      pop = arg2;
       break;
     }
     case OP_SETLIST: {
       if (arg2 == 0) return NO_JUMP;  /* nothing to do */
-      delta = -arg2;
+      pop = arg2;
       break;
     }
     case OP_SETMAP: {
       if (arg1 == 0) return NO_JUMP;  /* nothing to do */
-      delta = -2*arg1;
+      pop = 2*arg1;
       break;
     }
     case OP_RETURN: {
@@ -491,7 +492,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
     }
     case OP_PUSHNIL: {
       if (arg1 == 0) return NO_JUMP;  /* nothing to do */
-      delta = arg1;
+      push = arg1;
       switch(GET_OPCODE(i)) {
         case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
         default: break;
@@ -500,7 +501,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
     }
     case OP_POP: {
       if (arg1 == 0) return NO_JUMP;  /* nothing to do */
-      delta = -arg1;
+      pop = arg1;
       switch(GET_OPCODE(i)) {
         case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
         default: break;
@@ -539,7 +540,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
       break;
     }
     case OP_CONCAT: {
-      delta = -arg1+1;
+      pop = arg1;
       switch(GET_OPCODE(i)) {
         case OP_CONCAT:  /* `a..b..c' */
           SETARG_U(i, GETARG_U(i)+1);
@@ -573,7 +574,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
     case OP_JMPEQ: {
       if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a==nil' */
         i = CREATE_0(OP_NOT);
-        delta = -1;  /* just undo effect of previous PUSHNIL */
+        pop = 1;  /* just undo effect of previous PUSHNIL */
         optm = 1;
       }
       break;
@@ -637,12 +638,14 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
       break;
     }
     default: {
-      lua_assert(delta != VD);
       break;
     }
   }
   f = fs->f;
-  luaK_deltastack(fs, delta);
+  lua_assert(push != VD);
+  lua_assert(pop != VD);
+  luaK_deltastack(fs, push);
+  luaK_deltastack(fs, -pop);
   if (optm) {  /* optimize: put instruction in place of last one */
       f->code[fs->pc-1] = i;  /* change previous instruction */
       return fs->pc-1;  /* do not generate new instruction */
@@ -668,7 +671,7 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = {
   {iAB, 0, 0},	/* OP_CALL */
   {iAB, 0, 0},	/* OP_TAILCALL */
   {iU, VD, 0},	/* OP_PUSHNIL */
-  {iU, VD, 0},	/* OP_POP */
+  {iU, 0, VD},	/* OP_POP */
   {iS, 1, 0},	/* OP_PUSHINT */
   {iU, 1, 0},	/* OP_PUSHSTRING */
   {iU, 1, 0},	/* OP_PUSHNUM */
@@ -683,16 +686,16 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = {
   {iU, 1, 0},	/* OP_CREATETABLE */
   {iU, 0, 1},	/* OP_SETLOCAL */
   {iU, 0, 1},	/* OP_SETGLOBAL */
-  {iAB, VD, 0},	/* OP_SETTABLE */
-  {iAB, VD, 0},	/* OP_SETLIST */
-  {iU, VD, 0},	/* OP_SETMAP */
+  {iAB, 0, VD},	/* OP_SETTABLE */
+  {iAB, 0, VD},	/* OP_SETLIST */
+  {iU, 0, VD},	/* OP_SETMAP */
   {iO, 1, 2},	/* OP_ADD */
   {iS, 1, 1},	/* OP_ADDI */
   {iO, 1, 2},	/* OP_SUB */
   {iO, 1, 2},	/* OP_MULT */
   {iO, 1, 2},	/* OP_DIV */
   {iO, 1, 2},	/* OP_POW */
-  {iU, VD, 0},	/* OP_CONCAT */
+  {iU, 1, VD},	/* OP_CONCAT */
   {iO, 1, 1},	/* OP_MINUS */
   {iO, 1, 1},	/* OP_NOT */
   {iS, 0, 2},	/* OP_JMPNE */
@@ -711,6 +714,6 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = {
   {iS, 0, 3},	/* OP_FORLOOP */
   {iS, 3, 0},	/* OP_LFORPREP */
   {iS, 0, 4},	/* OP_LFORLOOP */
-  {iAB, VD, 0}	/* OP_CLOSURE */
+  {iAB, 1, VD}	/* OP_CLOSURE */
 };
 
diff --git a/ldebug.c b/ldebug.c
index 0cb93494..a54b293c 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.58 2001/01/29 17:16:58 roberto Exp roberto $
+** $Id: ldebug.c,v 1.59 2001/02/02 15:13:05 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -397,10 +397,12 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
       }
       default: {
         OpCode op = GET_OPCODE(i);
-        lua_assert(luaK_opproperties[op].push != VD);
-        top -= (int)luaK_opproperties[op].pop;
-        lua_assert(top >= 0);
-        top = pushpc(stack, pc, top, luaK_opproperties[op].push);
+        int push = (int)luaK_opproperties[op].push;
+        int pop = (int)luaK_opproperties[op].pop;
+        lua_assert(push != VD && pop != VD);
+        lua_assert(0 <= top-pop && top+push <= pt->maxstacksize);
+        top -= pop;
+        top = pushpc(stack, pc, top, push);
       }
     }
   }
@@ -482,9 +484,9 @@ void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) {
 }
 
 
-void luaG_ordererror (lua_State *L, StkId top) {
-  const char *t1 = luaT_typename(G(L), top-2);
-  const char *t2 = luaT_typename(G(L), top-1);
+void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
+  const char *t1 = luaT_typename(G(L), p1);
+  const char *t2 = luaT_typename(G(L), p2);
   if (t1[2] == t2[2])
     luaO_verror(L, "attempt to compare two %.10s values", t1);
   else
diff --git a/ldebug.h b/ldebug.h
index dd217513..bab4d1d7 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.h,v 1.6 2000/10/02 20:10:55 roberto Exp roberto $
+** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp roberto $
 ** Auxiliary functions from Debug Interface module
 ** See Copyright Notice in lua.h
 */
@@ -15,7 +15,7 @@
 void luaG_typeerror (lua_State *L, StkId o, const char *op);
 void luaG_binerror (lua_State *L, StkId p1, int t, const char *op);
 int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
-void luaG_ordererror (lua_State *L, StkId top);
+void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
 
 
 #endif
diff --git a/ldo.c b/ldo.c
index 24f4a169..39ef5626 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.121 2001/02/02 15:13:05 roberto Exp roberto $
+** $Id: ldo.c,v 1.122 2001/02/02 16:23:20 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -143,14 +143,6 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
 }
 
 
-void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) {
-  StkId base = L->top - nParams;
-  luaD_openstack(L, base);
-  setclvalue(base, f);
-  luaD_call(L, base, nResults);
-}
-
-
 /*
 ** Call a function (C or Lua). The function to be called is at *func.
 ** The arguments are on the stack, right after the function.
@@ -182,6 +174,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
   if (callhook)  /* same hook that was active at entry */
     luaD_callHook(L, func, callhook, "return");
   lua_assert(ttype(func) == LUA_TMARK);
+  setnilvalue(func);  /* remove callinfo from the stack */
   /* move results to `func' (to erase parameters and function) */
   if (nResults == LUA_MULTRET) {
     while (firstResult < L->top)  /* copy all results */
diff --git a/ldo.h b/ldo.h
index 42497736..2cd9a91c 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp roberto $
+** $Id: ldo.h,v 1.29 2001/01/24 15:45:33 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -23,7 +23,6 @@ void luaD_init (lua_State *L, int stacksize);
 void luaD_adjusttop (lua_State *L, StkId base, int extra);
 void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
 void luaD_call (lua_State *L, StkId func, int nResults);
-void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
 void luaD_checkstack (lua_State *L, int n);
 
 void luaD_error (lua_State *L, const char *s);
diff --git a/lgc.c b/lgc.c
index c8331b69..77927940 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.86 2001/02/02 16:23:20 roberto Exp roberto $
+** $Id: lgc.c,v 1.87 2001/02/02 16:32:00 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -101,11 +101,14 @@ static void markobject (GCState *st, TObject *o) {
 static void markstacks (lua_State *L, GCState *st) {
   lua_State *L1 = L;
   do {  /* for each thread */
-    StkId o;
+    StkId o, lim;
     marktable(st, L1->gt);  /* mark table of globals */
     for (o=L1->stack; o<L1->top; o++)
       markobject(st, o);
-    lua_assert(L->previous->next == L && L->next->previous == L);
+    lim = (L1->stack_last - L1->top > MAXSTACK) ? L1->top+MAXSTACK
+                                              : L1->stack_last;
+    for (; o<=lim; o++) setnilvalue(o);
+    lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
     L1 = L1->next;
   } while (L1 != L);
 }
diff --git a/lvm.c b/lvm.c
index a25f02cd..55a9e433 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,10 +1,11 @@
 /*
-** $Id: lvm.c,v 1.164 2001/02/02 15:13:05 roberto Exp roberto $
+** $Id: lvm.c,v 1.165 2001/02/06 16:01:29 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
 
 
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -26,14 +27,6 @@
 
 
 
-/*
-** Extra stack size to run a function:
-** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
-*/
-#define	EXTRA_FSTACK	8
-
-
-
 int luaV_tonumber (TObject *obj) {
   if (ttype(obj) != LUA_TSTRING)
     return 1;
@@ -58,7 +51,7 @@ int luaV_tostring (lua_State *L, TObject *obj) {  /* LUA_NUMBER */
 }
 
 
-static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
+static void traceexec (lua_State *L, StkId base, lua_Hook linehook) {
   CallInfo *ci = infovalue(base-1);
   int *lineinfo = ci->func->f.l->lineinfo;
   int pc = (*ci->pc - ci->func->f.l->code) - 1;
@@ -72,7 +65,6 @@ static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
   /* calls linehook when enters a new line or jumps back (loop) */
   if (newline != ci->line || pc <= ci->lastpc) {
     ci->line = newline;
-    L->top = top;
     luaD_lineHook(L, base-2, newline, linehook);
   }
   ci->lastpc = pc;
@@ -104,19 +96,52 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
 }
 
 
+static void callTM (lua_State *L, const char *fmt, ...) {
+  va_list argp;
+  StkId base = L->top;
+  int has_result = 0;
+  va_start(argp, fmt);
+  for (;;) {
+    switch (*fmt++) {
+      case 'c':
+        setclvalue(L->top, va_arg(argp, Closure *));
+        break;
+      case 'o':
+        setobj(L->top, va_arg(argp, TObject *));
+        break;
+      case 's':
+        setsvalue(L->top, va_arg(argp, TString *));
+        break;
+      case 'r':
+        has_result = 1;
+        /* go through */
+      default:
+        goto endloop;
+    }
+    incr_top;
+  } endloop:
+  luaD_call(L, base, has_result);
+  if (has_result) {
+    L->top--;
+    setobj(va_arg(argp, TObject *), L->top);
+  }
+  va_end(argp);
+}
+
+
 /*
 ** Function to index a table.
-** Receives the table at `t' and the key at the top (`top'-1),
+** Receives the table at `t' and the key at the `key'.
 ** leaves the result at `res'.
 */
-void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) {
+void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
   Closure *tm;
   int tg;
   if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
       ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
         luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */
     /* do a primitive get */
-    const TObject *h = luaH_get(hvalue(t), top-1);
+    const TObject *h = luaH_get(hvalue(t), key);
     /* result is no nil or there is no `index' tag method? */
     if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) {
       setobj(res, h);
@@ -127,116 +152,79 @@ void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) {
   else {  /* try a `gettable' tag method */
     tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE);
   }
-  L->top = top;
   if (tm == NULL)  /* no tag method? */
     luaG_typeerror(L, t, "index");
-  else {  /* call tag method */
-    luaD_checkstack(L, 2);
-    setobj(res+2, top-1);  /* key */
-    setobj(res+1, t);  /* table */
-    setclvalue(res, tm);  /* tag method */
-    L->top = res+3;
-    luaD_call(L, res, 1);
-    L->top = top;  /* will be decremented by the callee */
-  }
+  else
+    callTM(L, "coor", tm, t, key, res);
 }
 
 
+
 /*
-** Receives table at `t', key at `key' and value at top.
+** Receives table at `t', key at `key' and value at `val'.
 */
-void luaV_settable (lua_State *L, StkId t, StkId key, StkId top) {
+void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) {
   int tg;
   if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
       ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
         luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */
-    setobj(luaH_set(L, hvalue(t), key), top-1);  /* do a primitive set */
+    setobj(luaH_set(L, hvalue(t), key), val);  /* do a primitive set */
   }
   else {  /* try a `settable' tag method */
     Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE);
-    lua_assert(L->top == top);
     if (tm == NULL)  /* no tag method? */
       luaG_typeerror(L, t, "index");
-    else {
-      luaD_checkstack(L, 3);
-      setobj(top+2, top-1);
-      setobj(top+1, key);
-      setobj(top, t);
-      setclvalue(top-1, tm);
-      L->top = top+3;
-      luaD_call(L, top-1, 0);  /* call `settable' tag method */
-      lua_assert(L->top == top-1);
-      L->top = top;  /* will be decremented by the callee */
-    }
+    else
+      callTM(L, "cooo", tm, t, key, val);
   }
 }
 
 
-void luaV_getglobal (lua_State *L, TString *s, StkId top) {
-  const TObject *value = luaH_getstr(L->gt, s);
+void luaV_getglobal (lua_State *L, TString *name, StkId res) {
+  const TObject *value = luaH_getstr(L->gt, name);
   Closure *tm;
   if (!HAS_TM_GETGLOBAL(L, ttype(value)) ||  /* is there a tag method? */
       (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) {
-    setobj(top, value);  /* default behavior */
-  }
-  else {  /* call tag method */
-    L->top = top;
-    luaD_checkstack(L, 3);
-    setclvalue(top, tm);
-    setsvalue(top+1, s);  /* global name */
-    setobj(top+2, value);
-    L->top = top+3;
-    luaD_call(L, top, 1);
-    lua_assert(L->top == top+1);
-    L->top = top;  /* will be incremented by the callee */
+    setobj(res, value);  /* default behavior */
   }
+  else
+    callTM(L, "csor", tm, name, value, res);
 }
 
 
-void luaV_setglobal (lua_State *L, TString *s, StkId top) {
-  TObject *oldvalue = luaH_setstr(L, L->gt, s);
+void luaV_setglobal (lua_State *L, TString *name, StkId val) {
+  TObject *oldvalue = luaH_setstr(L, L->gt, name);
   Closure *tm;
   if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) ||  /* no tag methods? */
      (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
-    setobj(oldvalue, top-1);  /* raw set */
-  }
-  else {  /* call tag method */
-    lua_assert(L->top == top);
-    luaD_checkstack(L, 3);
-    setobj(top+2, top-1);  /* new value */
-    setobj(top+1, oldvalue);  /* old value */
-    setsvalue(top, s);        /* var name */
-    setclvalue(top-1, tm);    /* tag method */
-    L->top = top+3;
-    luaD_call(L, top-1, 0);
-    lua_assert(L->top == top-1);
-    L->top = top;  /*  will be decremented by the callee */
+    setobj(oldvalue, val);  /* raw set */
   }
+  else
+    callTM(L, "csoo", tm, name, oldvalue, val);
 }
 
 
-static int call_binTM (lua_State *L, StkId top, TMS event) {
-  /* try first operand */
-  Closure *tm = luaT_gettmbyObj(G(L), top-2, event);
-  L->top = top;
+static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
+                       TObject *res, TMS event) {
+  TString *opname;
+  Closure *tm = luaT_gettmbyObj(G(L), p1, event);  /* try first operand */
   if (tm == NULL) {
-    tm = luaT_gettmbyObj(G(L), top-1, event);  /* try second operand */
+    tm = luaT_gettmbyObj(G(L), p2, event);  /* try second operand */
     if (tm == NULL) {
       tm = luaT_gettm(G(L), 0, event);  /* try a `global' method */
       if (tm == NULL)
-        return 0;  /* error */
+        return 0;  /* no tag method */
     }
   }
-  setsvalue(L->top, luaS_new(L, luaT_eventname[event]));
-  incr_top;
-  luaD_callTM(L, tm, 3, 1);
+  opname = luaS_new(L, luaT_eventname[event]);
+  callTM(L, "coosr", tm, p1, p2, opname, res);
   return 1;
 }
 
 
-static void call_arith (lua_State *L, StkId top, TMS event) {
-  if (!call_binTM(L, top, event))
-    luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on");
+static void call_arith (lua_State *L, StkId p1, TMS event) {
+  if (!call_binTM(L, p1, p1+1, p1, event))
+    luaG_binerror(L, p1, LUA_TNUMBER, "perform arithmetic on");
 }
 
 
@@ -262,19 +250,14 @@ static int luaV_strlessthan (const TString *ls, const TString *rs) {
 }
 
 
-int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
+int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
   if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER)
     return (nvalue(l) < nvalue(r));
   else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING)
     return luaV_strlessthan(tsvalue(l), tsvalue(r));
-  else {  /* call TM */
-    L->top = top;
-    luaD_checkstack(L, 2);
-    setobj(top++, l);
-    setobj(top++, r);
-    if (!call_binTM(L, top, TM_LT))
-      luaG_ordererror(L, top);
-    L->top--;
+  else {  /* try TM */
+    if (!call_binTM(L, l, r, L->top, TM_LT))
+      luaG_ordererror(L, l, r);
     return (ttype(L->top) != LUA_TNIL);
   }
 }
@@ -284,7 +267,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
   do {
     int n = 2;  /* number of elements handled in this pass (at least 2) */
     if (tostring(L, top-2) || tostring(L, top-1)) {
-      if (!call_binTM(L, top, TM_CONCAT))
+      if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
         luaG_binerror(L, top-2, LUA_TSTRING, "concat");
     }
     else if (tsvalue(top-1)->len > 0) {  /* if len=0, do nothing */
@@ -350,17 +333,16 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
   TString **const kstr = tf->kstr;
   const lua_Hook linehook = L->linehook;
   infovalue(base-1)->pc = &pc;
-  luaD_checkstack(L, tf->maxstacksize+EXTRA_FSTACK);
   if (tf->is_vararg)  /* varargs? */
     adjust_varargs(L, base, tf->numparams);
-  else
-    luaD_adjusttop(L, base, tf->numparams);
-  top = L->top;
+  luaD_adjusttop(L, base, tf->maxstacksize);
+  top = base+tf->numparams+tf->is_vararg;
   /* main loop of interpreter */
   for (;;) {
     const Instruction i = *pc++;
+    lua_assert(L->top == base+tf->maxstacksize);
     if (linehook)
-      traceexec(L, base, top, linehook);
+      traceexec(L, base, linehook);
     switch (GET_OPCODE(i)) {
       case OP_RETURN: {
         L->top = top;
@@ -372,6 +354,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         L->top = top;
         luaD_call(L, base+GETARG_A(i), nres);
         top = L->top;
+        L->top = base+tf->maxstacksize;
         break;
       }
       case OP_TAILCALL: {
@@ -425,31 +408,27 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         break;
       }
       case OP_GETTABLE: {
-        luaV_gettable(L, top-2, top, top-2);
         top--;
+        luaV_gettable(L, top-1, top, top-1);
         break;
       }
       case OP_GETDOTTED: {
         setsvalue(top, kstr[GETARG_U(i)]);
-        luaV_gettable(L, top-1, top+1, top-1);
+        luaV_gettable(L, top-1, top, top-1);
         break;
       }
       case OP_GETINDEXED: {
-        setobj(top, base+GETARG_U(i));
-        luaV_gettable(L, top-1, top+1, top-1);
+        luaV_gettable(L, top-1, base+GETARG_U(i), top-1);
         break;
       }
       case OP_PUSHSELF: {
-        TObject receiver;
-        setobj(&receiver, top-1);
-        setsvalue(top, kstr[GETARG_U(i)]);
+        setobj(top, top-1);
+        setsvalue(top+1, kstr[GETARG_U(i)]);
+        luaV_gettable(L, top-1, top+1, top-1);
         top++;
-        luaV_gettable(L, top-2, top, top-2);
-        setobj(top-1, &receiver);
         break;
       }
       case OP_CREATETABLE: {
-        L->top = top;
         luaC_checkGC(L);
         sethvalue(top, luaH_new(L, GETARG_U(i)));
         top++;
@@ -460,15 +439,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         break;
       }
       case OP_SETGLOBAL: {
-        L->top = top;  /* primitive set may generate an error */
-        luaV_setglobal(L, kstr[GETARG_U(i)], top);
         top--;
+        luaV_setglobal(L, kstr[GETARG_U(i)], top);
         break;
       }
       case OP_SETTABLE: {
         StkId t = top-GETARG_A(i);
-        L->top = top;  /* primitive set may generate an error */
-        luaV_settable(L, t, t+1, top);
+        luaV_settable(L, t, t+1, top-1);
         top -= GETARG_B(i);  /* pop values */
         break;
       }
@@ -476,16 +453,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
         int n = GETARG_B(i);
         Hash *arr = hvalue(top-n-1);
-        L->top = top-n;
         for (; n; n--)
           setobj(luaH_setnum(L, arr, n+aux), --top);
         break;
       }
       case OP_SETMAP: {
         int n = GETARG_U(i);
-        StkId finaltop = top-2*n;
-        Hash *arr = hvalue(finaltop-1);
-        L->top = finaltop;
+        Hash *arr = hvalue((top-2*n)-1);
         for (; n; n--) {
           top-=2;
           setobj(luaH_set(L, arr, top), top+1);
@@ -494,7 +468,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_ADD: {
         if (tonumber(top-2) || tonumber(top-1))
-          call_arith(L, top, TM_ADD);
+          call_arith(L, top-2, TM_ADD);
         else
           nvalue(top-2) += nvalue(top-1);
         top--;
@@ -503,7 +477,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       case OP_ADDI: {
         if (tonumber(top-1)) {
           setnvalue(top, (lua_Number)GETARG_S(i));
-          call_arith(L, top+1, TM_ADD);
+          call_arith(L, top-1, TM_ADD);
         }
         else
           nvalue(top-1) += (lua_Number)GETARG_S(i);
@@ -511,7 +485,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_SUB: {
         if (tonumber(top-2) || tonumber(top-1))
-          call_arith(L, top, TM_SUB);
+          call_arith(L, top-2, TM_SUB);
         else
           nvalue(top-2) -= nvalue(top-1);
         top--;
@@ -519,7 +493,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_MULT: {
         if (tonumber(top-2) || tonumber(top-1))
-          call_arith(L, top, TM_MUL);
+          call_arith(L, top-2, TM_MUL);
         else
           nvalue(top-2) *= nvalue(top-1);
         top--;
@@ -527,14 +501,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_DIV: {
         if (tonumber(top-2) || tonumber(top-1))
-          call_arith(L, top, TM_DIV);
+          call_arith(L, top-2, TM_DIV);
         else
           nvalue(top-2) /= nvalue(top-1);
         top--;
         break;
       }
       case OP_POW: {
-        if (!call_binTM(L, top, TM_POW))
+        if (!call_binTM(L, top-2, top-1, top-2, TM_POW))
           luaD_error(L, "undefined operation");
         top--;
         break;
@@ -543,14 +517,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         int n = GETARG_U(i);
         luaV_strconc(L, n, top);
         top -= n-1;
-        L->top = top;
         luaC_checkGC(L);
         break;
       }
       case OP_MINUS: {
         if (tonumber(top-1)) {
           setnilvalue(top);
-          call_arith(L, top+1, TM_UNM);
+          call_arith(L, top-1, TM_UNM);
         }
         else
           nvalue(top-1) = -nvalue(top-1);
@@ -574,22 +547,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_JMPLT: {
         top -= 2;
-        if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
+        if (luaV_lessthan(L, top, top+1)) dojump(pc, i);
         break;
       }
       case OP_JMPLE: {  /* a <= b  ===  !(b<a) */
         top -= 2;
-        if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
+        if (!luaV_lessthan(L, top+1, top)) dojump(pc, i);
         break;
       }
       case OP_JMPGT: {  /* a > b  ===  (b<a) */
         top -= 2;
-        if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
+        if (luaV_lessthan(L, top+1, top)) dojump(pc, i);
         break;
       }
       case OP_JMPGE: {  /* a >= b  ===  !(a<b) */
         top -= 2;
-        if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
+        if (!luaV_lessthan(L, top, top+1)) dojump(pc, i);
         break;
       }
       case OP_JMPT: {
@@ -675,11 +648,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_CLOSURE: {
         int nup = GETARG_B(i);
+        luaC_checkGC(L);
         L->top = top;
         luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup);
         top -= (nup-1);
-        lua_assert(top == L->top);
-        luaC_checkGC(L);
+        L->top = base+tf->maxstacksize;
         break;
       }
     }
diff --git a/lvm.h b/lvm.h
index ed862f2d..a8513c8a 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 1.27 2000/10/05 12:14:08 roberto Exp roberto $
+** $Id: lvm.h,v 1.28 2001/02/01 16:03:38 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -19,14 +19,14 @@
 
 int luaV_tonumber (TObject *obj);
 int luaV_tostring (lua_State *L, TObject *obj);
-void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res);
-void luaV_settable (lua_State *L, StkId t, StkId key, StkId top);
-void luaV_getglobal (lua_State *L, TString *s, StkId top);
-void luaV_setglobal (lua_State *L, TString *s, StkId top);
+void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
+void luaV_settable (lua_State *L, StkId t, StkId key, StkId val);
+void luaV_getglobal (lua_State *L, TString *s, StkId res);
+void luaV_setglobal (lua_State *L, TString *s, StkId val);
 StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
 void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
 void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
-int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
+int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
 void luaV_strconc (lua_State *L, int total, StkId top);
 
 #endif
-- 
cgit v1.2.3-55-g6feb