/*
** $Id: lvm.c,v 1.189 2001/06/28 14:48:44 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/


#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LUA_PRIVATE
#include "lua.h"

#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"



static void luaV_checkGC (lua_State *L, StkId top) {
  if (G(L)->nblocks >= G(L)->GCthreshold) {
    StkId temp = L->top;
    L->top = top;
    luaC_collectgarbage(L);
    L->top = temp;  /* restore old top position */
  }
}


const TObject *luaV_tonumber (const TObject *obj, TObject *n) {
  lua_Number num;
  if (ttype(obj) == LUA_TNUMBER) return obj;
  if (ttype(obj) == LUA_TSTRING && luaO_str2d(svalue(obj), &num)) {
    setnvalue(n, num);
    return n;
  }
  else
    return NULL;
}


int luaV_tostring (lua_State *L, TObject *obj) {
  if (ttype(obj) != LUA_TNUMBER)
    return 1;
  else {
    l_char s[32];  /* 16 digits, sign, point and \0  (+ some extra...) */
    lua_number2str(s, nvalue(obj));  /* convert `s' to number */
    setsvalue(obj, luaS_new(L, s));
    return 0;
  }
}


static void traceexec (lua_State *L, lua_Hook linehook) {
  CallInfo *ci = L->ci;
  int *lineinfo = ci_func(ci)->f.l->lineinfo;
  int pc = (*ci->pc - ci_func(ci)->f.l->code) - 1;
  int newline;
  if (pc == 0) {  /* may be first time? */
    ci->line = 1;
    ci->refi = 0;
    ci->lastpc = pc+1;  /* make sure it will call linehook */
  }
  newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
  /* calls linehook when enters a new line or jumps back (loop) */
  if (newline != ci->line || pc <= ci->lastpc) {
    ci->line = newline;
    luaD_lineHook(L, newline, linehook);
  }
  ci->lastpc = pc;
}


static Closure *luaV_closure (lua_State *L, int nelems) {
  Closure *c = luaF_newclosure(L, nelems);
  L->top -= nelems;
  while (nelems--)
    setobj(&c->upvalue[nelems], L->top+nelems);
  setclvalue(L->top, c);
  incr_top;
  return c;
}


void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
  Closure *cl = luaV_closure(L, nelems);
  cl->f.c = c;
  cl->isC = 1;
}


void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
  Closure *cl = luaV_closure(L, nelems);
  cl->f.l = l;
  cl->isC = 0;
}


/* maximum stack used by a call to a tag method (func + args) */
#define MAXSTACK_TM	4

static StkId callTM (lua_State *L, Closure *f, const l_char *fmt, ...) {
  va_list argp;
  StkId base = L->top;
  lua_assert(strlen(fmt)+1 <= MAXSTACK_TM);
  luaD_checkstack(L, MAXSTACK_TM);
  va_start(argp, fmt);
  setclvalue(L->top, f);  /* push function */
  L->top++;
  while (*fmt) {
    if (*fmt++ == l_c('o')) {
        setobj(L->top, va_arg(argp, TObject *));
    }
    else {
      lua_assert(*(fmt-1) == l_c('s'));
      setsvalue(L->top, va_arg(argp, TString *));
    }
    L->top++;
  }
  luaD_call(L, base);
  va_end(argp);
  return base;
}


#define setTM(L, base)	(L->top = (base))

static void setTMresult (lua_State *L, TObject *result, StkId base) {
  if (L->top == base) {  /* are there valid results? */
    setnilvalue(result);  /* function had no results */
  }
  else {
    setobj(result, base);  /* get first result */
  }
  L->top = base;  /* restore top */
}


/*
** Function to index a table.
** Receives the table at `t' and the key at the `key'.
** leaves the result at `res'.
*/
void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
  Closure *tm;
  if (ttype(t) == LUA_TTABLE) {  /* `t' is a table? */
    int tg = hvalue(t)->htag;
    if (tg == LUA_TTABLE ||  /* with default tag? */
       (tm = luaT_gettm(G(L), tg, TM_GETTABLE)) == NULL) {  /* or no TM? */
      const TObject *h = luaH_get(hvalue(t), key);  /* do a primitive get */
      /* result is no nil or there is no `index' tag method? */
      if (ttype(h) != LUA_TNIL ||  /* no nil? */
         ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) {  /* or no index TM? */
        setobj(res, h);  /* default get */
        return;
      }
    }
    /* else will call the tag method */
  } else {  /* not a table; try a `gettable' tag method */
    tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE);
    if (tm == NULL)  /* no tag method? */
      luaG_typeerror(L, t, l_s("index"));
  }
  setTMresult(L, res, callTM(L, tm, l_s("oo"), t, key));
}



/*
** Receives table at `t', key at `key' and value at `val'.
*/
void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
  Closure *tm;
  if (ttype(t) == LUA_TTABLE) {  /* `t' is a table? */
    int tg = hvalue(t)->htag;
    if (hvalue(t)->htag == LUA_TTABLE ||  /* with default tag? */
        (tm = luaT_gettm(G(L), tg, TM_SETTABLE)) == NULL) { /* or no TM? */
      setobj(luaH_set(L, hvalue(t), key), val);  /* do a primitive set */
      return;
    }
    /* else will call the tag method */
  } else {  /* not a table; try a `settable' tag method */
    tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE);
    if (tm == NULL)  /* no tag method? */
      luaG_typeerror(L, t, l_s("index"));
  }
  setTM(L, callTM(L, tm, l_s("ooo"), t, key, val));
}


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(res, value);  /* default behavior */
  }
  else
    setTMresult(L, res, callTM(L, tm, l_s("so"), name, value));
}


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, val);  /* raw set */
  }
  else
    setTM(L, callTM(L, tm, l_s("soo"), name, oldvalue, val));
}


static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
                       TObject *res, TMS event) {
  Closure *tm = luaT_gettmbyObj(G(L), p1, event);  /* try first operand */
  if (tm == NULL) {
    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;  /* no tag method */
    }
  }
  setTMresult(L, res, callTM(L, tm, l_s("oo"), p1, p2));
  return 1;
}


static void call_arith (lua_State *L, StkId p1, TObject *p2,
                        StkId res, TMS event) {
  if (!call_binTM(L, p1, p2, res, event))
    luaG_aritherror(L, p1, p2);
}


static int luaV_strlessthan (const TString *ls, const TString *rs) {
  const l_char *l = getstr(ls);
  size_t ll = ls->tsv.len;
  const l_char *r = getstr(rs);
  size_t lr = rs->tsv.len;
  for (;;) {
    int temp = strcoll(l, r);
    if (temp != 0) return (temp < 0);
    else {  /* strings are equal up to a `\0' */
      size_t len = strlen(l);  /* index of first `\0' in both strings */
      if (len == lr)  /* r is finished? */
        return 0;  /* l is equal or greater than r */
      else if (len == ll)  /* l is finished? */
        return 1;  /* l is smaller than r (because r is not finished) */
      /* both strings longer than `len'; go on comparing (after the `\0') */
      len++;
      l += len; ll -= len; r += len; lr -= len;
    }
  }
}


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 {  /* try TM */
    if (!call_binTM(L, l, r, L->top, TM_LT))
      luaG_ordererror(L, l, r);
    return (ttype(L->top) != LUA_TNIL);
  }
}


void luaV_strconc (lua_State *L, int total, StkId top) {
  luaV_checkGC(L, 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-2, top-1, top-2, TM_CONCAT))
        luaG_concaterror(L, top-2, top-1);
    } else if (tsvalue(top-1)->tsv.len > 0) {  /* if len=0, do nothing */
      /* at least two string values; get as many as possible */
      lu_mem tl = (lu_mem)tsvalue(top-1)->tsv.len +
                  (lu_mem)tsvalue(top-2)->tsv.len;
      l_char *buffer;
      int i;
      while (n < total && !tostring(L, top-n-1)) {  /* collect total length */
        tl += tsvalue(top-n-1)->tsv.len;
        n++;
      }
      if (tl > MAX_SIZET) luaD_error(L, l_s("string size overflow"));
      buffer = luaO_openspace(L, tl, l_char);
      tl = 0;
      for (i=n; i>0; i--) {  /* concat all strings */
        size_t l = tsvalue(top-i)->tsv.len;
        memcpy(buffer+tl, svalue(top-i), l);
        tl += l;
      }
      setsvalue(top-n, luaS_newlstr(L, buffer, tl));
    }
    total -= n-1;  /* got `n' strings to create 1 new */
    top -= n-1;
  } while (total > 1);  /* repeat until only 1 result left */
}


static void luaV_pack (lua_State *L, StkId firstelem) {
  int i;
  Hash *htab = luaH_new(L, 0);
  TObject *n;
  for (i=0; firstelem+i<L->top; i++)
    setobj(luaH_setnum(L, htab, i+1), firstelem+i);
  /* store counter in field `n' */
  n = luaH_setstr(L, htab, luaS_newliteral(L, l_s("n")));
  setnvalue(n, i);
  L->top = firstelem;  /* remove elements from the stack */
  sethvalue(L->top, htab);
  incr_top;
}


static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
  int nvararg = (L->top-base) - nfixargs;
  StkId firstvar = base + nfixargs;  /* position of first vararg */
  if (nvararg < 0) {
    luaD_checkstack(L, -nvararg);
    luaD_adjusttop(L, firstvar);
  }
  luaV_pack(L, firstvar);
}



/*
** some macros for common tasks in `luaV_execute'
*/

#define runtime_check(L, c)	{ if (!(c)) return L->top; }

#define RA(i)	(base+GETARG_A(i))
#define RB(i)	(base+GETARG_B(i))
#define RC(i)	(base+GETARG_C(i))
#define RKC(i)	((GETARG_C(i) < MAXSTACK) ? \
			base+GETARG_C(i) : \
			tf->k+GETARG_C(i)-MAXSTACK)
#define KBc(i)	(tf->k+GETARG_Bc(i))

#define Arith(op, optm)	{ \
  const TObject *b = RB(i); const TObject *c = RKC(i);		\
  TObject tempb, tempc; \
  if ((ttype(b) == LUA_TNUMBER || (b = luaV_tonumber(b, &tempb)) != NULL) && \
      (ttype(c) == LUA_TNUMBER || (c = luaV_tonumber(c, &tempc)) != NULL)) { \
    setnvalue(ra, nvalue(b) op nvalue(c));		\
  } else		\
    call_arith(L, RB(i), RKC(i), ra, optm); \
}


#define dojump(pc, i)	((pc) += GETARG_sBc(i))

/*
** Executes the given Lua function. Parameters are between [base,top).
** Returns n such that the the results are between [n,top).
*/
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
  const Proto *const tf = cl->f.l;
  const Instruction *pc;
  lua_Hook linehook;
  if (tf->is_vararg)  /* varargs? */
    adjust_varargs(L, base, tf->numparams);
  if (base > L->stack_last - tf->maxstacksize)
    luaD_stackerror(L);
  luaD_adjusttop(L, base + tf->maxstacksize);
  pc = tf->code;
  L->ci->pc = &pc;
  linehook = L->linehook;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    const StkId ra = RA(i);
    if (linehook)
      traceexec(L, linehook);
    switch (GET_OPCODE(i)) {
      case OP_MOVE: {
        setobj(ra, RB(i));
        break;
      }
      case OP_LOADK: {
        setobj(ra, KBc(i));
        break;
      }
      case OP_LOADINT: {
        setnvalue(ra, (lua_Number)GETARG_sBc(i));
        break;
      }
      case OP_LOADUPVAL: {
        setobj(ra, cl->upvalue+GETARG_Bc(i));
        break;
      }
      case OP_LOADNIL: {
        TObject *rb = RB(i);
        do {
          setnilvalue(rb--);
        } while (rb >= ra);
        break;
      }
      case OP_GETGLOBAL: {
        lua_assert(ttype(KBc(i)) == LUA_TSTRING);
        luaV_getglobal(L, tsvalue(KBc(i)), ra);
        break;
      }
      case OP_GETTABLE: {
        luaV_gettable(L, RB(i), RKC(i), ra);
        break;
      }
      case OP_SETGLOBAL: {
        lua_assert(ttype(KBc(i)) == LUA_TSTRING);
        luaV_setglobal(L, tsvalue(KBc(i)), ra);
        break;
      }
      case OP_SETTABLE: {
        luaV_settable(L, RB(i), RKC(i), ra);
        break;
      }
      case OP_NEWTABLE: {
        sethvalue(ra, luaH_new(L, GETARG_Bc(i)));
        luaV_checkGC(L, ra+1);
        break;
      }
      case OP_SELF: {
        StkId rb = RB(i);
        setobj(ra+1, rb);
        luaV_gettable(L, rb, RKC(i), ra);
        break;
      }
      case OP_ADD: {
        Arith( + , TM_ADD);
        break;
      }
      case OP_SUB: {
        Arith( - , TM_SUB);
        break;
      }
      case OP_MUL: {
        Arith( * , TM_MUL);
        break;
      }
      case OP_DIV: {
        Arith( / , TM_DIV);
        break;
      }
      case OP_POW: {
        call_arith(L, RB(i), RKC(i), ra, TM_POW);
        break;
      }
      case OP_UNM: {
        const TObject *rb = RB(i);
        if (ttype(rb) == LUA_TNUMBER || (rb=luaV_tonumber(rb, ra)) != NULL) {
          setnvalue(ra, -nvalue(rb));
        }
        else {
          TObject temp;
          setnilvalue(&temp);
          call_arith(L, RB(i), &temp, ra, TM_UNM);
        }
        break;
      }
      case OP_NOT: {
        if (ttype(RB(i)) == LUA_TNIL) {
          setnvalue(ra, 1);
        } else {
          setnilvalue(ra);
        }
        break;
      }
      case OP_CONCAT: {
        StkId top = RC(i)+1;
        StkId rb = RB(i);
        luaV_strconc(L, top-rb, top);
        setobj(ra, rb);
        break;
      }
      case OP_CJMP:
      case OP_JMP: {
        dojump(pc, i);
        break;
      }
      case OP_TESTEQ: {
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (luaO_equalObj(ra, RKC(i))) dojump(pc, *pc);
        pc++;
        break;
      }
      case OP_TESTNE: {
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (!luaO_equalObj(ra, RKC(i))) dojump(pc, *pc);
        pc++;
        break;
      }
      case OP_TESTLT: {
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc);
        pc++;
        break;
      }
      case OP_TESTLE: {  /* b <= c  ===  !(c<b) */
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (!luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc);
        pc++;
        break;
      }
      case OP_TESTGT: {  /* b > c  ===  (c<b) */
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc);
        pc++;
        break;
      }
      case OP_TESTGE: {  /* b >= c  === !(b<c) */
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (!luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc);
        pc++;
        break;
      }
      case OP_TESTT: {
        StkId rb = RB(i);
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (ttype(rb) != LUA_TNIL) {
          setobj(ra, rb);
          dojump(pc, *pc);
        }
        pc++;
        break;
      }
      case OP_TESTF: {
        lua_assert(GET_OPCODE(*pc) == OP_CJMP);
        if (ttype(RB(i)) == LUA_TNIL) {
          setnilvalue(ra);
          dojump(pc, *pc);
        }
        pc++;
        break;
      }
      case OP_NILJMP: {
        setnilvalue(ra);
        pc++;
        break;
      }
      case OP_CALL: {
        int c;
        int b = GETARG_B(i);
        if (b != NO_REG)
          L->top = ra+b+1;
        luaD_call(L, ra);
        c = GETARG_C(i);
        if (c != NO_REG) {
          while (L->top < ra+c) setnilvalue(L->top++);
          L->top = base + tf->maxstacksize;
        }
        break;
      }
      case OP_RETURN: {
        int b = GETARG_B(i);
        if (b != NO_REG)
          L->top = ra+b;
        return ra;
      }
      case OP_FORPREP: {
        if (luaV_tonumber(ra, ra) == NULL)
          luaD_error(L, l_s("`for' initial value must be a number"));
        if (luaV_tonumber(ra+1, ra+1) == NULL)
          luaD_error(L, l_s("`for' limit must be a number"));
        if (luaV_tonumber(ra+2, ra+2) == NULL)
          luaD_error(L, l_s("`for' step must be a number"));
        /* decrement index (to be incremented) */
        chgnvalue(ra, nvalue(ra) - nvalue(ra+2));
        pc += -GETARG_sBc(i);  /* `jump' to loop end (delta is negated here) */
        /* store in `ra+1' total number of repetitions */
        chgnvalue(ra+1, (nvalue(ra+1)-nvalue(ra))/nvalue(ra+2));
        /* go through */
      }
      case OP_FORLOOP: {
        runtime_check(L, ttype(ra+1) == LUA_TNUMBER &&
                         ttype(ra+2) == LUA_TNUMBER);
        if (ttype(ra) != LUA_TNUMBER)
          luaD_error(L, l_s("`for' index must be a number"));
        chgnvalue(ra+1, nvalue(ra+1) - 1);  /* decrement counter */
        if (nvalue(ra+1) >= 0) {
          chgnvalue(ra, nvalue(ra) + nvalue(ra+2));  /* increment index */
          dojump(pc, i);  /* repeat loop */
        }
        break;
      }
      case OP_TFORPREP: {
        if (ttype(ra) != LUA_TTABLE)
          luaD_error(L, l_s("`for' table must be a table"));
        setnvalue(ra+1, -1);  /* initial index */
        setnilvalue(ra+2);
        setnilvalue(ra+3);
        pc += -GETARG_sBc(i);  /* `jump' to loop end (delta is negated here) */
        /* go through */
      }
      case OP_TFORLOOP: {
        Hash *t;
        int n;
        runtime_check(L, ttype(ra) == LUA_TTABLE &&
                         ttype(ra+1) == LUA_TNUMBER);
        t = hvalue(ra);
        n = (int)nvalue(ra+1);
        n = luaH_nexti(t, n);
        if (n != -1) {  /* repeat loop? */
          Node *node = node(t, n);
          setnvalue(ra+1, n);  /* index */
          setobj(ra+2, key(node));
          setobj(ra+3, val(node));
          dojump(pc, i);  /* repeat loop */
        }
        break;
      }
      case OP_SETLIST:
      case OP_SETLISTO: {
        int bc;
        int n;
        Hash *h;
        runtime_check(L, ttype(ra) == LUA_TTABLE);
        h = hvalue(ra);
        bc = GETARG_Bc(i);
        if (GET_OPCODE(i) == OP_SETLIST)
          n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
        else
          n = L->top - ra - 1;
        bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
        for (; n > 0; n--)
          setobj(luaH_setnum(L, h, bc+n), ra+n);
        break;
      }
      case OP_CLOSURE: {
        Proto *p = tf->p[GETARG_Bc(i)];
        int nup = p->nupvalues;
        luaV_checkGC(L, ra+nup);
        L->top = ra+nup;
        luaV_Lclosure(L, p, nup);
        L->top = base + tf->maxstacksize;
        break;
      }
    }
  }
}

