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); }
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); }