Пример #1
0
 void prefix(int /* UnOpr */ op, expdesc e, int line) {
   expdesc e2 = new expdesc();
   e2.init(LexState.VKNUM, 0);
   switch (op) {
     case LexState.OPR_MINUS:
       {
         if (e.isnumeral()) /* minus constant? */ e.u.setNval(e.u.nval().neg()); /* fold it */
         else {
           this.exp2anyreg(e);
           this.codearith(OP_UNM, e, e2, line);
         }
         break;
       }
     case LexState.OPR_NOT:
       this.codenot(e);
       break;
     case LexState.OPR_LEN:
       {
         this.exp2anyreg(e); /* cannot operate on constants */
         this.codearith(OP_LEN, e, e2, line);
         break;
       }
     default:
       _assert(false);
   }
 }
Пример #2
0
 int exp2RK(expdesc e) {
   this.exp2val(e);
   switch (e.k) {
     case LexState.VTRUE:
     case LexState.VFALSE:
     case LexState.VNIL:
       {
         if (this.nk <= MAXINDEXRK) {
             /* constant fit in RK operand? */
           e.u.info = (e.k == LexState.VNIL) ? this.nilK() : this.boolK((e.k == LexState.VTRUE));
           e.k = LexState.VK;
           return RKASK(e.u.info);
         } else break;
       }
     case LexState.VKNUM:
       {
         e.u.info = this.numberK(e.u.nval());
         e.k = LexState.VK;
         /* go through */
       }
     case LexState.VK:
       {
         if (e.u.info <= MAXINDEXRK) /* constant fit in argC? */ return RKASK(e.u.info);
         else break;
       }
     default:
       break;
   }
   /* not a constant in the right range: put it in a register */
   return this.exp2anyreg(e);
 }
Пример #3
0
 void setoneret(expdesc e) {
   if (e.k == LexState.VCALL) {
       /* expression is an open function call? */
     e.k = LexState.VNONRELOC;
     e.u.info = GETARG_A(this.getcode(e));
   } else if (e.k == LexState.VVARARG) {
     SETARG_B(this.getcodePtr(e), 2);
     e.k = LexState.VRELOCABLE; /* can relocate its simple result */
   }
 }
Пример #4
0
 void indexed(expdesc t, expdesc k) {
   t.u.ind_t = (short) t.u.info;
   t.u.ind_idx = (short) this.exp2RK(k);
   LuaC._assert(t.k == LexState.VUPVAL || vkisinreg(t.k));
   t.u.ind_vt = (short) ((t.k == LexState.VUPVAL) ? LexState.VUPVAL : LexState.VLOCAL);
   t.k = LexState.VINDEXED;
 }
Пример #5
0
 void infix(int /* BinOpr */ op, expdesc v) {
   switch (op) {
     case LexState.OPR_AND:
       {
         this.goiftrue(v);
         break;
       }
     case LexState.OPR_OR:
       {
         this.goiffalse(v);
         break;
       }
     case LexState.OPR_CONCAT:
       {
         this.exp2nextreg(v); /* operand must be on the `stack' */
         break;
       }
     case LexState.OPR_ADD:
     case LexState.OPR_SUB:
     case LexState.OPR_MUL:
     case LexState.OPR_DIV:
     case LexState.OPR_MOD:
     case LexState.OPR_POW:
       {
         if (!v.isnumeral()) this.exp2RK(v);
         break;
       }
     default:
       {
         this.exp2RK(v);
         break;
       }
   }
 }
Пример #6
0
 void codenot(expdesc e) {
   this.dischargevars(e);
   switch (e.k) {
     case LexState.VNIL:
     case LexState.VFALSE:
       {
         e.k = LexState.VTRUE;
         break;
       }
     case LexState.VK:
     case LexState.VKNUM:
     case LexState.VTRUE:
       {
         e.k = LexState.VFALSE;
         break;
       }
     case LexState.VJMP:
       {
         this.invertjump(e);
         break;
       }
     case LexState.VRELOCABLE:
     case LexState.VNONRELOC:
       {
         this.discharge2anyreg(e);
         this.freeexp(e);
         e.u.info = this.codeABC(OP_NOT, 0, e.u.info, 0);
         e.k = LexState.VRELOCABLE;
         break;
       }
     default:
       {
         _assert(false); /* cannot happen */
         break;
       }
   }
   /* interchange true and false lists */
   {
     int temp = e.f.i;
     e.f.i = e.t.i;
     e.t.i = temp;
   }
   this.removevalues(e.f.i);
   this.removevalues(e.t.i);
 }
Пример #7
0
 boolean constfolding(int op, expdesc e1, expdesc e2) {
   LuaValue v1, v2, r;
   if (!e1.isnumeral() || !e2.isnumeral()) return false;
   if ((op == OP_DIV || op == OP_MOD) && e2.u.nval().eq_b(LuaValue.ZERO))
     return false; /* do not attempt to divide by 0 */
   v1 = e1.u.nval();
   v2 = e2.u.nval();
   switch (op) {
     case OP_ADD:
       r = v1.add(v2);
       break;
     case OP_SUB:
       r = v1.sub(v2);
       break;
     case OP_MUL:
       r = v1.mul(v2);
       break;
     case OP_DIV:
       r = v1.div(v2);
       break;
     case OP_MOD:
       r = v1.mod(v2);
       break;
     case OP_POW:
       r = v1.pow(v2);
       break;
     case OP_UNM:
       r = v1.neg();
       break;
     case OP_LEN:
       // r = v1.len();
       // break;
       return false; /* no constant folding for 'len' */
     default:
       _assert(false);
       r = null;
       break;
   }
   if (Double.isNaN(r.todouble())) return false; /* do not attempt to produce NaN */
   e1.u.setNval(r);
   return true;
 }
Пример #8
0
 void self(expdesc e, expdesc key) {
   int func;
   this.exp2anyreg(e);
   this.freeexp(e);
   func = this.freereg;
   this.reserveregs(2);
   this.codeABC(OP_SELF, func, e.u.info, this.exp2RK(key));
   this.freeexp(key);
   e.u.info = func;
   e.k = LexState.VNONRELOC;
 }
Пример #9
0
 void exp2reg(expdesc e, int reg) {
   this.discharge2reg(e, reg);
   if (e.k == LexState.VJMP) this.concat(e.t, e.u.info); /* put this jump in `t' list */
   if (e.hasjumps()) {
     int _final; /* position after whole expression */
     int p_f = LexState.NO_JUMP; /* position of an eventual LOAD false */
     int p_t = LexState.NO_JUMP; /* position of an eventual LOAD true */
     if (this.need_value(e.t.i) || this.need_value(e.f.i)) {
       int fj = (e.k == LexState.VJMP) ? LexState.NO_JUMP : this.jump();
       p_f = this.code_label(reg, 0, 1);
       p_t = this.code_label(reg, 1, 0);
       this.patchtohere(fj);
     }
     _final = this.getlabel();
     this.patchlistaux(e.f.i, _final, reg, p_f);
     this.patchlistaux(e.t.i, _final, reg, p_t);
   }
   e.f.i = e.t.i = LexState.NO_JUMP;
   e.u.info = reg;
   e.k = LexState.VNONRELOC;
 }
Пример #10
0
 static int singlevaraux(FuncState fs, LuaString n, expdesc var, int base) {
   if (fs == null) /* no more levels? */ return LexState.VVOID; /* default is global */
   int v = fs.searchvar(n); /* look up at current level */
   if (v >= 0) {
     var.init(LexState.VLOCAL, v);
     if (base == 0) fs.markupval(v); /* local will be used as an upval */
     return LexState.VLOCAL;
   } else {
       /* not found at current level; try upvalues */
     int idx = fs.searchupvalue(n); /* try existing upvalues */
     if (idx < 0) {
         /* not found? */
       if (singlevaraux(fs.prev, n, var, 0) == LexState.VVOID) /* try upper levels */
         return LexState.VVOID; /* not found; is a global */
       /* else was LOCAL or UPVAL */
       idx = fs.newupvalue(n, var); /* will be a new upvalue */
     }
     var.init(LexState.VUPVAL, idx);
     return LexState.VUPVAL;
   }
 }
Пример #11
0
 int exp2anyreg(expdesc e) {
   this.dischargevars(e);
   if (e.k == LexState.VNONRELOC) {
     if (!e.hasjumps()) return e.u.info; /* exp is already in a register */
     if (e.u.info >= this.nactvar) {
         /* reg. is not a local? */
       this.exp2reg(e, e.u.info); /* put value on it */
       return e.u.info;
     }
   }
   this.exp2nextreg(e); /* default */
   return e.u.info;
 }
Пример #12
0
 void dischargevars(expdesc e) {
   switch (e.k) {
     case LexState.VLOCAL:
       {
         e.k = LexState.VNONRELOC;
         break;
       }
     case LexState.VUPVAL:
       {
         e.u.info = this.codeABC(OP_GETUPVAL, 0, e.u.info, 0);
         e.k = LexState.VRELOCABLE;
         break;
       }
     case LexState.VINDEXED:
       {
         int op = OP_GETTABUP; /* assume 't' is in an upvalue */
         this.freereg(e.u.ind_idx);
         if (e.u.ind_vt == LexState.VLOCAL) {
             /* 't' is in a register? */
           this.freereg(e.u.ind_t);
           op = OP_GETTABLE;
         }
         e.u.info = this.codeABC(op, 0, e.u.ind_t, e.u.ind_idx);
         e.k = LexState.VRELOCABLE;
         break;
       }
     case LexState.VVARARG:
     case LexState.VCALL:
       {
         this.setoneret(e);
         break;
       }
     default:
       break; /* there is one value available (somewhere) */
   }
 }
Пример #13
0
 void codecomp(int /* OpCode */ op, int cond, expdesc e1, expdesc e2) {
   int o1 = this.exp2RK(e1);
   int o2 = this.exp2RK(e2);
   this.freeexp(e2);
   this.freeexp(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.info = this.condjump(op, cond, o1, o2);
   e1.k = LexState.VJMP;
 }
Пример #14
0
 void codearith(int op, expdesc e1, expdesc e2, int line) {
   if (constfolding(op, e1, e2)) return;
   else {
     int o2 = (op != OP_UNM && op != OP_LEN) ? this.exp2RK(e2) : 0;
     int o1 = this.exp2RK(e1);
     if (o1 > o2) {
       this.freeexp(e1);
       this.freeexp(e2);
     } else {
       this.freeexp(e2);
       this.freeexp(e1);
     }
     e1.u.info = this.codeABC(op, 0, o1, o2);
     e1.k = LexState.VRELOCABLE;
     fixline(line);
   }
 }
Пример #15
0
 void discharge2reg(expdesc e, int reg) {
   this.dischargevars(e);
   switch (e.k) {
     case LexState.VNIL:
       {
         this.nil(reg, 1);
         break;
       }
     case LexState.VFALSE:
     case LexState.VTRUE:
       {
         this.codeABC(OP_LOADBOOL, reg, (e.k == LexState.VTRUE ? 1 : 0), 0);
         break;
       }
     case LexState.VK:
       {
         this.codeABx(OP_LOADK, reg, e.u.info);
         break;
       }
     case LexState.VKNUM:
       {
         this.codeABx(OP_LOADK, reg, this.numberK(e.u.nval()));
         break;
       }
     case LexState.VRELOCABLE:
       {
         InstructionPtr pc = this.getcodePtr(e);
         SETARG_A(pc, reg);
         break;
       }
     case LexState.VNONRELOC:
       {
         if (reg != e.u.info) this.codeABC(OP_MOVE, reg, e.u.info, 0);
         break;
       }
     default:
       {
         _assert(e.k == LexState.VVOID || e.k == LexState.VJMP);
         return; /* nothing to do... */
       }
   }
   e.u.info = reg;
   e.k = LexState.VNONRELOC;
 }
Пример #16
0
 void posfix(int op, expdesc e1, expdesc e2, int line) {
   switch (op) {
     case LexState.OPR_AND:
       {
         _assert(e1.t.i == LexState.NO_JUMP); /* list must be closed */
         this.dischargevars(e2);
         this.concat(e2.f, e1.f.i);
         // *e1 = *e2;
         e1.setvalue(e2);
         break;
       }
     case LexState.OPR_OR:
       {
         _assert(e1.f.i == LexState.NO_JUMP); /* list must be closed */
         this.dischargevars(e2);
         this.concat(e2.t, e1.t.i);
         // *e1 = *e2;
         e1.setvalue(e2);
         break;
       }
     case LexState.OPR_CONCAT:
       {
         this.exp2val(e2);
         if (e2.k == LexState.VRELOCABLE && GET_OPCODE(this.getcode(e2)) == OP_CONCAT) {
           _assert(e1.u.info == GETARG_B(this.getcode(e2)) - 1);
           this.freeexp(e1);
           SETARG_B(this.getcodePtr(e2), e1.u.info);
           e1.k = LexState.VRELOCABLE;
           e1.u.info = e2.u.info;
         } else {
           this.exp2nextreg(e2); /* operand must be on the 'stack' */
           this.codearith(OP_CONCAT, e1, e2, line);
         }
         break;
       }
     case LexState.OPR_ADD:
       this.codearith(OP_ADD, e1, e2, line);
       break;
     case LexState.OPR_SUB:
       this.codearith(OP_SUB, e1, e2, line);
       break;
     case LexState.OPR_MUL:
       this.codearith(OP_MUL, e1, e2, line);
       break;
     case LexState.OPR_DIV:
       this.codearith(OP_DIV, e1, e2, line);
       break;
     case LexState.OPR_MOD:
       this.codearith(OP_MOD, e1, e2, line);
       break;
     case LexState.OPR_POW:
       this.codearith(OP_POW, e1, e2, line);
       break;
     case LexState.OPR_EQ:
       this.codecomp(OP_EQ, 1, e1, e2);
       break;
     case LexState.OPR_NE:
       this.codecomp(OP_EQ, 0, e1, e2);
       break;
     case LexState.OPR_LT:
       this.codecomp(OP_LT, 1, e1, e2);
       break;
     case LexState.OPR_LE:
       this.codecomp(OP_LE, 1, e1, e2);
       break;
     case LexState.OPR_GT:
       this.codecomp(OP_LT, 0, e1, e2);
       break;
     case LexState.OPR_GE:
       this.codecomp(OP_LE, 0, e1, e2);
       break;
     default:
       _assert(false);
   }
 }
Пример #17
0
 void exp2anyregup(expdesc e) {
   if (e.k != LexState.VUPVAL || e.hasjumps()) exp2anyreg(e);
 }
Пример #18
0
 void exp2val(expdesc e) {
   if (e.hasjumps()) this.exp2anyreg(e);
   else this.dischargevars(e);
 }