Exemple #1
0
lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
  switch (op) {
    case LUA_OPADD: return luai_numadd(NULL, v1, v2);
    case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
    case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
    case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
    case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
    case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
    case LUA_OPUNM: return luai_numunm(NULL, v1);
    default: lua_assert(0); return 0;
  }
}
Exemple #2
0
static lua_Number numarith (lua_State *L, int op, lua_Number v1,
                                                  lua_Number v2) {
  switch (op) {
    case LUA_OPADD: return luai_numadd(L, v1, v2);
    case LUA_OPSUB: return luai_numsub(L, v1, v2);
    case LUA_OPMUL: return luai_nummul(L, v1, v2);
    case LUA_OPDIV: return luai_numdiv(L, v1, v2);
    case LUA_OPMOD: return luai_nummod(L, v1, v2);
    case LUA_OPPOW: return luai_numpow(L, v1, v2);
    case LUA_OPUNM: return luai_numunm(L, v1);
    default: lua_assert(0); return 0;
  }
}
Exemple #3
0
void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
                 const TValue *rc, TMS op) {
  TValue tempb, tempc;
  const TValue *b, *c;
  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
      (c = luaV_tonumber(rc, &tempc)) != NULL) {
    lua_Number nb = nvalue(b), nc = nvalue(c);
    switch (op) {
      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
      case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
      case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
      case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
      default: lua_assert(0); break;
    }
  }
  else if (!call_binTM(L, rb, rc, ra, op))
    luaG_aritherror(L, rb, rc);
}
Exemple #4
0
/* Note: if called for unary operations, 'rc'=='rb'.
 */
static void Arith (lua_State *L, StkId ra, const TValue *rb,
                   const TValue *rc, TMS op) {
  TValue tempb, tempc;
  const TValue *b, *c;
  lua_Number nb,nc;

  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
      (c = luaV_tonumber(rc, &tempc)) != NULL) {

    /* Keep integer arithmetics in the integer realm, if possible.
     */
#ifdef LUA_TINT
    if (ttisint(b) && ttisint(c)) {
      lua_Integer ib = ivalue(b), ic = ivalue(c);
      lua_Integer *ri = &ra->value.i;
      ra->tt= LUA_TINT;  /* part of 'setivalue(ra)' */
      switch (op) {
        case TM_ADD: if (try_addint( ri, ib, ic)) return; break;
        case TM_SUB: if (try_subint( ri, ib, ic)) return; break;
        case TM_MUL: if (try_mulint( ri, ib, ic)) return; break;
        case TM_DIV: if (try_divint( ri, ib, ic)) return; break;
        case TM_MOD: if (try_modint( ri, ib, ic)) return; break;
        case TM_POW: if (try_powint( ri, ib, ic)) return; break;
        case TM_UNM: if (try_unmint( ri, ib)) return; break;
        default: lua_assert(0);
      }
    }
#endif
    /* Fallback to floating point, when leaving range. */

#ifdef LNUM_COMPLEX
    if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) {
      lua_Complex r;
      if (op==TM_UNM) {
        r= -nvalue_complex_fast(b);     /* never an integer (or scalar) */
        setnvalue_complex_fast( ra, r );
      } else {
        lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c);
        switch (op) {
          case TM_ADD: r= bb + cc; break;
          case TM_SUB: r= bb - cc; break;
          case TM_MUL: r= bb * cc; break;
          case TM_DIV: r= bb / cc; break;
          case TM_MOD: 
            luaG_runerror(L, "attempt to use %% on complex numbers");  /* no return */
          case TM_POW: r= luai_vectpow( bb, cc ); break;
          default: lua_assert(0); r=0;
        }
        setnvalue_complex( ra, r );
      }
      return;
    }
#endif
    nb = nvalue(b); nc = nvalue(c);
    switch (op) {
      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return;
      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return;
      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return;
      case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return;
      case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return;
      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return;
      case TM_UNM: setnvalue(ra, luai_numunm(nb)); return;
      default: lua_assert(0);
    }
  }
  
  /* Either operand not a number */
  if (!call_binTM(L, rb, rc, ra, op))
    luaG_aritherror(L, rb, rc);
}
Exemple #5
0
void luaV_execute (lua_State *L, int nexeccalls) {
  LClosure *cl;
  StkId base;
  TValue *k;
  const Instruction *pc;
 reentry:  /* entry point */
  lua_assert(isLua(L->ci));
  pc = L->savedpc;
  cl = &clvalue(L->ci->func)->l;
  base = L->base;
  k = cl->p->k;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    StkId ra;
    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
      traceexec(L, pc);
      if (L->status == LUA_YIELD) {  /* did hook yield? */
        L->savedpc = pc - 1;
        return;
      }
      base = L->base;
    }
    /* warning!! several calls may realloc the stack and invalidate `ra' */
    ra = RA(i);
    lua_assert(base == L->base && L->base == L->ci->base);
    lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
    lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
    switch (GET_OPCODE(i)) {
      case OP_MOVE: {
        setobjs2s(L, ra, RB(i));
        continue;
      }
      case OP_LOADK: {
        setobj2s(L, ra, KBx(i));
        continue;
      }
      case OP_LOADBOOL: {
        setbvalue(ra, GETARG_B(i));
        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
        continue;
      }
      case OP_LOADNIL: {
        TValue *rb = RB(i);
        do {
          setnilvalue(rb--);
        } while (rb >= ra);
        continue;
      }
      case OP_GETUPVAL: {
        int b = GETARG_B(i);
        setobj2s(L, ra, cl->upvals[b]->v);
        continue;
      }
      case OP_GETGLOBAL: {
        TValue g;
        TValue *rb = KBx(i);
        sethvalue(L, &g, cl->env);
        lua_assert(ttisstring(rb));
        Protect(luaV_gettable(L, &g, rb, ra));
        continue;
      }
      case OP_GETTABLE: {
        Protect(luaV_gettable(L, RB(i), RKC(i), ra));
        continue;
      }
      case OP_SETGLOBAL: {
        TValue g;
        sethvalue(L, &g, cl->env);
        lua_assert(ttisstring(KBx(i)));
        Protect(luaV_settable(L, &g, KBx(i), ra));
        continue;
      }
      case OP_SETUPVAL: {
        UpVal *uv = cl->upvals[GETARG_B(i)];
        setobj(L, uv->v, ra);
        luaC_barrier(L, uv, ra);
        continue;
      }
      case OP_SETTABLE: {
        Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
        continue;
      }
      case OP_NEWTABLE: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
        Protect(luaC_checkGC(L));
        continue;
      }
      case OP_SELF: {
        StkId rb = RB(i);
        setobjs2s(L, ra+1, rb);
        Protect(luaV_gettable(L, rb, RKC(i), ra));
        continue;
      }
      case OP_ADD: {
        arith_op(luai_numadd, TM_ADD);
        continue;
      }
      case OP_SUB: {
        arith_op(luai_numsub, TM_SUB);
        continue;
      }
      case OP_MUL: {
        arith_op(luai_nummul, TM_MUL);
        continue;
      }
      case OP_DIV: {
        TValue *rb = RKB(i);
        TValue *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          lua_Number nb = nvalue(rb), nc = nvalue(rc);
          if (nc == 0) {
            lua_pushliteral(L, "divide by zero error");
            lua_error(L);
          }
          else
            setnvalue(ra, luai_numdiv(nb, nc));
        }
        else
          Protect(Arith(L, ra, rb, rc, TM_DIV));
        continue;
      }
      case OP_MOD: {
        TValue *rb = RKB(i);
        TValue *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          lua_Number nb = nvalue(rb), nc = nvalue(rc);
          if (nc == 0) {
            lua_pushliteral(L, "modulo by zero error");
            lua_error(L);
          }
          else
            setnvalue(ra, luai_nummod(nb, nc));
        }
        else
          Protect(Arith(L, ra, rb, rc, TM_MOD));
        continue;
      }
      case OP_POW: {
        arith_op(luai_numpow, TM_POW);
        continue;
      }
      case OP_BAND: {
	arith_op(luai_numand, TM_AND);
	continue;
      }
      case OP_BOR: {
	arith_op(luai_numor, TM_OR);
	continue;
      }
      case OP_BXOR: {
	arith_op(luai_numxor, TM_XOR);
	continue;
      }
      case OP_BSHL: {
	arith_op(luai_numshl, TM_SHL);
	continue;
      }
      case OP_BSHR: {
	arith_op(luai_numshr, TM_SHR);
	continue;
      }
      case OP_BNOT: {
        TValue *rb = RB(i);
        if (ttisnumber(rb)) {
          lua_Number nb = nvalue(rb);
          setnvalue(ra, luai_numnot(nb));
        }
        else {
          Protect(Arith(L, ra, rb, rb, TM_NOT));
        }
        continue;
      }
      case OP_UNM: {
        TValue *rb = RB(i);
        if (ttisnumber(rb)) {
          lua_Number nb = nvalue(rb);
          setnvalue(ra, luai_numunm(nb));
        }
        else {
          Protect(Arith(L, ra, rb, rb, TM_UNM));
        }
        continue;
      }
      case OP_NOT: {
        int res = l_isfalse(RB(i));  /* next assignment may change this value */
        setbvalue(ra, res);
        continue;
      }
      case OP_LEN: {
        TValue *rb = RB(i);
        switch (ttype(rb)) {
          case LUA_TTABLE: {
            setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
            break;
          }
          case LUA_TSTRING: {
            setnvalue(ra, cast_num(tsvalue(rb)->len));
            break;
          }
          default: {  /* try metamethod */
            Protect(
              if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
                luaG_typeerror(L, rb, "get length of");
            )
          }
        }
        continue;
      }
      case OP_CONCAT: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
        setobjs2s(L, RA(i), base+b);
        continue;
      }
      case OP_JMP: {
        dojump(L, pc, GETARG_sBx(i));
        continue;
      }
      case OP_EQ: {
        TValue *rb = RKB(i);
        TValue *rc = RKC(i);
        Protect(
          if (equalobj(L, rb, rc) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
      case OP_LT: {
        Protect(
          if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
      case OP_LE: {
        Protect(
          if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
Exemple #6
0
static void Arith (lua_State *L, StkId ra, TValue *rb,
                   TValue *rc, TMS op) {
  TValue tempb, tempc;
  const TValue *b, *c;
  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
      (c = luaV_tonumber(rc, &tempc)) != NULL) {
    lua_Number nb = nvalue(b), nc = nvalue(c);
    switch (op) {
      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
      case TM_DIV: if (nc == 0) { lua_pushliteral(L, "divide by zero error"); lua_error(L); } else setnvalue(ra, luai_numdiv(nb, nc)); break;
      case TM_MOD: if (nc == 0) { lua_pushliteral(L, "modulo by zero error"); lua_error(L); } else setnvalue(ra, luai_nummod(nb, nc)); break;
      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
      case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
      case TM_AND: setnvalue(ra, luai_numand(nb, nc)); break;
      case TM_OR: setnvalue(ra, luai_numor(nb, nc)); break;
      case TM_XOR: setnvalue(ra, luai_numxor(nb, nc)); break;
      case TM_SHL: setnvalue(ra, luai_numshl(nb, nc)); break;
      case TM_SHR: setnvalue(ra, luai_numshr(nb, nc)); break;
      case TM_NOT: setnvalue(ra, luai_numnot(nb)); break;
      default: lua_assert(0); break;
    }
  }
  else if (!call_binTM(L, rb, rc, ra, op))
    luaG_aritherror(L, rb, rc);
}
Exemple #7
0
static void Arith (lua_State *L, StkId ra, const TValue *rb,
                   const TValue *rc, TMS op) {
  TValue tempb, tempc;
  const TValue *b, *c;
#if LUA_REFCOUNT
  luarc_newvalue(&tempb);
  luarc_newvalue(&tempc);
  if ((b = luaV_tonumber(L, rb, &tempb)) != NULL &&
      (c = luaV_tonumber(L, rc, &tempc)) != NULL) {
#else
  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
      (c = luaV_tonumber(rc, &tempc)) != NULL) {
#endif /* LUA_REFCOUNT */
    lua_Number nb = nvalue(b), nc = nvalue(c);
#if LUA_REFCOUNT
    luarc_cleanvalue(&tempb);
    luarc_cleanvalue(&tempc);
#endif /* LUA_REFCOUNT */
    switch (op) {
      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
      case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
      case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
      case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
      default: lua_assert(0); break;
    }
  }
#if LUA_REFCOUNT
  else if (!call_binTM(L, rb, rc, ra, op)) {
    luarc_cleanvalue(&tempb);
    luarc_cleanvalue(&tempc);
    luaG_aritherror(L, rb, rc);
  }
#else
  else if (!call_binTM(L, rb, rc, ra, op))
    luaG_aritherror(L, rb, rc);
#endif /* LUA_REFCOUNT */
}



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

#define runtime_check(L, c)	{ if (!(c)) break; }

#define RA(i)	(base+GETARG_A(i))
/* to be used after possible stack reallocation */
#define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
#define RC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
#define RKB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
	ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
#define RKC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
	ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
#define KBx(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))


#define dojump(L,pc,i)	{(pc) += (i); luai_threadyield(L);}


#define Protect(x)	{ L->savedpc = pc; {x;}; base = L->base; }


#define arith_op(op,tm) { \
        TValue *rb = RKB(i); \
        TValue *rc = RKC(i); \
        if (ttisnumber(rb) && ttisnumber(rc)) { \
          lua_Number nb = nvalue(rb), nc = nvalue(rc); \
          setnvalue(ra, op(nb, nc)); \
        } \
        else \
          Protect(Arith(L, ra, rb, rc, tm)); \
      }

#if LUA_BITFIELD_OPS

#define bit_op(op) { \
        TValue *rb = RKB(i); \
        TValue *rc = RKC(i); \
        if (ttisnumber(rb) && ttisnumber(rc)) { \
          unsigned int nb = (unsigned int)nvalue(rb), nc = (unsigned int)nvalue(rc); \
          setnvalue(ra, nb op nc); \
        } \
        else \
          luaG_aritherror(L, rb, rc); \
      }

#endif /* LUA_BITFIELD_OPS */



void luaV_execute (lua_State *L, int nexeccalls) {
  LClosure *cl;
  StkId base;
  TValue *k;
  const Instruction *pc;
 reentry:  /* entry point */
  lua_assert(isLua(L->ci));
  pc = L->savedpc;
  cl = &clvalue(L->ci->func)->l;
  base = L->base;
  k = cl->p->k;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    StkId ra;
    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
      traceexec(L, pc);
      if (L->status == LUA_YIELD) {  /* did hook yield? */
        L->savedpc = pc - 1;
        return;
      }
      base = L->base;
    }
    /* warning!! several calls may realloc the stack and invalidate `ra' */
    ra = RA(i);
    lua_assert(base == L->base && L->base == L->ci->base);
    lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
    lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
    switch (GET_OPCODE(i)) {
      case OP_MOVE: {
        setobjs2s(L, ra, RB(i));
        continue;
      }
      case OP_LOADK: {
        setobj2s(L, ra, KBx(i));
        continue;
      }
      case OP_LOADBOOL: {
        setbvalue(ra, GETARG_B(i));
        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
        continue;
      }
      case OP_LOADNIL: {
        TValue *rb = RB(i);
        do {
          setnilvalue(rb--);
        } while (rb >= ra);
        continue;
      }
      case OP_GETUPVAL: {
        int b = GETARG_B(i);
        setobj2s(L, ra, cl->upvals[b]->v);
        continue;
      }
      case OP_GETGLOBAL: {
        TValue g;
        TValue *rb = KBx(i);
#if LUA_REFCOUNT
        sethvalue2n(L, &g, cl->env);
#else
        sethvalue(L, &g, cl->env);
#endif /* LUA_REFCOUNT */
        lua_assert(ttisstring(rb));
        Protect(luaV_gettable(L, &g, rb, ra));
#if LUA_REFCOUNT
		setnilvalue(&g);
#endif /* LUA_REFCOUNT */
        continue;
      }
      case OP_GETTABLE: {
        Protect(luaV_gettable(L, RB(i), RKC(i), ra));
        continue;
      }
      case OP_SETGLOBAL: {
        TValue g;
#if LUA_REFCOUNT
        sethvalue2n(L, &g, cl->env);
#else
        sethvalue(L, &g, cl->env);
#endif /* LUA_REFCOUNT */
        lua_assert(ttisstring(KBx(i)));
        Protect(luaV_settable(L, &g, KBx(i), ra));
#if LUA_REFCOUNT
		setnilvalue(&g);
#endif /* LUA_REFCOUNT */
        continue;
      }
      case OP_SETUPVAL: {
        UpVal *uv = cl->upvals[GETARG_B(i)];
        setobj(L, uv->v, ra);
        luaC_barrier(L, uv, ra);
        continue;
      }
      case OP_SETTABLE: {
        Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
        continue;
      }
      case OP_NEWTABLE: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
        Protect(luaC_checkGC(L));
        continue;
      }
      case OP_SELF: {
        StkId rb = RB(i);
        setobjs2s(L, ra+1, rb);
        Protect(luaV_gettable(L, rb, RKC(i), ra));
        continue;
      }
      case OP_ADD: {
        arith_op(luai_numadd, TM_ADD);
        continue;
      }
      case OP_SUB: {
        arith_op(luai_numsub, TM_SUB);
        continue;
      }
      case OP_MUL: {
        arith_op(luai_nummul, TM_MUL);
        continue;
      }
      case OP_DIV: {
        arith_op(luai_numdiv, TM_DIV);
        continue;
      }
      case OP_MOD: {
        arith_op(luai_nummod, TM_MOD);
        continue;
      }
      case OP_POW: {
        arith_op(luai_numpow, TM_POW);
        continue;
      }
      case OP_UNM: {
        TValue *rb = RB(i);
        if (ttisnumber(rb)) {
          lua_Number nb = nvalue(rb);
          setnvalue(ra, luai_numunm(nb));
        }
        else {
          Protect(Arith(L, ra, rb, rb, TM_UNM));
        }
        continue;
      }
      case OP_NOT: {
        int res = l_isfalse(RB(i));  /* next assignment may change this value */
        setbvalue(ra, res);
        continue;
      }
#if LUA_BITFIELD_OPS
      case OP_BAND: {
        bit_op(&);
        continue;
      }
      case OP_BOR: {
        bit_op(|);
        continue;
      }
      case OP_BXOR: {
        bit_op(^);
        continue;
      }
      case OP_BSHL: {
        bit_op(<<);
        continue;
      }
      case OP_BSHR: {
        bit_op(>>);
        continue;
      }
#endif /* LUA_BITFIELD_OPS */
      case OP_LEN: {
        const TValue *rb = RB(i);
        switch (ttype(rb)) {
          case LUA_TTABLE: {
            setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
            break;
          }
          case LUA_TSTRING: {
            setnvalue(ra, cast_num(tsvalue(rb)->len));
            break;
          }
#if LUA_WIDESTRING
          case LUA_TWSTRING: {
            setnvalue(ra, cast_num(tsvalue(rb)->len));
            break;
          }
#endif /* LUA_WIDESTRING */
          default: {  /* try metamethod */
            Protect(
              if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
                luaG_typeerror(L, rb, "get length of");
            )
          }
        }
        continue;
      }
      case OP_CONCAT: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
        setobjs2s(L, RA(i), base+b);
        continue;
      }
      case OP_JMP: {
        dojump(L, pc, GETARG_sBx(i));
        continue;
      }
      case OP_EQ: {
        TValue *rb = RKB(i);
        TValue *rc = RKC(i);
        Protect(
          if (equalobj(L, rb, rc) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
      case OP_LT: {
        Protect(
          if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
      case OP_LE: {
        Protect(
          if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
Exemple #8
0
void ZCC_InitOperators()
{
	// Prototypes are added from lowest to highest conversion precedence.

	// Unary operators
	static const OpProto1 UnaryOpInit[] =
	{
		{ PEX_PostInc	 , (PType **)&TypeSInt32,  EvalIdentity },
		{ PEX_PostInc	 , (PType **)&TypeUInt32,  EvalIdentity },
		{ PEX_PostInc	 , (PType **)&TypeFloat64, EvalIdentity },

		{ PEX_PostDec	 , (PType **)&TypeSInt32,  EvalIdentity },
		{ PEX_PostDec	 , (PType **)&TypeUInt32,  EvalIdentity },
		{ PEX_PostDec	 , (PType **)&TypeFloat64, EvalIdentity },

		{ PEX_PreInc	 , (PType **)&TypeSInt32,  [](auto *val) { val->IntVal += 1; return val; } },
		{ PEX_PreInc	 , (PType **)&TypeUInt32,  [](auto *val) { val->UIntVal += 1; return val; } },
		{ PEX_PreInc	 , (PType **)&TypeFloat64, [](auto *val) { val->DoubleVal += 1; return val; } },

		{ PEX_PreDec	 , (PType **)&TypeSInt32,  [](auto *val) { val->IntVal -= 1; return val; } },
		{ PEX_PreDec	 , (PType **)&TypeUInt32,  [](auto *val) { val->UIntVal -= 1; return val; } },
		{ PEX_PreDec	 , (PType **)&TypeFloat64, [](auto *val) { val->DoubleVal -= 1; return val; } },

		{ PEX_Negate	 , (PType **)&TypeSInt32,  [](auto *val) { val->IntVal = -val->IntVal; return val; } },
		{ PEX_Negate	 , (PType **)&TypeFloat64, [](auto *val) { val->DoubleVal = -val->DoubleVal; return val; } },

		{ PEX_AntiNegate , (PType **)&TypeSInt32,  EvalIdentity },
		{ PEX_AntiNegate , (PType **)&TypeUInt32,  EvalIdentity },
		{ PEX_AntiNegate , (PType **)&TypeFloat64, EvalIdentity },

		{ PEX_BitNot	 , (PType **)&TypeSInt32,  [](auto *val) { val->IntVal = ~val->IntVal; return val; } },
		{ PEX_BitNot	 , (PType **)&TypeUInt32,  [](auto *val) { val->UIntVal = ~val->UIntVal; return val; } },

		{ PEX_BoolNot	 , (PType **)&TypeBool,    [](auto *val) { val->IntVal = !val->IntVal; return val; } },
	};
	for (size_t i = 0; i < countof(UnaryOpInit); ++i)
	{
		ZCC_OpInfo[UnaryOpInit[i].Op].AddProto(*UnaryOpInit[i].Type, *UnaryOpInit[i].Type, UnaryOpInit[i].EvalConst);
	}

	// Binary operators
	static const OpProto2 BinaryOpInit[] =
	{
		{ PEX_Add		 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal += r->IntVal; return l; } },
		{ PEX_Add		 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal += r->UIntVal; return l; } },
		{ PEX_Add		 , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal += r->DoubleVal; return l; } },

		{ PEX_Sub		 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal -= r->IntVal; return l; } },
		{ PEX_Sub		 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal -= r->UIntVal; return l; } },
		{ PEX_Sub		 , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal -= r->DoubleVal; return l; } },

		{ PEX_Mul		 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal *= r->IntVal; return l; } },
		{ PEX_Mul		 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal *= r->UIntVal; return l; } },
		{ PEX_Mul		 , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal *= r->DoubleVal; return l; } },

		{ PEX_Div		 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal /= r->IntVal; return l; } },
		{ PEX_Div		 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal /= r->UIntVal; return l; } },
		{ PEX_Div		 , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal /= r->DoubleVal; return l; } },

		{ PEX_Mod		 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal %= r->IntVal; return l; } },
		{ PEX_Mod		 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal %= r->UIntVal; return l; } },
		{ PEX_Mod		 , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal = luai_nummod(l->DoubleVal, r->DoubleVal); return l; } },

		{ PEX_Pow		 , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal = g_pow(l->DoubleVal, r->DoubleVal); return l; } },

		{ PEX_Concat	 , (PType **)&TypeString,  (PType **)&TypeString,  (PType **)&TypeString,  EvalConcat },

		{ PEX_BitAnd	 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal &= r->IntVal; return l; } },
		{ PEX_BitAnd	 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal &= r->UIntVal; return l; } },

		{ PEX_BitOr		 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal |= r->IntVal; return l; } },
		{ PEX_BitOr		 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal |= r->UIntVal; return l; } },

		{ PEX_BitXor	 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal ^= r->IntVal; return l; } },
		{ PEX_BitXor	 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal ^= r->UIntVal; return l; } },

		{ PEX_BoolAnd	 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal && r->IntVal; l->Type = TypeBool; return l; } },
		{ PEX_BoolAnd	 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal && r->UIntVal; l->Type = TypeBool; return l;  } },

		{ PEX_BoolOr	 , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal || r->IntVal; l->Type = TypeBool; return l; } },
		{ PEX_BoolOr	 , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal || r->UIntVal; l->Type = TypeBool; return l; } },

		{ PEX_LeftShift  , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->IntVal <<= r->UIntVal; return l; } },
		{ PEX_LeftShift  , (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->UIntVal <<= r->UIntVal; return l; } },

		{ PEX_RightShift , (PType **)&TypeSInt32,  (PType **)&TypeSInt32,  (PType **)&TypeUInt32,  [](auto *l, auto *r, auto &) { l->IntVal >>= r->UIntVal; return l; } },
Exemple #9
0
static ZCC_ExprConstant *EvalModFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &)
{
	l->DoubleVal = luai_nummod(l->DoubleVal, r->DoubleVal);
	return l;
}