Exemple #1
0
 public static void SetReturns(FuncState fs, ExpDesc e, int nResults)
 {
     if (e.Kind == ExpKind.VCALL)                // expression is an open function call?
     {
         var pi = fs.GetCode(e);
         pi.Value = pi.Value.SETARG_C(nResults + 1);
     }
     else if (e.Kind == ExpKind.VVARARG)
     {
         var pi = fs.GetCode(e);
         pi.Value = pi.Value.SETARG_B(nResults + 1).SETARG_A(fs.FreeReg);
         ReserveRegs(fs, 1);
     }
 }
Exemple #2
0
 public static void SetOneRet(FuncState fs, ExpDesc e)
 {
     // expression is an open function call?
     if (e.Kind == ExpKind.VCALL)
     {
         e.Kind = ExpKind.VNONRELOC;
         e.Info = (fs.GetCode(e)).Value.GETARG_A();
     }
     else if (e.Kind == ExpKind.VVARARG)
     {
         var pi = fs.GetCode(e);
         pi.Value = pi.Value.SETARG_B(2);
         e.Kind   = ExpKind.VRELOCABLE;               // can relocate its simple result
     }
 }
Exemple #3
0
        private static void Discharge2Reg(FuncState fs, ExpDesc e, int reg)
        {
            DischargeVars(fs, e);
            switch (e.Kind)
            {
            case ExpKind.VNIL:
            {
                CodeNil(fs, reg, 1);
                break;
            }

            case ExpKind.VFALSE:
            case ExpKind.VTRUE:
            {
                CodeABC(fs, OpCode.OP_LOADBOOL, reg,
                        (e.Kind == ExpKind.VTRUE ? 1 : 0), 0);
                break;
            }

            case ExpKind.VK:
            {
                CodeK(fs, reg, e.Info);
                break;
            }

            case ExpKind.VKNUM:
            {
                CodeK(fs, reg, NumberK(fs, e.NumberValue));
                break;
            }

            case ExpKind.VRELOCABLE:
            {
                InstructionPtr pi = fs.GetCode(e);
                pi.Value = pi.Value.SETARG_A(reg);
                break;
            }

            case ExpKind.VNONRELOC:
            {
                if (reg != e.Info)
                {
                    CodeABC(fs, OpCode.OP_MOVE, reg, e.Info, 0);
                }
                break;
            }

            default:
            {
                Utl.Assert(e.Kind == ExpKind.VVOID || e.Kind == ExpKind.VJMP);
                return;         // nothing to do...
            }
            }
            e.Info = reg;
            e.Kind = ExpKind.VNONRELOC;
        }
Exemple #4
0
 private static int JumpOnCond(FuncState fs, ExpDesc e, bool cond)
 {
     if (e.Kind == ExpKind.VRELOCABLE)
     {
         Instruction ie = fs.GetCode(e).Value;
         if (ie.GET_OPCODE() == OpCode.OP_NOT)
         {
             fs.Pc--;                     // remove previous OP_NOT
             return(CondJump(fs, OpCode.OP_TEST, ie.GETARG_B(), 0,
                             (cond ? 0 : 1)));
         }
         // else go through
     }
     Discharge2AnyReg(fs, e);
     FreeExp(fs, e);
     return(CondJump(fs, OpCode.OP_TESTSET, NO_REG, e.Info,
                     (cond ? 1 : 0)));
 }
Exemple #5
0
		private static void Discharge2Reg( FuncState fs, ExpDesc e, int reg )
		{
			DischargeVars( fs, e );
			switch( e.Kind )
			{
				case ExpKind.VNIL: {
					CodeNil( fs, reg, 1 );
					break;
				}
				case ExpKind.VFALSE:
				case ExpKind.VTRUE: {
					CodeABC( fs, OpCode.OP_LOADBOOL, reg,
						(e.Kind == ExpKind.VTRUE ? 1 : 0), 0 );
					break;
				}
				case ExpKind.VK: {
					CodeK( fs, reg, e.Info );
					break;
				}
				case ExpKind.VKNUM: {
					CodeK( fs, reg, NumberK( fs, e.NumberValue ) );
					break;
				}
				case ExpKind.VRELOCABLE: {
					InstructionPtr pi = fs.GetCode(e);
					pi.Value = pi.Value.SETARG_A(reg);
					break;
				}
				case ExpKind.VNONRELOC: {
					if( reg != e.Info )
						CodeABC( fs, OpCode.OP_MOVE, reg, e.Info, 0 );
					break;
				}
				default: {
					Utl.Assert( e.Kind == ExpKind.VVOID || e.Kind == ExpKind.VJMP );
					return; // nothing to do...
				}
			}
			e.Info = reg;
			e.Kind = ExpKind.VNONRELOC;
		}
Exemple #6
0
		public static void Posfix( FuncState fs, BinOpr op,
			ExpDesc e1, ExpDesc e2, int line )
		{
			// Debug.Log(">> POSFIX op:" + op);
			switch( op )
			{
				case BinOpr.AND: {
					Utl.Assert( e1.ExitTrue == NO_JUMP );
					DischargeVars( fs, e2 );
					e2.ExitFalse = Concat( fs, e2.ExitFalse, e1.ExitFalse );
					e1.CopyFrom( e2 );
					break;
				}
				case BinOpr.OR: {
					Utl.Assert( e1.ExitFalse == NO_JUMP );
					DischargeVars( fs, e2 );
					e2.ExitTrue = Concat( fs, e2.ExitTrue, e1.ExitTrue );
					e1.CopyFrom( e2 );
					break;
				}
				case BinOpr.CONCAT: {
					Exp2Val( fs, e2 );
					var pe2 = fs.GetCode( e2 );
					if( e2.Kind == ExpKind.VRELOCABLE &&
						pe2.Value.GET_OPCODE() == OpCode.OP_CONCAT )
					{
						Utl.Assert( e1.Info == pe2.Value.GETARG_B()-1 );
						FreeExp( fs, e1 );
						pe2.Value = pe2.Value.SETARG_B( e1.Info );
						e1.Kind = ExpKind.VRELOCABLE;
						e1.Info = e2.Info;
					}
					else
					{
						// operand must be on the `stack'
						Exp2NextReg( fs, e2 );
						CodeArith( fs, OpCode.OP_CONCAT, e1, e2, line );
					}
					break;
				}
				case BinOpr.ADD: {
					CodeArith( fs, OpCode.OP_ADD, e1, e2, line);
					break;
				}
				case BinOpr.SUB: {
					CodeArith( fs, OpCode.OP_SUB, e1, e2, line);
					break;
				}
				case BinOpr.MUL: {
					CodeArith( fs, OpCode.OP_MUL, e1, e2, line);
					break;
				}
				case BinOpr.DIV: {
					CodeArith( fs, OpCode.OP_DIV, e1, e2, line);
					break;
				}
				case BinOpr.MOD: {
					CodeArith( fs, OpCode.OP_MOD, e1, e2, line);
					break;
				}
				case BinOpr.POW: {
					CodeArith( fs, OpCode.OP_POW, e1, e2, line);
					break;
				}
				case BinOpr.EQ: {
					CodeComp( fs, OpCode.OP_EQ, 1, e1, e2 );
					break;
				}
				case BinOpr.LT: {
					CodeComp( fs, OpCode.OP_LT, 1, e1, e2 );
					break;
				}
				case BinOpr.LE: {
					CodeComp( fs, OpCode.OP_LE, 1, e1, e2 );
					break;
				}
				case BinOpr.NE: {
					CodeComp( fs, OpCode.OP_EQ, 0, e1, e2 );
					break;
				}
				case BinOpr.GT: {
					CodeComp( fs, OpCode.OP_LT, 0, e1, e2 );
					break;
				}
				case BinOpr.GE: {
					CodeComp( fs, OpCode.OP_LE, 0, e1, e2 );
					break;
				}
				default: Utl.Assert(false); break;
			}
		}
Exemple #7
0
		private static int JumpOnCond( FuncState fs, ExpDesc e, bool cond )
		{
			// Debug.Log("--------------- 2 ----------JumpOnCond k:" + e.Kind );
			if( e.Kind == ExpKind.VRELOCABLE )
			{
				Instruction ie = fs.GetCode( e ).Value;
				if( ie.GET_OPCODE() == OpCode.OP_NOT )
				{
					fs.Pc--; // remove previous OP_NOT
					return CondJump( fs, OpCode.OP_TEST, ie.GETARG_B(), 0,
						(cond ? 0 : 1) );
				}
				// else go through
			}
			Discharge2AnyReg( fs, e );
			FreeExp( fs, e );
			return CondJump( fs, OpCode.OP_TESTSET, NO_REG, e.Info,
				(cond ? 1 : 0) );
		}
Exemple #8
0
		public static void SetOneRet( FuncState fs, ExpDesc e )
		{
			// expression is an open function call?
			if( e.Kind == ExpKind.VCALL )
			{
				e.Kind = ExpKind.VNONRELOC;
				e.Info = ( fs.GetCode( e ) ).Value.GETARG_A();
			}
			else if( e.Kind == ExpKind.VVARARG )
			{
				var pi = fs.GetCode( e );
				pi.Value = pi.Value.SETARG_B( 2 );
				e.Kind = ExpKind.VRELOCABLE; // can relocate its simple result
			}
		}
Exemple #9
0
		public static void SetReturns( FuncState fs, ExpDesc e, int nResults )
		{
			if( e.Kind == ExpKind.VCALL ) { // expression is an open function call?
				var pi = fs.GetCode(e);
				pi.Value = pi.Value.SETARG_C( nResults+1 );
			}
			else if( e.Kind == ExpKind.VVARARG ) {
				var pi = fs.GetCode(e);
				pi.Value = pi.Value.SETARG_B( nResults+1 ).SETARG_A( fs.FreeReg );
				ReserveRegs( fs, 1 );
			}
		}
Exemple #10
0
        public static void Posfix(FuncState fs, BinOpr op,
                                  ExpDesc e1, ExpDesc e2, int line)
        {
            switch (op)
            {
            case BinOpr.AND: {
                Utl.Assert(e1.ExitTrue == NO_JUMP);
                DischargeVars(fs, e2);
                e2.ExitFalse = Concat(fs, e2.ExitFalse, e1.ExitFalse);
                e1.CopyFrom(e2);
                break;
            }

            case BinOpr.OR: {
                Utl.Assert(e1.ExitFalse == NO_JUMP);
                DischargeVars(fs, e2);
                e2.ExitTrue = Concat(fs, e2.ExitTrue, e1.ExitTrue);
                e1.CopyFrom(e2);
                break;
            }

            case BinOpr.CONCAT: {
                Exp2Val(fs, e2);
                var pe2 = fs.GetCode(e2);
                if (e2.Kind == ExpKind.VRELOCABLE &&
                    pe2.Value.GET_OPCODE() == OpCode.OP_CONCAT)
                {
                    Utl.Assert(e1.Info == pe2.Value.GETARG_B() - 1);
                    FreeExp(fs, e1);
                    pe2.Value = pe2.Value.SETARG_B(e1.Info);
                    e1.Kind   = ExpKind.VRELOCABLE;
                    e1.Info   = e2.Info;
                }
                else
                {
                    // operand must be on the `stack'
                    Exp2NextReg(fs, e2);
                    CodeArith(fs, OpCode.OP_CONCAT, e1, e2, line);
                }
                break;
            }

            case BinOpr.ADD: {
                CodeArith(fs, OpCode.OP_ADD, e1, e2, line);
                break;
            }

            case BinOpr.SUB: {
                CodeArith(fs, OpCode.OP_SUB, e1, e2, line);
                break;
            }

            case BinOpr.MUL: {
                CodeArith(fs, OpCode.OP_MUL, e1, e2, line);
                break;
            }

            case BinOpr.DIV: {
                CodeArith(fs, OpCode.OP_DIV, e1, e2, line);
                break;
            }

            case BinOpr.MOD: {
                CodeArith(fs, OpCode.OP_MOD, e1, e2, line);
                break;
            }

            case BinOpr.POW: {
                CodeArith(fs, OpCode.OP_POW, e1, e2, line);
                break;
            }

            case BinOpr.EQ: {
                CodeComp(fs, OpCode.OP_EQ, 1, e1, e2);
                break;
            }

            case BinOpr.LT: {
                CodeComp(fs, OpCode.OP_LT, 1, e1, e2);
                break;
            }

            case BinOpr.LE: {
                CodeComp(fs, OpCode.OP_LE, 1, e1, e2);
                break;
            }

            case BinOpr.NE: {
                CodeComp(fs, OpCode.OP_EQ, 0, e1, e2);
                break;
            }

            case BinOpr.GT: {
                CodeComp(fs, OpCode.OP_LT, 0, e1, e2);
                break;
            }

            case BinOpr.GE: {
                CodeComp(fs, OpCode.OP_LE, 0, e1, e2);
                break;
            }

            default:
                throw new NotImplementedException(string.Format("opcode {0}({1}, {2}) @line:{3}", op, e1, e2, line));
            }
        }