Beispiel #1
0
        /// <summary>
        /// Equivalent to luaK_prefix. </summary>
        internal void kPrefix(int op, Expdesc e)
        {
            Expdesc e2 = new Expdesc(Expdesc.VKNUM, 0);

            switch (op)
            {
            case Syntax.OPR_MINUS:
                if (e.kind() == Expdesc.VK)
                {
                    kExp2anyreg(e);
                }
                codearith(Lua.OP_UNM, e, e2);
                break;

            case Syntax.OPR_NOT:
                codenot(e);
                break;

            case Syntax.OPR_LEN:
                kExp2anyreg(e);
                codearith(Lua.OP_LEN, e, e2);
                break;

            default:
                throw new System.ArgumentException();
            }
        }
Beispiel #2
0
        internal void setargc(Expdesc e, int c)
        {
            int at = e.info_Renamed;

            int[] code = f.code_Renamed;
            code[at] = Lua.SETARG_C(code[at], c);
        }
Beispiel #3
0
 private void freeexp(Expdesc e)
 {
     if (e.kind() == Expdesc.VNONRELOC)
     {
         freereg(e.info_Renamed);
     }
 }
Beispiel #4
0
        /// <summary>
        /// Equivalent to <code>luaK_goiffalse</code>. </summary>
        internal void kGoiffalse(Expdesc e)
        {
            int lj;     // pc of last jump

            kDischargevars(e);
            switch (e.k)
            {
            case Expdesc.VNIL:
            case Expdesc.VFALSE:
                lj = NO_JUMP;         // always false; do nothing
                break;

            case Expdesc.VTRUE:
                lj = kJump();         // always jump
                break;

            case Expdesc.VJMP:
                lj = e.info_Renamed;
                break;

            default:
                lj = jumponcond(e, true);
                break;
            }
            e.t = kConcat(e.t, lj);     // insert last jump in `t' list
            kPatchtohere(e.f);
            e.f = NO_JUMP;
        }
Beispiel #5
0
        internal void setargb(Expdesc e, int b)
        {
            int at = e.info_Renamed;

            int[] code = f.code_Renamed;
            code[at] = Lua.SETARG_B(code[at], b);
        }
Beispiel #6
0
        internal void setarga(Expdesc e, int a)
        {
            int at = e.info_Renamed;

            int[] code = f.code_Renamed;
            code[at] = Lua.SETARG_A(code[at], a);
        }
Beispiel #7
0
        /// <summary>
        /// Equivalent to <code>luaK_goiftrue</code>. </summary>
        internal void kGoiftrue(Expdesc e)
        {
            int lj;     // pc of last jump

            kDischargevars(e);
            switch (e.k)
            {
            case Expdesc.VK:
            case Expdesc.VKNUM:
            case Expdesc.VTRUE:
                lj = NO_JUMP;         // always true; do nothing
                break;

            case Expdesc.VFALSE:
                lj = kJump();         // always jump
                break;

            case Expdesc.VJMP:
                invertjump(e);
                lj = e.info_Renamed;
                break;

            default:
                lj = jumponcond(e, false);
                break;
            }
            e.f = kConcat(e.f, lj);     // insert last jump in `f' list
            kPatchtohere(e.t);
            e.t = NO_JUMP;
        }
Beispiel #8
0
 /// <summary>
 /// Equivalent to luaK_exp2nextreg. </summary>
 internal void kExp2nextreg(Expdesc e)
 {
     kDischargevars(e);
     freeexp(e);
     kReserveregs(1);
     exp2reg(e, freereg_Renamed - 1);
 }
Beispiel #9
0
        /// <summary>
        /// Equivalent to luaK_dischargevars. </summary>
        internal void kDischargevars(Expdesc e)
        {
            switch (e.kind())
            {
            case Expdesc.VLOCAL:
                e.Kind = Expdesc.VNONRELOC;
                break;

            case Expdesc.VUPVAL:
                e.reloc(kCodeABC(Lua.OP_GETUPVAL, 0, e.info_Renamed, 0));
                break;

            case Expdesc.VGLOBAL:
                e.reloc(kCodeABx(Lua.OP_GETGLOBAL, 0, e.info_Renamed));
                break;

            case Expdesc.VINDEXED:
                freereg(e.aux());
                freereg(e.info());
                e.reloc(kCodeABC(Lua.OP_GETTABLE, 0, e.info_Renamed, e.aux_Renamed));
                break;

            case Expdesc.VVARARG:
            case Expdesc.VCALL:
                kSetoneret(e);
                break;

            default:
                break;         // there is one value available (somewhere)
            }
        }
Beispiel #10
0
 private void discharge2anyreg(Expdesc e)
 {
     if (e.k != Expdesc.VNONRELOC)
     {
         kReserveregs(1);
         discharge2reg(e, freereg_Renamed - 1);
     }
 }
Beispiel #11
0
        private void invertjump(Expdesc e)
        {
            int at = getjumpcontrol(e.info_Renamed);

            int[] code  = f.code_Renamed;
            int   instr = code[at];

            //# assert testTMode(Lua.OPCODE(instr)) && Lua.OPCODE(instr) != Lua.OP_TESTSET && Lua.OPCODE(instr) != Lua.OP_TEST
            code[at] = Lua.SETARG_A(instr, (Lua.ARGA(instr) == 0 ? 1 : 0));
        }
Beispiel #12
0
 /// <summary>
 /// Equivalent to <code>luaK_exp2val</code>. </summary>
 internal void kExp2val(Expdesc e)
 {
     if (e.hasjumps())
     {
         kExp2anyreg(e);
     }
     else
     {
         kDischargevars(e);
     }
 }
Beispiel #13
0
 /// <summary>
 /// Equivalent to luaK_setoneret. </summary>
 internal void kSetoneret(Expdesc e)
 {
     if (e.kind() == Expdesc.VCALL)     // expression is an open function call?
     {
         e.nonreloc(Lua.ARGA(getcode(e)));
     }
     else if (e.kind() == Expdesc.VVARARG)
     {
         setargb(e, 2);
         e.Kind = Expdesc.VRELOCABLE;
     }
 }
Beispiel #14
0
        internal void kSelf(Expdesc e, Expdesc key)
        {
            kExp2anyreg(e);
            freeexp(e);
            int func = freereg_Renamed;

            kReserveregs(2);
            kCodeABC(Lua.OP_SELF, func, e.info_Renamed, kExp2RK(key));
            freeexp(key);
            e.info_Renamed = func;
            e.k            = Expdesc.VNONRELOC;
        }
Beispiel #15
0
 /// <summary>
 /// Equivalent to luaK_setreturns. </summary>
 internal void kSetreturns(Expdesc e, int nresults)
 {
     if (e.kind() == Expdesc.VCALL)     // expression is an open function call?
     {
         setargc(e, nresults + 1);
     }
     else if (e.kind() == Expdesc.VVARARG)
     {
         setargb(e, nresults + 1);
         setarga(e, freereg_Renamed);
         kReserveregs(1);
     }
 }
Beispiel #16
0
 private void codearith(int op, Expdesc e1, Expdesc e2)
 {
     if (constfolding(op, e1, e2))
     {
         return;
     }
     else
     {
         int o1 = kExp2RK(e1);
         int o2 = (op != Lua.OP_UNM && op != Lua.OP_LEN) ? kExp2RK(e2) : 0;
         freeexp(e2);
         freeexp(e1);
         e1.info_Renamed = kCodeABC(op, 0, o1, o2);
         e1.k            = Expdesc.VRELOCABLE;
     }
 }
Beispiel #17
0
 private int jumponcond(Expdesc e, bool cond)
 {
     if (e.k == Expdesc.VRELOCABLE)
     {
         int ie = getcode(e);
         if (Lua.OPCODE(ie) == Lua.OP_NOT)
         {
             pc--;     // remove previous OP_NOT
             return(condjump(Lua.OP_TEST, Lua.ARGB(ie), 0, cond ? 0 : 1));
         }
         /* else go through */
     }
     discharge2anyreg(e);
     freeexp(e);
     return(condjump(Lua.OP_TESTSET, Lua.NO_REG, e.info_Renamed, cond ? 1 : 0));
 }
Beispiel #18
0
        internal void codecomp(int op, bool cond, Expdesc e1, Expdesc e2)
        {
            int o1 = kExp2RK(e1);
            int o2 = kExp2RK(e2);

            freeexp(e2);
            freeexp(e1);
            if ((!cond) && op != Lua.OP_EQ)
            {
                /* exchange args to replace by `<' or `<=' */
                int temp = o1;   // o1 <==> o2
                o1   = o2;
                o2   = temp;
                cond = true;
            }
            e1.info_Renamed = condjump(op, (cond ? 1 : 0), o1, o2);
            e1.k            = Expdesc.VJMP;
        }
Beispiel #19
0
 /// <summary>
 /// Equivalent to luaK_exp2anyreg. </summary>
 internal int kExp2anyreg(Expdesc e)
 {
     kDischargevars(e);
     if (e.k == Expdesc.VNONRELOC)
     {
         if (!e.hasjumps())
         {
             return(e.info_Renamed);
         }
         if (e.info_Renamed >= nactvar)   // reg is not a local?
         {
             exp2reg(e, e.info_Renamed);  // put value on it
             return(e.info_Renamed);
         }
     }
     kExp2nextreg(e);     // default
     return(e.info_Renamed);
 }
Beispiel #20
0
        private void discharge2reg(Expdesc e, int reg)
        {
            kDischargevars(e);
            switch (e.k)
            {
            case Expdesc.VNIL:
                kNil(reg, 1);
                break;

            case Expdesc.VFALSE:
            case Expdesc.VTRUE:
                kCodeABC(Lua.OP_LOADBOOL, reg, (e.k == Expdesc.VTRUE ? 1 : 0), 0);
                break;

            case Expdesc.VK:
                kCodeABx(Lua.OP_LOADK, reg, e.info_Renamed);
                break;

            case Expdesc.VKNUM:
                kCodeABx(Lua.OP_LOADK, reg, kNumberK(e.nval_Renamed));
                break;

            case Expdesc.VRELOCABLE:
                setarga(e, reg);
                break;

            case Expdesc.VNONRELOC:
                if (reg != e.info_Renamed)
                {
                    kCodeABC(Lua.OP_MOVE, reg, e.info_Renamed, 0);
                }
                break;

            case Expdesc.VVOID:
            case Expdesc.VJMP:
                return;

            default:
                //# assert false
                break;
            }
            e.nonreloc(reg);
        }
Beispiel #21
0
        private void codenot(Expdesc e)
        {
            kDischargevars(e);
            switch (e.k)
            {
            case Expdesc.VNIL:
            case Expdesc.VFALSE:
                e.k = Expdesc.VTRUE;
                break;

            case Expdesc.VK:
            case Expdesc.VKNUM:
            case Expdesc.VTRUE:
                e.k = Expdesc.VFALSE;
                break;

            case Expdesc.VJMP:
                invertjump(e);
                break;

            case Expdesc.VRELOCABLE:
            case Expdesc.VNONRELOC:
                discharge2anyreg(e);
                freeexp(e);
                e.info_Renamed = kCodeABC(Lua.OP_NOT, 0, e.info_Renamed, 0);
                e.k            = Expdesc.VRELOCABLE;
                break;

            default:
                //# assert false
                break;
            }
            /* interchange true and false lists */
            {
                int temp = e.f;
                e.f = e.t;
                e.t = temp;
            }
            removevalues(e.f);
            removevalues(e.t);
        }
Beispiel #22
0
        /// <summary>
        /// Equivalent to <code>luaK_storevar</code>. </summary>
        internal void kStorevar(Expdesc @var, Expdesc ex)
        {
            switch (@var.k)
            {
            case Expdesc.VLOCAL:
            {
                freeexp(ex);
                exp2reg(ex, @var.info_Renamed);
                return;
            }

            case Expdesc.VUPVAL:
            {
                int e = kExp2anyreg(ex);
                kCodeABC(Lua.OP_SETUPVAL, e, @var.info_Renamed, 0);
                break;
            }

            case Expdesc.VGLOBAL:
            {
                int e = kExp2anyreg(ex);
                kCodeABx(Lua.OP_SETGLOBAL, e, @var.info_Renamed);
                break;
            }

            case Expdesc.VINDEXED:
            {
                int e = kExp2RK(ex);
                kCodeABC(Lua.OP_SETTABLE, @var.info_Renamed, @var.aux_Renamed, e);
                break;
            }

            default:
            {
                /* invalid var kind to store */
                //# assert false
                break;
            }
            }
            freeexp(ex);
        }
Beispiel #23
0
        /// <summary>
        /// Equivalent to <code>luaK_exp2RK</code>. </summary>
        internal int kExp2RK(Expdesc e)
        {
            kExp2val(e);
            switch (e.k)
            {
            case Expdesc.VKNUM:
            case Expdesc.VTRUE:
            case Expdesc.VFALSE:
            case Expdesc.VNIL:
                if (nk <= Lua.MAXINDEXRK)         // constant fit in RK operand?
                {
                    e.info_Renamed = (e.k == Expdesc.VNIL) ? nilK() : (e.k == Expdesc.VKNUM) ? kNumberK(e.nval_Renamed) : boolK(e.k == Expdesc.VTRUE);
                    e.k            = Expdesc.VK;
                    return(e.info_Renamed | Lua.BITRK);
                }
                else
                {
                    break;
                }

            case Expdesc.VK:
                if (e.info_Renamed <= Lua.MAXINDEXRK)         // constant fit in argC?
                {
                    return(e.info_Renamed | Lua.BITRK);
                }
                else
                {
                    break;
                }

            default:
                break;
            }
            /* not a constant in the right range: put it in a register */
            return(kExp2anyreg(e));
        }
Beispiel #24
0
        /// <summary>
        /// Equivalent to luaK_infix. </summary>
        internal void kInfix(int op, Expdesc v)
        {
            switch (op)
            {
            case Syntax.OPR_AND:
                kGoiftrue(v);
                break;

            case Syntax.OPR_OR:
                kGoiffalse(v);
                break;

            case Syntax.OPR_CONCAT:
                kExp2nextreg(v);   // operand must be on the `stack'
                break;

            default:
                if (!isnumeral(v))
                {
                    kExp2RK(v);
                }
                break;
            }
        }
Beispiel #25
0
 private void exp2reg(Expdesc e, int reg)
 {
     discharge2reg(e, reg);
     if (e.k == Expdesc.VJMP)
     {
         e.t = kConcat(e.t, e.info_Renamed);   // put this jump in `t' list
     }
     if (e.hasjumps())
     {
         int p_f = NO_JUMP;   // position of an eventual LOAD false
         int p_t = NO_JUMP;   // position of an eventual LOAD true
         if (need_value(e.t) || need_value(e.f))
         {
             int fj = (e.k == Expdesc.VJMP) ? NO_JUMP : kJump();
             p_f = code_label(reg, 0, 1);
             p_t = code_label(reg, 1, 0);
             kPatchtohere(fj);
         }
         int finalpos = kGetlabel();   // position after whole expression
         patchlistaux(e.f, finalpos, reg, p_f);
         patchlistaux(e.t, finalpos, reg, p_t);
     }
     e.init(Expdesc.VNONRELOC, reg);
 }
Beispiel #26
0
 /// <summary>
 /// Equivalent to luaK_setmultret (in lcode.h). </summary>
 internal void kSetmultret(Expdesc e)
 {
     kSetreturns(e, Lua.MULTRET);
 }
Beispiel #27
0
        /// <summary>
        /// Equivalent to luaK_posfix. </summary>
        internal void kPosfix(int op, Expdesc e1, Expdesc e2)
        {
            switch (op)
            {
            case Syntax.OPR_AND:
                /* list must be closed */
                //# assert e1.t == NO_JUMP
                kDischargevars(e2);
                e2.f = kConcat(e2.f, e1.f);
                e1.init(e2);
                break;

            case Syntax.OPR_OR:
                /* list must be closed */
                //# assert e1.f == NO_JUMP
                kDischargevars(e2);
                e2.t = kConcat(e2.t, e1.t);
                e1.init(e2);
                break;

            case Syntax.OPR_CONCAT:
                kExp2val(e2);
                if (e2.k == Expdesc.VRELOCABLE && Lua.OPCODE(getcode(e2)) == Lua.OP_CONCAT)
                {
                    //# assert e1.info == Lua.ARGB(getcode(e2))-1
                    freeexp(e1);
                    setcode(e2, Lua.SETARG_B(getcode(e2), e1.info_Renamed));
                    e1.k            = e2.k;
                    e1.info_Renamed = e2.info_Renamed;
                }
                else
                {
                    kExp2nextreg(e2);       // operand must be on the 'stack'
                    codearith(Lua.OP_CONCAT, e1, e2);
                }
                break;

            case Syntax.OPR_ADD:
                codearith(Lua.OP_ADD, e1, e2);
                break;

            case Syntax.OPR_SUB:
                codearith(Lua.OP_SUB, e1, e2);
                break;

            case Syntax.OPR_MUL:
                codearith(Lua.OP_MUL, e1, e2);
                break;

            case Syntax.OPR_DIV:
                codearith(Lua.OP_DIV, e1, e2);
                break;

            case Syntax.OPR_MOD:
                codearith(Lua.OP_MOD, e1, e2);
                break;

            case Syntax.OPR_POW:
                codearith(Lua.OP_POW, e1, e2);
                break;

            case Syntax.OPR_EQ:
                codecomp(Lua.OP_EQ, true, e1, e2);
                break;

            case Syntax.OPR_NE:
                codecomp(Lua.OP_EQ, false, e1, e2);
                break;

            case Syntax.OPR_LT:
                codecomp(Lua.OP_LT, true, e1, e2);
                break;

            case Syntax.OPR_LE:
                codecomp(Lua.OP_LE, true, e1, e2);
                break;

            case Syntax.OPR_GT:
                codecomp(Lua.OP_LT, false, e1, e2);
                break;

            case Syntax.OPR_GE:
                codecomp(Lua.OP_LE, false, e1, e2);
                break;

            default:
                //# assert false
                break;
            }
        }
Beispiel #28
0
 internal void setcode(Expdesc e, int code)
 {
     f.code_Renamed[e.info_Renamed] = code;
 }
Beispiel #29
0
 internal int getcode(Expdesc e)
 {
     return(f.code_Renamed[e.info_Renamed]);
 }
Beispiel #30
0
        private bool constfolding(int op, Expdesc e1, Expdesc e2)
        {
            double r;

            if (!isnumeral(e1) || !isnumeral(e2))
            {
                return(false);
            }
            double v1 = e1.nval_Renamed;
            double v2 = e2.nval_Renamed;

            switch (op)
            {
            case Lua.OP_ADD:
                r = v1 + v2;
                break;

            case Lua.OP_SUB:
                r = v1 - v2;
                break;

            case Lua.OP_MUL:
                r = v1 * v2;
                break;

            case Lua.OP_DIV:
                if (v2 == 0.0)
                {
                    return(false);            // do not attempt to divide by 0
                }
                r = v1 / v2;
                break;

            case Lua.OP_MOD:
                if (v2 == 0.0)
                {
                    return(false);            // do not attempt to divide by 0
                }
                r = v1 % v2;
                break;

            case Lua.OP_POW:
                r = Lua.iNumpow(v1, v2);
                break;

            case Lua.OP_UNM:
                r = -v1;
                break;

            case Lua.OP_LEN:       // no constant folding for 'len'
                return(false);

            default:
                //# assert false
                r = 0.0;
                break;
            }
            if (double.IsNaN(r))
            {
                return(false);  // do not attempt to produce NaN
            }
            e1.nval_Renamed = r;
            return(true);
        }