Exemple #1
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);
 }
Exemple #2
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 */
   }
 }
Exemple #3
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;
 }
Exemple #4
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);
 }
Exemple #5
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;
 }
Exemple #6
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;
 }
Exemple #7
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) */
   }
 }
Exemple #8
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);
   }
 }
Exemple #9
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;
 }
Exemple #10
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;
 }
Exemple #11
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);
   }
 }