⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcode.c

📁 MTK上实现虚拟机的一种有效方案
💻 C
📖 第 1 页 / 共 2 页
字号:
  exp2reg(fs, e, fs->freereg - 1);}int luaK_exp2anyreg (FuncState *fs, expdesc *e) {  luaK_dischargevars(fs, e);  if (e->k == VNONRELOC) {    if (!hasjumps(e)) return e->u.s.info;  /* exp is already in a register */    if (e->u.s.info >= fs->nactvar) {  /* reg. is not a local? */      exp2reg(fs, e, e->u.s.info);  /* put value on it */      return e->u.s.info;    }  }  luaK_exp2nextreg(fs, e);  /* default */  return e->u.s.info;}void luaK_exp2val (FuncState *fs, expdesc *e) {  if (hasjumps(e))    luaK_exp2anyreg(fs, e);  else    luaK_dischargevars(fs, e);}int luaK_exp2RK (FuncState *fs, expdesc *e) {  luaK_exp2val(fs, e);  switch (e->k) {    case VKNUM:    case VTRUE:    case VFALSE:    case VNIL: {      if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */        e->u.s.info = (e->k == VNIL)  ? nilK(fs) :                      (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :                                        boolK(fs, (e->k == VTRUE));        e->k = VK;        return RKASK(e->u.s.info);      }      else break;    }    case VK: {      if (e->u.s.info <= MAXINDEXRK)  /* constant fit in argC? */        return RKASK(e->u.s.info);      else break;    }    default: break;  }  /* not a constant in the right range: put it in a register */  return luaK_exp2anyreg(fs, e);}void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {  switch (var->k) {    case VLOCAL: {      freeexp(fs, ex);      exp2reg(fs, ex, var->u.s.info);      return;    }    case VUPVAL: {      int e = luaK_exp2anyreg(fs, ex);      luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);      break;    }    case VGLOBAL: {      int e = luaK_exp2anyreg(fs, ex);      luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);      break;    }    case VINDEXED: {      int e = luaK_exp2RK(fs, ex);      luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);      break;    }    default: {      lua_assert(0);  /* invalid var kind to store */      break;    }  }  freeexp(fs, ex);}void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {  int func;  luaK_exp2anyreg(fs, e);  freeexp(fs, e);  func = fs->freereg;  luaK_reserveregs(fs, 2);  luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));  freeexp(fs, key);  e->u.s.info = func;  e->k = VNONRELOC;}static void invertjump (FuncState *fs, expdesc *e) {  Instruction *pc = getjumpcontrol(fs, e->u.s.info);  lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&                                           GET_OPCODE(*pc) != OP_TEST);  SETARG_A(*pc, !(GETARG_A(*pc)));}static int jumponcond (FuncState *fs, expdesc *e, int cond) {  if (e->k == VRELOCABLE) {    Instruction ie = getcode(fs, e);    if (GET_OPCODE(ie) == OP_NOT) {      fs->pc--;  /* remove previous OP_NOT */      return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);    }    /* else go through */  }  discharge2anyreg(fs, e);  freeexp(fs, e);  return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);}void luaK_goiftrue (FuncState *fs, expdesc *e) {  int pc;  /* pc of last jump */  luaK_dischargevars(fs, e);  switch (e->k) {    case VK: case VKNUM: case VTRUE: {      pc = NO_JUMP;  /* always true; do nothing */      break;    }    case VFALSE: {      pc = luaK_jump(fs);  /* always jump */      break;    }    case VJMP: {      invertjump(fs, e);      pc = e->u.s.info;      break;    }    default: {      pc = jumponcond(fs, e, 0);      break;    }  }  luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */  luaK_patchtohere(fs, e->t);  e->t = NO_JUMP;}static void luaK_goiffalse (FuncState *fs, expdesc *e) {  int pc;  /* pc of last jump */  luaK_dischargevars(fs, e);  switch (e->k) {    case VNIL: case VFALSE: {      pc = NO_JUMP;  /* always false; do nothing */      break;    }    case VTRUE: {      pc = luaK_jump(fs);  /* always jump */      break;    }    case VJMP: {      pc = e->u.s.info;      break;    }    default: {      pc = jumponcond(fs, e, 1);      break;    }  }  luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */  luaK_patchtohere(fs, e->f);  e->f = NO_JUMP;}static void codenot (FuncState *fs, expdesc *e) {  luaK_dischargevars(fs, e);  switch (e->k) {    case VNIL: case VFALSE: {      e->k = VTRUE;      break;    }    case VK: case VKNUM: case VTRUE: {      e->k = VFALSE;      break;    }    case VJMP: {      invertjump(fs, e);      break;    }    case VRELOCABLE:    case VNONRELOC: {      discharge2anyreg(fs, e);      freeexp(fs, e);      e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);      e->k = VRELOCABLE;      break;    }    default: {      lua_assert(0);  /* cannot happen */      break;    }  }  /* interchange true and false lists */  { int temp = e->f; e->f = e->t; e->t = temp; }  removevalues(fs, e->f);  removevalues(fs, e->t);}void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {  t->u.s.aux = luaK_exp2RK(fs, k);  t->k = VINDEXED;}static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {  lua_Number v1, v2, r;  if (!isnumeral(e1) || !isnumeral(e2)) return 0;  v1 = e1->u.nval;  v2 = e2->u.nval;  switch (op) {    case OP_ADD: r = luai_numadd(v1, v2); break;    case OP_SUB: r = luai_numsub(v1, v2); break;    case OP_MUL: r = luai_nummul(v1, v2); break;    case OP_DIV:      if (v2 == 0) return 0;  /* do not attempt to divide by 0 */      r = luai_numdiv(v1, v2); break;    case OP_MOD:      if (v2 == 0) return 0;  /* do not attempt to divide by 0 */      r = luai_nummod(v1, v2); break;    case OP_POW: r = luai_numpow(v1, v2); break;    case OP_UNM: r = luai_numunm(v1); break;    case OP_LEN: return 0;  /* no constant folding for 'len' */    default: lua_assert(0); r = 0; break;  }  if (luai_numisnan(r)) return 0;  /* do not attempt to produce NaN */  e1->u.nval = r;  return 1;}static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {  if (constfolding(op, e1, e2))    return;  else {    int o1 = luaK_exp2RK(fs, e1);    int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;    freeexp(fs, e2);    freeexp(fs, e1);    e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);    e1->k = VRELOCABLE;  }}static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,                                                          expdesc *e2) {  int o1 = luaK_exp2RK(fs, e1);  int o2 = luaK_exp2RK(fs, e2);  freeexp(fs, e2);  freeexp(fs, e1);  if (cond == 0 && op != OP_EQ) {    int temp;  /* exchange args to replace by `<' or `<=' */    temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */    cond = 1;  }  e1->u.s.info = condjump(fs, op, cond, o1, o2);  e1->k = VJMP;}void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {  expdesc e2;  e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;  switch (op) {    case OPR_MINUS: {      if (e->k == VK)        luaK_exp2anyreg(fs, e);  /* cannot operate on non-numeric constants */      codearith(fs, OP_UNM, e, &e2);      break;    }    case OPR_NOT: codenot(fs, e); break;    case OPR_LEN: {      luaK_exp2anyreg(fs, e);  /* cannot operate on constants */      codearith(fs, OP_LEN, e, &e2);      break;    }    default: lua_assert(0);  }}void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {  switch (op) {    case OPR_AND: {      luaK_goiftrue(fs, v);      break;    }    case OPR_OR: {      luaK_goiffalse(fs, v);      break;    }    case OPR_CONCAT: {      luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */      break;    }    default: {      if (!isnumeral(v)) luaK_exp2RK(fs, v);      break;    }  }}void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {  switch (op) {    case OPR_AND: {      lua_assert(e1->t == NO_JUMP);  /* list must be closed */      luaK_dischargevars(fs, e2);      luaK_concat(fs, &e2->f, e1->f);      *e1 = *e2;      break;    }    case OPR_OR: {      lua_assert(e1->f == NO_JUMP);  /* list must be closed */      luaK_dischargevars(fs, e2);      luaK_concat(fs, &e2->t, e1->t);      *e1 = *e2;      break;    }    case OPR_CONCAT: {      luaK_exp2val(fs, e2);      if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {        lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);        freeexp(fs, e1);        SETARG_B(getcode(fs, e2), e1->u.s.info);        e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;      }      else {        luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */        codearith(fs, OP_CONCAT, e1, e2);      }      break;    }    case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;    case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;    case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;    case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;    case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;    case OPR_POW: codearith(fs, OP_POW, e1, e2); break;    case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;    case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;    case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;    case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;    case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;    case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;    default: lua_assert(0);  }}void luaK_fixline (FuncState *fs, int line) {  fs->f->lineinfo[fs->pc - 1] = line;}static int luaK_code (FuncState *fs, Instruction i, int line) {  Proto *f = fs->f;  dischargejpc(fs);  /* `pc' will change */  /* put new instruction in code array */  luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,                  MAX_INT, "code size overflow");  f->code[fs->pc] = i;  /* save corresponding line information */  luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,                  MAX_INT, "code size overflow");  f->lineinfo[fs->pc] = line;  return fs->pc++;}int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {  lua_assert(getOpMode(o) == iABC);  lua_assert(getBMode(o) != OpArgN || b == 0);  lua_assert(getCMode(o) != OpArgN || c == 0);  return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);}int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);  lua_assert(getCMode(o) == OpArgN);  return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);}void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {  int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;  int b = (tostore == LUA_MULTRET) ? 0 : tostore;  lua_assert(tostore != 0);  if (c <= MAXARG_C)    luaK_codeABC(fs, OP_SETLIST, base, b, c);  else {    luaK_codeABC(fs, OP_SETLIST, base, b, 0);    luaK_code(fs, cast(Instruction, c), fs->ls->lastline);  }  fs->freereg = base + 1;  /* free registers with list values */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -