/*
** $Id: lvm.c,v 1.54 1999/03/10 14:09:45 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/


#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "luadebug.h"
#include "lvm.h"


#ifdef OLD_ANSI
#define strcoll(a,b)	strcmp(a,b)
#endif


#define highbyte(x)	((x)<<8)


/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
#define	EXTRA_STACK	5



static TaggedString *strconc (TaggedString *l, TaggedString *r) {
  long nl = l->u.s.len;
  long nr = r->u.s.len;
  char *buffer = luaL_openspace(nl+nr);
  memcpy(buffer, l->str, nl);
  memcpy(buffer+nl, r->str, nr);
  return luaS_newlstr(buffer, nl+nr);
}


int luaV_tonumber (TObject *obj) {  /* LUA_NUMBER */
  if (ttype(obj) != LUA_T_STRING)
    return 1;
  else {
    double t;
    char *e = svalue(obj);
    int sig = 1;
    while (isspace((unsigned char)*e)) e++;
    if (*e == '-') {
      e++;
      sig = -1;
    }
    else if (*e == '+') e++;
    /* no digit before or after decimal point? */
    if (!isdigit((unsigned char)*e) && !isdigit((unsigned char)*(e+1)))
      return 2;
    t = luaO_str2d(e);
    if (t<0) return 2;
    nvalue(obj) = (real)t*sig;
    ttype(obj) = LUA_T_NUMBER;
    return 0;
  }
}


int luaV_tostring (TObject *obj) {  /* LUA_NUMBER */
  if (ttype(obj) != LUA_T_NUMBER)
    return 1;
  else {
    char s[32];  /* 16 digits, signal, point and \0  (+ some extra...) */
    sprintf(s, "%.16g", (double)nvalue(obj));
    tsvalue(obj) = luaS_new(s);
    ttype(obj) = LUA_T_STRING;
    return 0;
  }
}


void luaV_setn (Hash *t, int val) {
  TObject index, value;
  ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new("n");
  ttype(&value) = LUA_T_NUMBER; nvalue(&value) = val;
  luaH_set(t, &index, &value);
}


void luaV_closure (int nelems) {
  if (nelems > 0) {
    struct Stack *S = &L->stack;
    Closure *c = luaF_newclosure(nelems);
    c->consts[0] = *(S->top-1);
    memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
    S->top -= nelems;
    ttype(S->top-1) = LUA_T_CLOSURE;
    (S->top-1)->value.cl = c;
  }
}


/*
** Function to index a table.
** Receives the table at top-2 and the index at top-1.
*/
void luaV_gettable (void) {
  TObject *table = L->stack.top-2;
  TObject *im;
  if (ttype(table) != LUA_T_ARRAY) {  /* not a table, get gettable method */
    im = luaT_getimbyObj(table, IM_GETTABLE);
    if (ttype(im) == LUA_T_NIL)
      lua_error("indexed expression not a table");
  }
  else {  /* object is a table... */
    int tg = table->value.a->htag;
    im = luaT_getim(tg, IM_GETTABLE);
    if (ttype(im) == LUA_T_NIL) {  /* and does not have a "gettable" method */
      TObject *h = luaH_get(avalue(table), table+1);
      if (ttype(h) == LUA_T_NIL &&
          (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
        /* result is nil and there is an "index" tag method */
        luaD_callTM(im, 2, 1);  /* calls it */
      }
      else {
        L->stack.top--;
        *table = *h;  /* "push" result into table position */
      }
      return;
    }
    /* else it has a "gettable" method, go through to next command */
  }
  /* object is not a table, or it has a "gettable" method */
  luaD_callTM(im, 2, 1);
}


/*
** Receives table at *t, index at *(t+1) and value at top.
*/
void luaV_settable (TObject *t) {
  struct Stack *S = &L->stack;
  TObject *im;
  if (ttype(t) != LUA_T_ARRAY) {  /* not a table, get "settable" method */
    im = luaT_getimbyObj(t, IM_SETTABLE);
    if (ttype(im) == LUA_T_NIL)
      lua_error("indexed expression not a table");
  }
  else {  /* object is a table... */
    im = luaT_getim(avalue(t)->htag, IM_SETTABLE);
    if (ttype(im) == LUA_T_NIL) {  /* and does not have a "settable" method */
      luaH_set(avalue(t), t+1, S->top-1);
      S->top--;  /* pop value */
      return;
    }
    /* else it has a "settable" method, go through to next command */
  }
  /* object is not a table, or it has a "settable" method */
  /* prepare arguments and call the tag method */
  *(S->top+1) = *(L->stack.top-1);
  *(S->top) = *(t+1);
  *(S->top-1) = *t;
  S->top += 2;  /* WARNING: caller must assure stack space */
  luaD_callTM(im, 3, 0);
}


void luaV_rawsettable (TObject *t) {
  if (ttype(t) != LUA_T_ARRAY)
    lua_error("indexed expression not a table");
  else {
    struct Stack *S = &L->stack;
    luaH_set(avalue(t), t+1, S->top-1);
    S->top -= 3;
  }
}


void luaV_getglobal (TaggedString *ts) {
  /* WARNING: caller must assure stack space */
  /* only userdata, tables and nil can have getglobal tag methods */
  static char valid_getglobals[] = {1, 0, 0, 1, 0, 0, 1, 0};  /* ORDER LUA_T */
  TObject *value = &ts->u.s.globalval;
  if (valid_getglobals[-ttype(value)]) {
    TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
    if (ttype(im) != LUA_T_NIL) {  /* is there a tag method? */
      struct Stack *S = &L->stack;
      ttype(S->top) = LUA_T_STRING;
      tsvalue(S->top) = ts;
      S->top++;
      *S->top++ = *value;
      luaD_callTM(im, 2, 1);
      return;
    }
    /* else no tag method: go through to default behavior */
  }
  *L->stack.top++ = *value;  /* default behavior */
}


void luaV_setglobal (TaggedString *ts) {
  TObject *oldvalue = &ts->u.s.globalval;
  TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
  if (ttype(im) == LUA_T_NIL)  /* is there a tag method? */
    luaS_rawsetglobal(ts, --L->stack.top);
  else {
    /* WARNING: caller must assure stack space */
    struct Stack *S = &L->stack;
    TObject newvalue = *(S->top-1);
    ttype(S->top-1) = LUA_T_STRING;
    tsvalue(S->top-1) = ts;
    *S->top++ = *oldvalue;
    *S->top++ = newvalue;
    luaD_callTM(im, 3, 0);
  }
}


static void call_binTM (IMS event, char *msg)
{
  TObject *im = luaT_getimbyObj(L->stack.top-2, event);/* try first operand */
  if (ttype(im) == LUA_T_NIL) {
    im = luaT_getimbyObj(L->stack.top-1, event);  /* try second operand */
    if (ttype(im) == LUA_T_NIL) {
      im = luaT_getim(0, event);  /* try a 'global' i.m. */
      if (ttype(im) == LUA_T_NIL)
        lua_error(msg);
    }
  }
  lua_pushstring(luaT_eventname[event]);
  luaD_callTM(im, 3, 1);
}


static void call_arith (IMS event)
{
  call_binTM(event, "unexpected type in arithmetic operation");
}


static int luaV_strcomp (char *l, long ll, char *r, long lr)
{
  for (;;) {
    long temp = strcoll(l, r);
    if (temp != 0) return temp;
    /* strings are equal up to a '\0' */
    temp = strlen(l);  /* index of first '\0' in both strings */
    if (temp == ll)  /* l is finished? */
      return (temp == lr) ? 0 : -1;  /* l is equal or smaller than r */
    else if (temp == lr)  /* r is finished? */
      return 1;  /* l is greater than r (because l is not finished) */
    /* both strings longer than temp; go on comparing (after the '\0') */
    temp++;
    l += temp; ll -= temp; r += temp; lr -= temp;
  }
}

void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
                      lua_Type ttype_great, IMS op) {
  struct Stack *S = &L->stack;
  TObject *l = S->top-2;
  TObject *r = S->top-1;
  real result;
  if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
    result = nvalue(l)-nvalue(r);
  else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
    result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
                          svalue(r), tsvalue(r)->u.s.len);
  else {
    call_binTM(op, "unexpected type in comparison");
    return;
  }
  S->top--;
  nvalue(S->top-1) = 1;
  ttype(S->top-1) = (result < 0) ? ttype_less :
                                (result == 0) ? ttype_equal : ttype_great;
}


void luaV_pack (StkId firstel, int nvararg, TObject *tab) {
  TObject *firstelem = L->stack.stack+firstel;
  int i;
  Hash *htab;
  if (nvararg < 0) nvararg = 0;
  htab = avalue(tab) = luaH_new(nvararg+1);  /* +1 for field 'n' */
  ttype(tab) = LUA_T_ARRAY;
  for (i=0; i<nvararg; i++)
    luaH_setint(htab, i+1, firstelem+i);
  luaV_setn(htab, nvararg);  /* store counter in field "n" */
}


static void adjust_varargs (StkId first_extra_arg)
{
  TObject arg;
  luaV_pack(first_extra_arg,
       (L->stack.top-L->stack.stack)-first_extra_arg, &arg);
  luaD_adjusttop(first_extra_arg);
  *L->stack.top++ = arg;
}



/*
** Execute the given opcode, until a RET. Parameters are between
** [stack+base,top). Returns n such that the the results are between
** [stack+n,top).
*/
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
  struct Stack *S = &L->stack;  /* to optimize */
  register Byte *pc = tf->code;
  TObject *consts = tf->consts;
  if (L->callhook)
    luaD_callHook(base, tf, 0);
  luaD_checkstack((*pc++)+EXTRA_STACK);
  if (*pc < ZEROVARARG)
    luaD_adjusttop(base+*(pc++));
  else {  /* varargs */
    luaC_checkGC();
    adjust_varargs(base+(*pc++)-ZEROVARARG);
  }
  for (;;) {
    register int aux = 0;
    switchentry:
    switch ((OpCode)*pc++) {

      case ENDCODE:
        S->top = S->stack + base;
        goto ret;
        
      case RETCODE:
        base += *pc++;
        goto ret;

      case CALL: aux = *pc++;
        luaD_call((S->top-S->stack)-(*pc++), aux);
        break;

      case TAILCALL: aux = *pc++;
        luaD_call((S->top-S->stack)-(*pc++), MULT_RET);
        base += aux;
        goto ret;

      case PUSHNIL: aux = *pc++;
        do {
          ttype(S->top++) = LUA_T_NIL;
        } while (aux--);
        break;

      case POP: aux = *pc++;
        S->top -= aux;
        break;

      case PUSHNUMBERW: aux += highbyte(*pc++);
      case PUSHNUMBER:  aux += *pc++;
        ttype(S->top) = LUA_T_NUMBER;
        nvalue(S->top) = aux;
        S->top++;
        break;

      case PUSHNUMBERNEGW: aux += highbyte(*pc++);
      case PUSHNUMBERNEG:  aux += *pc++;
        ttype(S->top) = LUA_T_NUMBER;
        nvalue(S->top) = -aux;
        S->top++;
        break;

      case PUSHCONSTANTW: aux += highbyte(*pc++);
      case PUSHCONSTANT:  aux += *pc++;
        *S->top++ = consts[aux];
        break;

      case PUSHUPVALUE: aux = *pc++;
        *S->top++ = cl->consts[aux+1];
        break;

      case PUSHLOCAL: aux = *pc++;
        *S->top++ = *((S->stack+base) + aux);
        break;

      case GETGLOBALW: aux += highbyte(*pc++);
      case GETGLOBAL:  aux += *pc++;
        luaV_getglobal(tsvalue(&consts[aux]));
        break;

      case GETTABLE:
        luaV_gettable();
        break;

      case GETDOTTEDW: aux += highbyte(*pc++);
      case GETDOTTED:  aux += *pc++;
        *S->top++ = consts[aux];
        luaV_gettable();
        break;

      case PUSHSELFW: aux += highbyte(*pc++);
      case PUSHSELF:  aux += *pc++; {
        TObject receiver = *(S->top-1);
        *S->top++ = consts[aux];
        luaV_gettable();
        *S->top++ = receiver;
        break;
      }

      case CREATEARRAYW: aux += highbyte(*pc++);
      case CREATEARRAY:  aux += *pc++;
        luaC_checkGC();
        avalue(S->top) = luaH_new(aux);
        ttype(S->top) = LUA_T_ARRAY;
        S->top++;
        break;

      case SETLOCAL: aux = *pc++;
        *((S->stack+base) + aux) = *(--S->top);
        break;

      case SETGLOBALW: aux += highbyte(*pc++);
      case SETGLOBAL:  aux += *pc++;
        luaV_setglobal(tsvalue(&consts[aux]));
        break;

      case SETTABLEPOP:
        luaV_settable(S->top-3);
        S->top -= 2;  /* pop table and index */
        break;

      case SETTABLE:
        luaV_settable(S->top-3-(*pc++));
        break;

      case SETLISTW: aux += highbyte(*pc++);
      case SETLIST:  aux += *pc++; {
        int n = *(pc++);
        TObject *arr = S->top-n-1;
        aux *= LFIELDS_PER_FLUSH;
        for (; n; n--)
          luaH_setint(avalue(arr), n+aux, --S->top);
        break;
      }

      case SETMAP:  aux = *pc++; {
        TObject *arr = S->top-(2*aux)-3;
        do {
          luaH_set(avalue(arr), S->top-2, S->top-1);
          S->top-=2;
        } while (aux--);
        break;
      }

      case NEQOP: aux = 1;
      case EQOP: {
        int res = luaO_equalObj(S->top-2, S->top-1);
        if (aux) res = !res;
        S->top--;
        ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
        nvalue(S->top-1) = 1;
        break;
      }

       case LTOP:
         luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
         break;

      case LEOP:
        luaV_comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
        break;

      case GTOP:
        luaV_comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
        break;

      case GEOP:
        luaV_comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
        break;

      case ADDOP: {
        TObject *l = S->top-2;
        TObject *r = S->top-1;
        if (tonumber(r) || tonumber(l))
          call_arith(IM_ADD);
        else {
          nvalue(l) += nvalue(r);
          --S->top;
        }
        break;
      }

      case SUBOP: {
        TObject *l = S->top-2;
        TObject *r = S->top-1;
        if (tonumber(r) || tonumber(l))
          call_arith(IM_SUB);
        else {
          nvalue(l) -= nvalue(r);
          --S->top;
        }
        break;
      }

      case MULTOP: {
        TObject *l = S->top-2;
        TObject *r = S->top-1;
        if (tonumber(r) || tonumber(l))
          call_arith(IM_MUL);
        else {
          nvalue(l) *= nvalue(r);
          --S->top;
        }
        break;
      }

      case DIVOP: {
        TObject *l = S->top-2;
        TObject *r = S->top-1;
        if (tonumber(r) || tonumber(l))
          call_arith(IM_DIV);
        else {
          nvalue(l) /= nvalue(r);
          --S->top;
        }
        break;
      }

      case POWOP:
        call_binTM(IM_POW, "undefined operation");
        break;

      case CONCOP: {
        TObject *l = S->top-2;
        TObject *r = S->top-1;
        if (tostring(l) || tostring(r))
          call_binTM(IM_CONCAT, "unexpected type for concatenation");
        else {
          tsvalue(l) = strconc(tsvalue(l), tsvalue(r));
          --S->top;
        }
        luaC_checkGC();
        break;
      }

      case MINUSOP:
        if (tonumber(S->top-1)) {
          ttype(S->top) = LUA_T_NIL;
          S->top++;
          call_arith(IM_UNM);
        }
        else
          nvalue(S->top-1) = - nvalue(S->top-1);
        break;

      case NOTOP:
        ttype(S->top-1) =
           (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
        nvalue(S->top-1) = 1;
        break;

      case ONTJMPW: aux += highbyte(*pc++);
      case ONTJMP:  aux += *pc++;
        if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
        else S->top--;
        break;

      case ONFJMPW: aux += highbyte(*pc++);
      case ONFJMP:  aux += *pc++;
        if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
        else S->top--;
        break;

      case JMPW: aux += highbyte(*pc++);
      case JMP:  aux += *pc++;
        pc += aux;
        break;

      case IFFJMPW: aux += highbyte(*pc++);
      case IFFJMP:  aux += *pc++;
        if (ttype(--S->top) == LUA_T_NIL) pc += aux;
        break;

      case IFTUPJMPW: aux += highbyte(*pc++);
      case IFTUPJMP:  aux += *pc++;
        if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
        break;

      case IFFUPJMPW: aux += highbyte(*pc++);
      case IFFUPJMP:  aux += *pc++;
        if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
        break;

      case CLOSUREW: aux += highbyte(*pc++);
      case CLOSURE:  aux += *pc++;
        *S->top++ = consts[aux];
        luaV_closure(*pc++);
        luaC_checkGC();
        break;

      case SETLINEW: aux += highbyte(*pc++);
      case SETLINE:  aux += *pc++;
        if ((S->stack+base-1)->ttype != LUA_T_LINE) {
          /* open space for LINE value */
          luaD_openstack((S->top-S->stack)-base);
          base++;
          (S->stack+base-1)->ttype = LUA_T_LINE;
        }
        (S->stack+base-1)->value.i = aux;
        if (L->linehook)
          luaD_lineHook(aux);
        break;

      case LONGARGW: aux += highbyte(*pc++);
      case LONGARG:  aux += *pc++;
        aux = highbyte(highbyte(aux));
        goto switchentry;  /* do not reset "aux" */

      case CHECKSTACK: aux = *pc++;
        LUA_ASSERT((S->top-S->stack)-base == aux, "wrong stack size");
        break;

    }
  } ret:
  if (L->callhook)
    luaD_callHook(0, NULL, 1);
  return base;
}

