/*
** $Id: lcode.c,v 1.27 2000/04/17 14:05:34 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/


#include "stdlib.h"

#define LUA_REENTRANT

#include "lcode.h"
#include "ldo.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstring.h"


void luaK_error (LexState *ls, const char *msg) {
  luaX_error(ls, msg, ls->token);
}


/*
** Returns the the previous instruction, for optimizations.
** If there is a jump target between this and the current instruction,
** returns a dummy instruction to avoid wrong optimizations.
*/
static Instruction previous_instruction (FuncState *fs) {
  if (fs->pc > fs->lasttarget)  /* no jumps to current position? */
    return fs->f->code[fs->pc-1];  /* returns previous instruction */
  else
    return CREATE_0(OP_END);  /* no optimizations after an `END' */
}


int luaK_jump (FuncState *fs) {
  int j = luaK_code0(fs, OP_JMP);
  if (j == fs->lasttarget) {  /* possible jumps to this jump? */
    luaK_concat(fs, &j, fs->jlt);  /* keep them on hold */
    fs->jlt = NO_JUMP;
  }
  return j;
}


static void luaK_fixjump (FuncState *fs, int pc, int dest) {
  Instruction *jmp = &fs->f->code[pc];
  if (dest == NO_JUMP)
    SETARG_S(*jmp, NO_JUMP);  /* point to itself to represent end of list */
  else {  /* jump is relative to position following jump instruction */
    int offset = dest-(pc+1);
    if (abs(offset) > MAXARG_S)
      luaK_error(fs->ls, "control structure too long");
    SETARG_S(*jmp, offset);
  }
}


static int luaK_getjump (FuncState *fs, int pc) {
  int offset = GETARG_S(fs->f->code[pc]);
  if (offset == NO_JUMP)  /* point to itself represents end of list */
    return NO_JUMP;  /* end of list */
  else
    return (pc+1)+offset;  /* turn offset into absolute position */
}


/*
** discharge list of jumps to last target.
** returns current `pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
*/
int luaK_getlabel (FuncState *fs) {
  if (fs->pc != fs->lasttarget) {
    int lasttarget = fs->lasttarget;
    fs->lasttarget = fs->pc;
    luaK_patchlist(fs, fs->jlt, lasttarget);  /* discharge old list `jlt' */
    fs->jlt = NO_JUMP;  /* nobody jumps to this new label (till now) */
  }
  return fs->pc;
}


void luaK_deltastack (FuncState *fs, int delta) {
  fs->stacklevel += delta;
  if (delta > 0 && fs->stacklevel > fs->f->maxstacksize) {
    if (fs->stacklevel > MAXSTACK)
      luaK_error(fs->ls, "function or expression too complex");
    fs->f->maxstacksize = fs->stacklevel;
  }
}


void luaK_kstr (LexState *ls, int c) {
  luaK_code1(ls->fs, OP_PUSHSTRING, c);
}


static int real_constant (FuncState *fs, Number r) {
  /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
  Proto *f = fs->f;
  int c = f->nknum;
  int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
  while (--c >= lim)
    if (f->knum[c] == r) return c;
  /* not found; create a new entry */
  luaM_growvector(fs->L, f->knum, f->nknum, 1, Number, constantEM, MAXARG_U);
  c = f->nknum++;
  f->knum[c] = r;
  return c;
}


void luaK_number (FuncState *fs, Number f) {
  if (f <= (Number)MAXARG_S && (int)f == f)
    luaK_code1(fs, OP_PUSHINT, (int)f);  /* f has a short integer value */
  else
    luaK_code1(fs, OP_PUSHNUM, real_constant(fs, f));
}


void luaK_adjuststack (FuncState *fs, int n) {
  if (n > 0)
    luaK_code1(fs, OP_POP, n);
  else if (n < 0)
    luaK_code1(fs, OP_PUSHNIL, -n);
}


int luaK_lastisopen (FuncState *fs) {
  /* check whether last instruction is an open function call */
  Instruction i = previous_instruction(fs);
  if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)
    return 1;
  else return 0;
}


void luaK_setcallreturns (FuncState *fs, int nresults) {
  if (luaK_lastisopen(fs)) {  /* expression is an open function call? */
    SETARG_B(fs->f->code[fs->pc-1], nresults);  /* set number of results */
    luaK_deltastack(fs, nresults);  /* push results */
  }
}


static void assertglobal (FuncState *fs, int index) {
  luaS_assertglobal(fs->L, fs->f->kstr[index]);
}


static int discharge (FuncState *fs, expdesc *var) {
  switch (var->k) {
    case VLOCAL:
      luaK_code1(fs, OP_GETLOCAL, var->u.index);
      break;
    case VGLOBAL:
      luaK_code1(fs, OP_GETGLOBAL, var->u.index);
      assertglobal(fs, var->u.index);  /* make sure that there is a global */
      break;
    case VINDEXED:
      luaK_code0(fs, OP_GETTABLE);
      break;
    case VEXP:
      return 0;  /* nothing to do */
  }
  var->k = VEXP;
  var->u.l.t = var->u.l.f = NO_JUMP;
  return 1;
}


static void discharge1 (FuncState *fs, expdesc *var) {
  discharge(fs, var);
 /* if it has jumps it is already discharged */
  if (var->u.l.t == NO_JUMP && var->u.l.f  == NO_JUMP)
    luaK_setcallreturns(fs, 1);  /* call must return 1 value */
}


void luaK_storevar (LexState *ls, const expdesc *var) {
  FuncState *fs = ls->fs;
  switch (var->k) {
    case VLOCAL:
      luaK_code1(fs, OP_SETLOCAL, var->u.index);
      break;
    case VGLOBAL:
      luaK_code1(fs, OP_SETGLOBAL, var->u.index);
      assertglobal(fs, var->u.index);  /* make sure that there is a global */
      break;
    case VINDEXED:  /* table is at top-3; pop 3 elements after operation */
      luaK_code2(fs, OP_SETTABLE, 3, 3);
      break;
    default:
      LUA_INTERNALERROR(ls->L, "invalid var kind to store");
  }
}


static OpCode invertjump (OpCode op) {
  switch (op) {
    case OP_JMPNE: return OP_JMPEQ;
    case OP_JMPEQ: return OP_JMPNE;
    case OP_JMPLT: return OP_JMPGE;
    case OP_JMPLE: return OP_JMPGT;
    case OP_JMPGT: return OP_JMPLE;
    case OP_JMPGE: return OP_JMPLT;
    case OP_JMPT: case OP_JMPONT:  return OP_JMPF;
    case OP_JMPF: case OP_JMPONF:  return OP_JMPT;
    default:
      LUA_INTERNALERROR(NULL, "invalid jump instruction");
      return OP_END;  /* to avoid warnings */
  }
}


static void luaK_patchlistaux (FuncState *fs, int list, int target,
                               OpCode special, int special_target) {
  Instruction *code = fs->f->code;
  while (list != NO_JUMP) {
    int next = luaK_getjump(fs, list);
    Instruction *i = &code[list];
    OpCode op = GET_OPCODE(*i);
    if (op == special)  /* this `op' already has a value */
      luaK_fixjump(fs, list, special_target);
    else {
      luaK_fixjump(fs, list, target);  /* do the patch */
      if (op == OP_JMPONT)  /* remove eventual values */
        SET_OPCODE(*i, OP_JMPT);
      else if (op == OP_JMPONF)
        SET_OPCODE(*i, OP_JMPF);
    }
    list = next;
  }
}


void luaK_patchlist (FuncState *fs, int list, int target) {
  if (target == fs->lasttarget)  /* same target that list `jlt'? */
    luaK_concat(fs, &fs->jlt, list);  /* delay fixing */
  else
    luaK_patchlistaux(fs, list, target, OP_END, 0);
}


static int need_value (FuncState *fs, int list, OpCode hasvalue) {
  /* check whether list has a jump without a value */
  for (; list != NO_JUMP; list = luaK_getjump(fs, list))
    if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1;
  return 0;  /* not found */
}


void luaK_concat (FuncState *fs, int *l1, int l2) {
  if (*l1 == NO_JUMP)
    *l1 = l2;
  else {
    int list = *l1;
    for (;;) {  /* traverse `l1' */
      int next = luaK_getjump(fs, list);
      if (next == NO_JUMP) {  /* end of list? */
        luaK_fixjump(fs, list, l2);
        return;
      }
      list = next;
    }
  }
}


static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
  Instruction *previous;
  int *golist = &v->u.l.f;
  int *exitlist = &v->u.l.t;
  if (invert) {  /* interchange `golist' and `exitlist' */
    int *temp = golist; golist = exitlist; exitlist = temp;
  }
  discharge1(fs, v);
  previous = &fs->f->code[fs->pc-1];
  LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line");
  if (ISJUMP(GET_OPCODE(*previous))) {
    if (invert)
      SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
  }
  else
    luaK_code0(fs, jump);
  luaK_concat(fs, exitlist, fs->pc-1);  /* insert last jump in `exitlist' */
  luaK_patchlist(fs, *golist, luaK_getlabel(fs));
  *golist = NO_JUMP;
}


void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {
  luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);
}


void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
  luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);
}


static int code_label (FuncState *fs, OpCode op, int arg) {
  int j = luaK_getlabel(fs);
  luaK_code1(fs, op, arg);
  return j;
}


void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
  FuncState *fs = ls->fs;
  if (!discharge(fs, v)) {  /* `v' is an expression? */
    OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
    LUA_ASSERT(L, previous != OP_SETLINE, "bad place to set line");
    if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
      /* expression has no jumps */
      if (onlyone)
        luaK_setcallreturns(fs, 1);  /* call must return 1 value */
    }
    else {  /* expression has jumps */
      int final;  /* position after whole expression */
      int j = NO_JUMP;  /*  eventual  jump over values */
      int p_nil = NO_JUMP;  /* position of an eventual PUSHNIL */
      int p_1 = NO_JUMP;  /* position of an eventual PUSHINT */
      if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF) ||
                              need_value(fs, v->u.l.t, OP_JMPONT)) {
        /* expression needs values */
        if (ISJUMP(previous))
          luaK_concat(fs, &v->u.l.t, fs->pc-1);  /* put `previous' in t. list */
        else {
          j = code_label(fs, OP_JMP, 0);  /* to jump over both pushes */
          luaK_deltastack(fs, -1);  /* next PUSHes may be skipped */
        }
        p_nil = code_label(fs, OP_PUSHNILJMP, 0);
        p_1 = code_label(fs, OP_PUSHINT, 1);
        luaK_patchlist(fs, j, luaK_getlabel(fs));
      }
      final = luaK_getlabel(fs);
      luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final);
      luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final);
      v->u.l.f = v->u.l.t = NO_JUMP;
    }
  }
}


void luaK_prefix (LexState *ls, int op, expdesc *v) {
  FuncState *fs = ls->fs;
  if (op == '-') {
    luaK_tostack(ls, v, 1);
    luaK_code0(fs, OP_MINUS);
  }
  else {  /* op == NOT */
    Instruction *previous;
    discharge1(fs, v);
    previous = &fs->f->code[fs->pc-1];
    if (ISJUMP(GET_OPCODE(*previous)))
      SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
    else
      luaK_code0(fs, OP_NOT);
    /* interchange true and false lists */
    { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; }
  }
}


void luaK_infix (LexState *ls, int op, expdesc *v) {
  FuncState *fs = ls->fs;
  if (op == TK_AND)
    luaK_goiftrue(fs, v, 1);
  else if (op == TK_OR)
    luaK_goiffalse(fs, v, 1);
  else
    luaK_tostack(ls, v, 1);  /* all other binary operators need a value */
}


void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
  FuncState *fs = ls->fs;
  if (op == TK_AND) {
    LUA_ASSERT(ls->L, v1->u.l.t == NO_JUMP, "list must be closed");
    discharge1(fs, v2);
    v1->u.l.t = v2->u.l.t;
    luaK_concat(fs, &v1->u.l.f, v2->u.l.f);
  }
  else if (op == TK_OR) {
    LUA_ASSERT(ls->L, v1->u.l.f == NO_JUMP, "list must be closed");
    discharge1(fs, v2);
    v1->u.l.f = v2->u.l.f;
    luaK_concat(fs, &v1->u.l.t, v2->u.l.t);
  }
  else {
    luaK_tostack(ls, v2, 1);  /* `v2' must be a value */
    switch (op) {
      case '+': luaK_code0(fs, OP_ADD); break;
      case '-': luaK_code0(fs, OP_SUB); break;
      case '*': luaK_code0(fs, OP_MULT); break;
      case '/': luaK_code0(fs, OP_DIV); break;
      case '^': luaK_code0(fs, OP_POW); break;
      case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break;
      case TK_EQ: luaK_code0(fs, OP_JMPEQ); break;
      case TK_NE: luaK_code0(fs, OP_JMPNE); break;
      case '>': luaK_code0(fs, OP_JMPGT); break;
      case '<': luaK_code0(fs, OP_JMPLT); break;
      case TK_GE: luaK_code0(fs, OP_JMPGE); break;
      case TK_LE: luaK_code0(fs, OP_JMPLE); break;
    }
  }
}


int luaK_code0 (FuncState *fs, OpCode o) {
  return luaK_code2(fs, o, 0, 0);
}


int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
  return luaK_code2(fs, o, arg1, 0);
}



int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
  Instruction i = previous_instruction(fs);
  int delta = 0;
  enum {iO, iU, iS, iAB, iP} mode;  /* instruction format (or iP to optimize) */
  mode = iP;

  switch (o) {

    case OP_CLOSURE:
      delta = -arg2+1;
      mode = iAB;
      break;

    case OP_SETLINE:
      mode = iU;
      break;

    case OP_CALL:
      mode = iAB;
      break;

    case OP_PUSHINT:
      delta = 1;
      mode = iS;
      break;

    case OP_SETTABLE:
      delta = -arg2;
      mode = iAB;
      break;

    case OP_SETLIST:
      delta = -(arg2+1);
      mode = iAB;
      break;

    case OP_SETMAP:
      delta = -2*(arg1+1);
      mode = iU;
      break;

    case OP_FORLOOP:
      delta = -3;
      arg1 = NO_JUMP;
      mode = iS;
      break;

    case OP_SETLOCAL:
    case OP_SETGLOBAL:
      delta = -1;
      mode = iU;
      break;

    case OP_FORPREP:
    case OP_JMP:
      arg1 = NO_JUMP;
      mode = iS;
      break;

    case OP_END:
    case OP_PUSHNILJMP:
    case OP_NOT:
      mode = iO;
      break;

    case OP_PUSHSTRING:
    case OP_PUSHNUM:
    case OP_PUSHNEGNUM:
    case OP_PUSHUPVALUE:
    case OP_GETLOCAL:
    case OP_GETGLOBAL:
    case OP_PUSHSELF:
    case OP_CREATETABLE:
      delta = 1;
      mode = iU;
      break;

    case OP_JMPLT:
    case OP_JMPLE:
    case OP_JMPGT:
    case OP_JMPGE:
      delta = -2;
      arg1 = NO_JUMP;
      mode = iS;
      break;

    case OP_MULT:
    case OP_DIV:
    case OP_POW:
      delta = -1;
      mode = iO;
      break;

    case OP_RETURN:
      if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
        SET_OPCODE(i, OP_TAILCALL);
        SETARG_B(i, arg1);
      }
      else mode = iU;
      break;

    case OP_PUSHNIL:
      delta = arg1;
      switch(GET_OPCODE(i)) {
        case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); break;
        default: mode = iU; break;
      }
      break;

    case OP_POP:
      delta = -arg1;
      switch(GET_OPCODE(i)) {
        case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); break;
        default: mode = iU; break;
      }
      break;

    case OP_GETTABLE:
      delta = -1;
      switch(GET_OPCODE(i)) {
        case OP_PUSHSTRING: SET_OPCODE(i, OP_GETDOTTED); break;  /* `t.x' */
        case OP_GETLOCAL: SET_OPCODE(i, OP_GETINDEXED); break;  /* `t[i]' */
        default: mode = iO; break;
      }
      break;

    case OP_ADD:
      delta = -1;
      switch(GET_OPCODE(i)) {
        case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); break;  /* `a+k' */
        default: mode = iO; break;
      }
      break;

    case OP_SUB:
      delta = -1;
      switch(GET_OPCODE(i)) {
        case OP_PUSHINT: i = CREATE_S(OP_ADDI, -GETARG_S(i)); break; /* `a-k' */
        default: mode = iO; break;
      }
      break;

    case OP_CONCAT:
      delta = -arg1+1;
      switch(GET_OPCODE(i)) {
        case OP_CONCAT: SETARG_U(i, GETARG_U(i)+1); break;  /* `a..b..c' */
        default: mode = iU; break;
      }
      break;

    case OP_MINUS:
      switch(GET_OPCODE(i)) {
        case OP_PUSHINT: SETARG_S(i, -GETARG_S(i)); break;  /* `-k' */
        case OP_PUSHNUM: SET_OPCODE(i, OP_PUSHNEGNUM); break;  /* `-k' */
        default: mode = iO; break;
      }
      break;

    case OP_JMPNE:
      delta = -2;
      if (i == CREATE_U(OP_PUSHNIL, 1))  /* `a~=nil' */
        i = CREATE_S(OP_JMPT, NO_JUMP);
      else {
        arg1 = NO_JUMP;
        mode = iS;
      }
      break;

    case OP_JMPEQ:
      delta = -2;
      if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a==nil' */
        i = CREATE_0(OP_NOT);
        delta = -1;  /* just undo effect of previous PUSHNIL */
      }
      else {
        arg1 = NO_JUMP;
        mode = iS;
      }
      break;

    case OP_JMPT:
    case OP_JMPF:
    case OP_JMPONT:
    case OP_JMPONF:
      delta = -1;
      arg1 = NO_JUMP;
      switch (GET_OPCODE(i)) {
        case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); break;
        default: mode = iS; break;
      }
      break;

    case OP_GETDOTTED:
    case OP_GETINDEXED:
    case OP_TAILCALL:
    case OP_ADDI:
      LUA_INTERNALERROR(L, "instruction used only for optimizations");
      return 0;  /* to avoid warnings */

  }
  luaK_deltastack(fs, delta);
  switch (mode) {  /* handle instruction formats */
    case iO: i = CREATE_0(o); break;
    case iU: i = CREATE_U(o, arg1); break;
    case iS: i = CREATE_S(o, arg1); break;
    case iAB: i = CREATE_AB(o, arg1, arg2); break;
    case iP: {  /* optimize: put instruction in place of last one */
      fs->f->code[fs->pc-1] = i;  /* change previous instruction */
      return fs->pc-1;
    }
  }
  /* actually create the new instruction */
  luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT);
  fs->f->code[fs->pc] = i;
  return fs->pc++;
}

