예제 #1
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Initializer?.Compile(context, il);

            var start = il.DefineLabel();
            var end   = il.DefineLabel();

            il.MarkLabel(start);

            if (Predicate != null)
            {
                Predicate.Compile(context, il);
            }
            else
            {
                il.Emit(EmitOpCodes.Ldc_I4_1);
            }

            il.Emit(EmitOpCodes.Brfalse, end);

            Body.Compile(context, il);
            Incrementor?.Compile(context, il);
            il.Emit(EmitOpCodes.Br, start);

            il.MarkLabel(end);
        }
예제 #2
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Expression.Compile(context, il);

            var expressionType = Expression.GetExpressionType();
            EmitType voidType = typeof(void);
            if (expressionType.IsValueType && !context.Method.ReturnType.IsValueType && !Equals(expressionType, voidType))
            {
                il.Emit(EmitOpCodes.Box, Expression.GetExpressionType());
            }
            //            else if (!Expression.GetType(context.TypeSystem).IsValueType && !context.Method.ReturnType.IsValueType)
            //            {
            //
            //            }

            il.Emit(EmitOpCodes.Ret);
        }
예제 #3
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Expression.Compile(context, il);

            var      expressionType = Expression.GetExpressionType();
            EmitType voidType       = typeof(void);

            if (expressionType.IsValueType && !context.Method.ReturnType.IsValueType && !Equals(expressionType, voidType))
            {
                il.Emit(EmitOpCodes.Box, Expression.GetExpressionType());
            }
//            else if (!Expression.GetType(context.TypeSystem).IsValueType && !context.Method.ReturnType.IsValueType)
//            {
//
//            }

            il.Emit(EmitOpCodes.Ret);
        }
예제 #4
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     Expression.Compile(context, il);
     il.Emit(EmitOpCodes.Pop);
 }
예제 #5
0
 public abstract void Compile(EmitCompilerContext context, EmitIl il);
예제 #6
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     Expression.Compile(context, il);
     il.Emit(EmitOpCodes.Pop);
 }
예제 #7
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Operand.Compile(context, il);
            var operandType = Operand.GetExpressionType();

            EmitType typeInt = typeof(int);
            EmitType typeUint = typeof(uint);
            EmitType typeShort = typeof(short);
            EmitType typeUshort = typeof(ushort);
            EmitType typeByte = typeof(byte);
            EmitType typeSbyte = typeof(sbyte);
            EmitType typeLong = typeof(long);
            EmitType typeUlong = typeof(ulong);
            EmitType typeDouble = typeof(double);
            EmitType typeFloat = typeof(float);
            EmitType typeDecimal = typeof(decimal);
            EmitType typeBool = typeof(bool);

            var typeIs32Bit = Equals(Type, typeByte) || Equals(Type, typeShort) || Equals(Type, typeInt) || Equals(Type, typeSbyte) || Equals(Type, typeUshort) || Equals(Type, typeUint);
            var operandIs32Bit = Equals(operandType, typeByte) || Equals(operandType, typeShort) || Equals(operandType, typeInt) || Equals(operandType, typeSbyte) || Equals(operandType, typeUshort) || Equals(operandType, typeUint);
            var typeIsFloatingPoint = Equals(Type, typeFloat) || Equals(Type, typeDouble);
            var operandIsFloatingPoint = Equals(operandType, typeFloat) || Equals(operandType, typeDouble);

            if (operandIs32Bit || operandIsFloatingPoint || Equals(operandType, typeLong))
            {
                if (Equals(Type, operandType))
                {
                    return;
                }
                if (Equals(Type, typeFloat))
                {
                    il.Emit(EmitOpCodes.Conv_R4);
                    return;
                }
                if (Equals(Type, typeDouble))
                {
                    il.Emit(EmitOpCodes.Conv_R8);
                    return;
                }
                if (Equals(Type, typeByte))
                {
                    il.Emit(EmitOpCodes.Conv_U1);
                    return;
                }
                if (Equals(Type, typeSbyte))
                {
                    il.Emit(EmitOpCodes.Conv_I1);
                    return;
                }
                if (Equals(Type, typeShort))
                {
                    il.Emit(EmitOpCodes.Conv_I2);
                    return;
                }
                if (Equals(Type, typeUshort))
                {
                    il.Emit(EmitOpCodes.Conv_U2);
                    return;
                }
                if (Equals(Type, typeInt))
                {
                    il.Emit(EmitOpCodes.Conv_I4);
                    return;
                }
                if (Equals(Type, typeUint))
                {
                    il.Emit(EmitOpCodes.Conv_U4);
                    return;
                }
                if (Equals(Type, typeLong))
                {
                    il.Emit(EmitOpCodes.Conv_I8);
                    return;
                }
                if (Equals(Type, typeUlong))
                {
                    il.Emit(EmitOpCodes.Conv_U8);
                    return;
                }
            }

            // All else fails, then:
            il.Emit(EmitOpCodes.Castclass, Type);
        }
예제 #8
0
 public void SetData(EmitCompilerContext context, EmitLocal local)
 {
     context.Data[this] = local;
 }
예제 #9
0
 public EmitLocal GetData(EmitCompilerContext context)
 {
     return (EmitLocal)context.Data[this];
 }
예제 #10
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            switch (Operator)
            {
                case EmitUnaryOperator.BooleanNot:
                    Operand.Compile(context, il);
                    il.Emit(EmitOpCodes.Ldc_I4_0);
                    il.Emit(EmitOpCodes.Ceq);
                    break;
                case EmitUnaryOperator.BitwiseNot:
                    Operand.Compile(context, il);
                    il.Emit(EmitOpCodes.Not);
                    break;
                case EmitUnaryOperator.Minus:
                    Operand.Compile(context, il);
                    il.Emit(EmitOpCodes.Neg);
                    break;
                case EmitUnaryOperator.Plus:
                    Operand.Compile(context, il);
                    break;
                case EmitUnaryOperator.PostfixDecrement:
                {
                    Operand.Compile(context, il);

                    var local = il.DeclareLocal(Operand.GetExpressionType());
                    il.Emit(EmitOpCodes.Stloc, local);

                    ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                        il.Emit(EmitOpCodes.Ldc_I4_1);
                        il.Emit(EmitOpCodes.Sub);
                    });

                    il.Emit(EmitOpCodes.Pop);
                    il.Emit(EmitOpCodes.Ldloc, local);

                    break;
                }
                case EmitUnaryOperator.PostfixIncrement:
                {
                    Operand.Compile(context, il);

                    var local = il.DeclareLocal(Operand.GetExpressionType());
                    il.Emit(EmitOpCodes.Stloc, local);

                    ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                        il.Emit(EmitOpCodes.Ldc_I4_1);
                        il.Emit(EmitOpCodes.Add);
                    });

                    il.Emit(EmitOpCodes.Pop);
                    il.Emit(EmitOpCodes.Ldloc, local);

                    break;
                }
                case EmitUnaryOperator.PrefixDecrement:
                {
                    Operand.Compile(context, il);
                    il.Emit(EmitOpCodes.Ldc_I4_1);
                    il.Emit(EmitOpCodes.Sub);

                    var local = il.DeclareLocal(Operand.GetExpressionType());
                    il.Emit(EmitOpCodes.Stloc, local);

                    ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                    });
                    break;
                }
                case EmitUnaryOperator.PrefixIncrement:
                {
                    Operand.Compile(context, il);
                    il.Emit(EmitOpCodes.Ldc_I4_1);
                    il.Emit(EmitOpCodes.Add);

                    var local = il.DeclareLocal(Operand.GetExpressionType());
                    il.Emit(EmitOpCodes.Stloc, local);

                    ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                    });
                    break;
                }
            }
        }
예제 #11
0
 public void SetData(EmitCompilerContext context, EmitLocal local)
 {
     context.Data[this] = local;
 }
예제 #12
0
 public EmitLocal GetData(EmitCompilerContext context)
 {
     return((EmitLocal)context.Data[this]);
 }
예제 #13
0
 public abstract void Compile(EmitCompilerContext context, EmitIl il);
예제 #14
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            switch (Operator)
            {
            case EmitUnaryOperator.BooleanNot:
                Operand.Compile(context, il);
                il.Emit(EmitOpCodes.Ldc_I4_0);
                il.Emit(EmitOpCodes.Ceq);
                break;

            case EmitUnaryOperator.BitwiseNot:
                Operand.Compile(context, il);
                il.Emit(EmitOpCodes.Not);
                break;

            case EmitUnaryOperator.Minus:
                Operand.Compile(context, il);
                il.Emit(EmitOpCodes.Neg);
                break;

            case EmitUnaryOperator.Plus:
                Operand.Compile(context, il);
                break;

            case EmitUnaryOperator.PostfixDecrement:
            {
                Operand.Compile(context, il);

                var local = il.DeclareLocal(Operand.GetExpressionType());
                il.Emit(EmitOpCodes.Stloc, local);

                ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                        il.Emit(EmitOpCodes.Ldc_I4_1);
                        il.Emit(EmitOpCodes.Sub);
                    });

                il.Emit(EmitOpCodes.Pop);
                il.Emit(EmitOpCodes.Ldloc, local);

                break;
            }

            case EmitUnaryOperator.PostfixIncrement:
            {
                Operand.Compile(context, il);

                var local = il.DeclareLocal(Operand.GetExpressionType());
                il.Emit(EmitOpCodes.Stloc, local);

                ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                        il.Emit(EmitOpCodes.Ldc_I4_1);
                        il.Emit(EmitOpCodes.Add);
                    });

                il.Emit(EmitOpCodes.Pop);
                il.Emit(EmitOpCodes.Ldloc, local);

                break;
            }

            case EmitUnaryOperator.PrefixDecrement:
            {
                Operand.Compile(context, il);
                il.Emit(EmitOpCodes.Ldc_I4_1);
                il.Emit(EmitOpCodes.Sub);

                var local = il.DeclareLocal(Operand.GetExpressionType());
                il.Emit(EmitOpCodes.Stloc, local);

                ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                    });
                break;
            }

            case EmitUnaryOperator.PrefixIncrement:
            {
                Operand.Compile(context, il);
                il.Emit(EmitOpCodes.Ldc_I4_1);
                il.Emit(EmitOpCodes.Add);

                var local = il.DeclareLocal(Operand.GetExpressionType());
                il.Emit(EmitOpCodes.Stloc, local);

                ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () =>
                    {
                        il.Emit(EmitOpCodes.Ldloc, local);
                    });
                break;
            }
            }
        }
예제 #15
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Operand.Compile(context, il);
            var operandType = Operand.GetExpressionType();

            EmitType typeInt     = typeof(int);
            EmitType typeUint    = typeof(uint);
            EmitType typeShort   = typeof(short);
            EmitType typeUshort  = typeof(ushort);
            EmitType typeByte    = typeof(byte);
            EmitType typeSbyte   = typeof(sbyte);
            EmitType typeLong    = typeof(long);
            EmitType typeUlong   = typeof(ulong);
            EmitType typeDouble  = typeof(double);
            EmitType typeFloat   = typeof(float);
            EmitType typeDecimal = typeof(decimal);
            EmitType typeBool    = typeof(bool);

            var typeIs32Bit            = Equals(Type, typeByte) || Equals(Type, typeShort) || Equals(Type, typeInt) || Equals(Type, typeSbyte) || Equals(Type, typeUshort) || Equals(Type, typeUint);
            var operandIs32Bit         = Equals(operandType, typeByte) || Equals(operandType, typeShort) || Equals(operandType, typeInt) || Equals(operandType, typeSbyte) || Equals(operandType, typeUshort) || Equals(operandType, typeUint);
            var typeIsFloatingPoint    = Equals(Type, typeFloat) || Equals(Type, typeDouble);
            var operandIsFloatingPoint = Equals(operandType, typeFloat) || Equals(operandType, typeDouble);

            if (operandIs32Bit || operandIsFloatingPoint || Equals(operandType, typeLong))
            {
                if (Equals(Type, operandType))
                {
                    return;
                }
                if (Equals(Type, typeFloat))
                {
                    il.Emit(EmitOpCodes.Conv_R4);
                    return;
                }
                if (Equals(Type, typeDouble))
                {
                    il.Emit(EmitOpCodes.Conv_R8);
                    return;
                }
                if (Equals(Type, typeByte))
                {
                    il.Emit(EmitOpCodes.Conv_U1);
                    return;
                }
                if (Equals(Type, typeSbyte))
                {
                    il.Emit(EmitOpCodes.Conv_I1);
                    return;
                }
                if (Equals(Type, typeShort))
                {
                    il.Emit(EmitOpCodes.Conv_I2);
                    return;
                }
                if (Equals(Type, typeUshort))
                {
                    il.Emit(EmitOpCodes.Conv_U2);
                    return;
                }
                if (Equals(Type, typeInt))
                {
                    il.Emit(EmitOpCodes.Conv_I4);
                    return;
                }
                if (Equals(Type, typeUint))
                {
                    il.Emit(EmitOpCodes.Conv_U4);
                    return;
                }
                if (Equals(Type, typeLong))
                {
                    il.Emit(EmitOpCodes.Conv_I8);
                    return;
                }
                if (Equals(Type, typeUlong))
                {
                    il.Emit(EmitOpCodes.Conv_U8);
                    return;
                }
            }

            // All else fails, then:
            il.Emit(EmitOpCodes.Castclass, Type);
        }