Beispiel #1
0
        public static void Self(FuncState fs, ExpDesc e, ExpDesc key)
        {
            Exp2AnyReg(fs, e);
            int ereg = e.Info;             // register where `e' is placed

            FreeExp(fs, e);
            e.Info = fs.FreeReg;             // base register for op_self
            e.Kind = ExpKind.VNONRELOC;
            ReserveRegs(fs, 2);
            CodeABC(fs, OpCode.OP_SELF, e.Info, ereg, Coder.Exp2RK(fs, key));
            FreeExp(fs, key);
        }
Beispiel #2
0
        private int FindSetReg(LuaProto proto, int lastpc, int reg)
        {
            var setreg = -1;             // keep last instruction that changed `reg'

            for (int pc = 0; pc < lastpc; ++pc)
            {
                var ins = proto.Code[pc];
                var op  = ins.GET_OPCODE();
                var a   = ins.GETARG_A();
                switch (op)
                {
                case OpCode.OP_LOADNIL: {
                    var b = ins.GETARG_B();
                    // set registers from `a' to `a+b'
                    if (a <= reg && reg <= a + b)
                    {
                        setreg = pc;
                    }
                    break;
                }

                case OpCode.OP_TFORCALL: {
                    // effect all regs above its base
                    if (reg >= a + 2)
                    {
                        setreg = pc;
                    }
                    break;
                }

                case OpCode.OP_CALL:
                case OpCode.OP_TAILCALL: {
                    // effect all registers above base
                    if (reg >= a)
                    {
                        setreg = pc;
                    }
                    break;
                }

                case OpCode.OP_JMP: {
                    var b    = ins.GETARG_sBx();
                    var dest = pc + 1 + b;
                    // jump is forward and do not skip `lastpc'
                    if (pc < dest && dest <= lastpc)
                    {
                        pc += b;                                 // do the jump
                    }
                    break;
                }

                case OpCode.OP_TEST: {
                    // jumped code can change `a'
                    if (reg == a)
                    {
                        setreg = pc;
                    }
                    break;
                }

                default: {
                    // any instruction that set A
                    if (Coder.TestAMode(op) && reg == a)
                    {
                        setreg = pc;
                    }
                    break;
                }
                }
            }
            return(setreg);
        }