Example #1
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     foreach (var statement in Statements)
     {
         statement.Compile(context, il);
     }
 }
Example #2
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var arrayType = GetExpressionType();

            if (Lengths.Count == 1)
            {
                il.Emit(EmitOpCodes.Ldc_I4, Lengths[0]);
                il.Emit(EmitOpCodes.Newarr, Type);
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = (EmitExpression)Initializer[i];
                    il.Emit(EmitOpCodes.Dup);
                    il.Emit(EmitOpCodes.Ldc_I4, i);
                    element.Compile(context, il);
                    il.Emit(EmitOpCodes.Stelem, Type);
                }
            }
            else
            {
                var constructor = arrayType.Members.OfType <EmitConstructor>().Single(x => x.Parameters.Count() == Rank);
                var setter      = arrayType.Members.OfType <EmitMethod>().Single(x => x.Name == "Set");
                foreach (var length in Lengths)
                {
                    il.Emit(EmitOpCodes.Ldc_I4, length);
                }
                il.Emit(EmitOpCodes.Newobj, constructor);

                var indices = new int[Lengths.Count];
                Action <int, IEmitArrayElement> recurse = null;
                recurse = (level, element) =>
                {
                    if (level == Rank - 1)
                    {
                        var expression = (EmitExpression)element;
                        il.Emit(EmitOpCodes.Dup);
                        foreach (var index in indices)
                        {
                            il.Emit(EmitOpCodes.Ldc_I4, index);
                        }
                        expression.Compile(context, il);
                        il.Emit(EmitOpCodes.Call, setter);
                    }
                    else
                    {
                        for (var i = 0; i < element.Length; i++)
                        {
                            indices[level + 1] = i;
                            var current = element[i];
                            recurse(level + 1, current);
                        }
                    }
                };
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = Initializer[i];
                    indices[0] = i;
                    recurse(0, element);
                }
            }
        }
Example #3
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Condition.Compile(context, il);
            var ifNotTrue = il.DefineLabel();
            il.Emit(EmitOpCodes.Brfalse, ifNotTrue);
            Statement.Compile(context, il);
            var statementReturned = il.Instructions.Last().OpCode == EmitOpCodes.Ret;

            if (Else != null)
            {
                EmitLabel end = null;
                if (!statementReturned)
                {
                    end = il.DefineLabel();
                    il.Emit(EmitOpCodes.Br, end);
                }
                il.MarkLabel(ifNotTrue);
                Else.Compile(context, il);
                if (!statementReturned)
                {
                    il.MarkLabel(end);
                    il.Emit(EmitOpCodes.Nop);
                }
            }
            else
            {
                il.MarkLabel(ifNotTrue);
            }
        }
Example #4
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Condition.Compile(context, il);
            var ifNotTrue = il.DefineLabel();

            il.Emit(EmitOpCodes.Brfalse, ifNotTrue);
            Statement.Compile(context, il);
            var statementReturned = il.Instructions.Last().OpCode == EmitOpCodes.Ret;

            if (Else != null)
            {
                EmitLabel end = null;
                if (!statementReturned)
                {
                    end = il.DefineLabel();
                    il.Emit(EmitOpCodes.Br, end);
                }
                il.MarkLabel(ifNotTrue);
                Else.Compile(context, il);
                if (!statementReturned)
                {
                    il.MarkLabel(end);
                    il.Emit(EmitOpCodes.Nop);
                }
            }
            else
            {
                il.MarkLabel(ifNotTrue);
            }
        }
Example #5
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            switch (Operator)
            {
            case EmitBinaryOperator.Assign:
                ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => Right.Compile(context, il));
                break;

            case EmitBinaryOperator.BooleanAnd:
                Left.Compile(context, il);
                il.Emit(EmitOpCodes.Dup);

                var andEnd = il.DefineLabel();
                il.Emit(EmitOpCodes.Brfalse, andEnd);
                il.Emit(EmitOpCodes.Pop);

                Right.Compile(context, il);
                il.MarkLabel(andEnd);

                break;

            case EmitBinaryOperator.BooleanOr:
                Left.Compile(context, il);
                il.Emit(EmitOpCodes.Dup);

                var orEnd = il.DefineLabel();
                il.Emit(EmitOpCodes.Brtrue, orEnd);
                il.Emit(EmitOpCodes.Pop);

                Right.Compile(context, il);
                il.MarkLabel(orEnd);

                break;

            default:
                var instruction  = GetOpCode();
                var isInverted   = IsOperatorInverse();
                var isAssignment = IsOperatorAssignment();

                Left.Compile(context, il);
                Right.Compile(context, il);

                il.Emit(instruction);

                if (isInverted)
                {
                    il.Emit(EmitOpCodes.Ldc_I4_0);
                    il.Emit(EmitOpCodes.Ceq);
                }

                if (isAssignment)
                {
                    var local = il.DeclareLocal(typeof(bool));
                    il.Emit(EmitOpCodes.Stloc, local);
                    ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => il.Emit(EmitOpCodes.Ldloc, local));
                }

                break;
            }
        }
Example #6
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Value == null)
     {
         il.Emit(EmitOpCodes.Ldnull);
     }
     else if (Value is int)
     {
         il.Emit(EmitOpCodes.Ldc_I4, (int)Value);
     }
     else if (Value is long)
     {
         il.Emit(EmitOpCodes.Ldc_I8, (long)Value);
     }
     else if (Value is float)
     {
         il.Emit(EmitOpCodes.Ldc_R4, (float)Value);
     }
     else if (Value is double)
     {
         il.Emit(EmitOpCodes.Ldc_R8, (double)Value);
     }
     else if (Value is bool)
     {
         il.Emit(EmitOpCodes.Ldc_I4, (bool)Value ? 1 : 0);
     }
     else if (Value is string)
     {
         il.Emit(EmitOpCodes.Ldstr, (string)Value);
     }
     else
     {
         throw new Exception();
     }
 }
Example #7
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);
        }
        public void CompileAssignment(EmitCompilerContext context, EmitIl il, Action compileValue)
        {
            var local = Variable.GetData(context);

            compileValue();
            il.Emit(EmitOpCodes.Dup);       // We want to leave the assigned value on the stack, since assignment is an expression
            il.Emit(EmitOpCodes.Stloc, local);
        }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     foreach (var variable in Variables)
     {
         var local = il.DeclareLocal(variable.Type);
         variable.SetData(context, local);
     }
 }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var arrayType = GetExpressionType();

            if (Lengths.Count == 1)
            {
                il.Emit(EmitOpCodes.Ldc_I4, Lengths[0]);
                il.Emit(EmitOpCodes.Newarr, Type);
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = (EmitExpression)Initializer[i];
                    il.Emit(EmitOpCodes.Dup);
                    il.Emit(EmitOpCodes.Ldc_I4, i);
                    element.Compile(context, il);
                    il.Emit(EmitOpCodes.Stelem, Type);
                }
            }
            else
            {
                var constructor = arrayType.Members.OfType<EmitConstructor>().Single(x => x.Parameters.Count() == Rank);
                var setter = arrayType.Members.OfType<EmitMethod>().Single(x => x.Name == "Set");
                foreach (var length in Lengths)
                    il.Emit(EmitOpCodes.Ldc_I4, length);
                il.Emit(EmitOpCodes.Newobj, constructor);

                var indices = new int[Lengths.Count];
                Action<int, IEmitArrayElement> recurse = null;
                recurse = (level, element) =>
                {
                    if (level == Rank - 1)
                    {
                        var expression = (EmitExpression)element;
                        il.Emit(EmitOpCodes.Dup);
                        foreach (var index in indices)
                        {
                            il.Emit(EmitOpCodes.Ldc_I4, index);
                        }
                        expression.Compile(context, il);
                        il.Emit(EmitOpCodes.Call, setter);
                    }
                    else
                    {
                        for (var i = 0; i < element.Length; i++)
                        {
                            indices[level + 1] = i;
                            var current = element[i];
                            recurse(level + 1, current);
                        }
                    }
                };
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = Initializer[i];
                    indices[0] = i;
                    recurse(0, element);
                }
            }
        }
Example #11
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            switch (Operator)
            {
                case EmitBinaryOperator.Assign:
                    ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => Right.Compile(context, il));
                    break;
                case EmitBinaryOperator.BooleanAnd:
                    Left.Compile(context, il);
                    il.Emit(EmitOpCodes.Dup);

                    var andEnd = il.DefineLabel();
                    il.Emit(EmitOpCodes.Brfalse, andEnd);
                    il.Emit(EmitOpCodes.Pop);

                    Right.Compile(context, il);
                    il.MarkLabel(andEnd);

                    break;
                case EmitBinaryOperator.BooleanOr:
                    Left.Compile(context, il);
                    il.Emit(EmitOpCodes.Dup);

                    var orEnd = il.DefineLabel();
                    il.Emit(EmitOpCodes.Brtrue, orEnd);
                    il.Emit(EmitOpCodes.Pop);

                    Right.Compile(context, il);
                    il.MarkLabel(orEnd);

                    break;
                default:
                    var instruction = GetOpCode();
                    var isInverted = IsOperatorInverse();
                    var isAssignment = IsOperatorAssignment();

                    Left.Compile(context, il);
                    Right.Compile(context, il);

                    il.Emit(instruction);

                    if (isInverted)
                    {
                        il.Emit(EmitOpCodes.Ldc_I4_0);
                        il.Emit(EmitOpCodes.Ceq);
                    }

                    if (isAssignment)
                    {
                        var local = il.DeclareLocal(typeof(bool));
                        il.Emit(EmitOpCodes.Stloc, local);
                        ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => il.Emit(EmitOpCodes.Ldloc, local));
                    }

                    break;
            }
        }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            if (Arguments.Count != Method.Parameters.Count())
                throw new Exception($"Incorrect number of arguments passed to method {Method}");

            Target?.Compile(context, il);
            foreach (var argument in Arguments)
                argument.Compile(context, il);

            var opCode = Method.IsVirtual || Method.DeclaringType.IsInterface ? (IEmitOpCodeMethod)EmitOpCodes.Callvirt : EmitOpCodes.Call;

            il.Emit(opCode, Method);
        }
Example #13
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);
        }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            if (Arguments.Count != Method.Parameters.Count())
            {
                throw new Exception($"Incorrect number of arguments passed to method {Method}");
            }

            Target?.Compile(context, il);
            foreach (var argument in Arguments)
            {
                argument.Compile(context, il);
            }

            var opCode = Method.IsVirtual || Method.DeclaringType.IsInterface ? (IEmitOpCodeMethod)EmitOpCodes.Callvirt : EmitOpCodes.Call;

            il.Emit(opCode, Method);
        }
Example #15
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);
        }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Lengths.Count == 1)
     {
         Lengths[0].Compile(context, il);
         il.Emit(EmitOpCodes.Newarr, Type);
     }
     else
     {
         var arrayType = GetExpressionType();
         var constructor = arrayType.Members.OfType<EmitConstructor>().Single(x => x.Parameters.Count() == Lengths.Count);
         foreach (var length in Lengths)
         {
             length.Compile(context, il);
         }
         il.Emit(EmitOpCodes.Newobj, constructor);
     }
 }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Lengths.Count == 1)
     {
         Lengths[0].Compile(context, il);
         il.Emit(EmitOpCodes.Newarr, Type);
     }
     else
     {
         var arrayType   = GetExpressionType();
         var constructor = arrayType.Members.OfType <EmitConstructor>().Single(x => x.Parameters.Count() == Lengths.Count);
         foreach (var length in Lengths)
         {
             length.Compile(context, il);
         }
         il.Emit(EmitOpCodes.Newobj, constructor);
     }
 }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            // Special handling for value types without a constructor
            if (Constructor == null)
            {
                var local = il.DeclareLocal(Type);
                il.Emit(EmitOpCodes.Ldloca, local);
                il.Emit(EmitOpCodes.Initobj, Type);
                il.Emit(EmitOpCodes.Ldloc, local);
                return;
            }

            foreach (var argument in Arguments)
            {
                argument.Compile(context, il);
            }

            il.Emit(EmitOpCodes.Newobj, Constructor);
        }
Example #19
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Value == null)
         il.Emit(EmitOpCodes.Ldnull);
     else if (Value is int)
         il.Emit(EmitOpCodes.Ldc_I4, (int)Value);
     else if (Value is long)
         il.Emit(EmitOpCodes.Ldc_I8, (long)Value);
     else if (Value is float)
         il.Emit(EmitOpCodes.Ldc_R4, (float)Value);
     else if (Value is double)
         il.Emit(EmitOpCodes.Ldc_R8, (double)Value);
     else if (Value is bool)
         il.Emit(EmitOpCodes.Ldc_I4, (bool)Value ? 1 : 0);
     else if (Value is string)
         il.Emit(EmitOpCodes.Ldstr, (string)Value);
     else
         throw new Exception();
 }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            // Special handling for value types without a constructor
            if (Constructor == null)
            {
                var local = il.DeclareLocal(Type);
                il.Emit(EmitOpCodes.Ldloca, local);
                il.Emit(EmitOpCodes.Initobj, Type);
                il.Emit(EmitOpCodes.Ldloc, local);
                return;
            }

            foreach (var argument in Arguments)
            {
                argument.Compile(context, il);
            }

            il.Emit(EmitOpCodes.Newobj, Constructor);
        }
Example #21
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var item = il.DeclareLocal(Item.Type);

            Item.SetData(context, item);

            EmitType genericEnumerableType = typeof(IEnumerable <>);
            var      enumerableType        = genericEnumerableType.MakeGenericType(Item.Type);
            var      getEnumeratorMethod   = enumerableType.Members.OfType <EmitMethod>().Single(x => x.Name == nameof(IEnumerable <object> .GetEnumerator));

            EmitType genericEnumeratorType = typeof(IEnumerator <>);
            var      enumeratorType        = genericEnumeratorType.MakeGenericType(Item.Type);
            var      moveNextMethod        = enumerableType.Members.OfType <EmitMethod>().Single(x => x.Name == nameof(IEnumerator <object> .MoveNext));
            var      getCurrentMethod      = enumerableType.Members.OfType <EmitProperty>().Single(x => x.Name == nameof(IEnumerator <object> .Current)).GetMethod;

            var enumerator = il.DeclareLocal(enumeratorType);

            Collection.Compile(context, il);
            il.Emit(EmitOpCodes.Callvirt, getEnumeratorMethod);
            il.Emit(EmitOpCodes.Stloc, enumerator);

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

            il.MarkLabel(topOfLoop);
            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, moveNextMethod);
            il.Emit(EmitOpCodes.Brfalse, end);

            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, getCurrentMethod);
            il.Emit(EmitOpCodes.Stloc, item);

            Statement.Compile(context, il);
            il.Emit(EmitOpCodes.Br, topOfLoop);

            il.MarkLabel(end);
            il.Emit(EmitOpCodes.Nop);
        }
Example #22
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var item = il.DeclareLocal(Item.Type);
            Item.SetData(context, item);

            EmitType genericEnumerableType = typeof(IEnumerable<>);
            var enumerableType = genericEnumerableType.MakeGenericType(Item.Type);
            var getEnumeratorMethod = enumerableType.Members.OfType<EmitMethod>().Single(x => x.Name == nameof(IEnumerable<object>.GetEnumerator));

            EmitType genericEnumeratorType = typeof(IEnumerator<>);
            var enumeratorType = genericEnumeratorType.MakeGenericType(Item.Type);
            var moveNextMethod = enumerableType.Members.OfType<EmitMethod>().Single(x => x.Name == nameof(IEnumerator<object>.MoveNext));
            var getCurrentMethod = enumerableType.Members.OfType<EmitProperty>().Single(x => x.Name == nameof(IEnumerator<object>.Current)).GetMethod;

            var enumerator = il.DeclareLocal(enumeratorType);

            Collection.Compile(context, il);
            il.Emit(EmitOpCodes.Callvirt, getEnumeratorMethod);
            il.Emit(EmitOpCodes.Stloc, enumerator);

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

            il.MarkLabel(topOfLoop);
            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, moveNextMethod);
            il.Emit(EmitOpCodes.Brfalse, end);

            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, getCurrentMethod);
            il.Emit(EmitOpCodes.Stloc, item);

            Statement.Compile(context, il);
            il.Emit(EmitOpCodes.Br, topOfLoop);

            il.MarkLabel(end);
            il.Emit(EmitOpCodes.Nop);
        }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var local = Variable.GetData(context);

            il.Emit(EmitOpCodes.Ldloc, local);
        }
Example #24
0
 public abstract void Compile(EmitCompilerContext context, EmitIl il);
Example #25
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     Expression.Compile(context, il);
     il.Emit(EmitOpCodes.Pop);
 }
Example #26
0
 public abstract void Compile(EmitCompilerContext context, EmitIl il);
Example #27
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);
        }
Example #28
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;
            }
            }
        }
Example #29
0
            private void GenerateIl(ILGenerator il, EmitIl emitIl)
            {
                var locals = emitIl.Locals.ToDictionary(x => x, x => il.DeclareLocal(x.Type));
                var labels = emitIl.Labels.ToDictionary(x => x, x => il.DefineLabel());

                foreach (var instruction in emitIl.Instructions)
                {
                    foreach (var label in instruction.Labels)
                    {
                        il.MarkLabel(labels[label]);
                    }

                    var opCode = instruction.OpCode.ToOpCode();
                    if (instruction.Operand == null)
                    {
                        il.Emit(opCode);
                    }
                    else if (instruction.Operand is EmitType)
                    {
                        il.Emit(opCode, (EmitType)instruction.Operand);
                    }
                    else if (instruction.Operand is EmitMethod)
                    {
                        il.Emit(opCode, (EmitMethod)instruction.Operand);
                    }
                    else if (instruction.Operand is EmitConstructor)
                    {
                        il.Emit(opCode, (EmitConstructor)instruction.Operand);
                    }
                    else if (instruction.Operand is EmitField)
                    {
                        il.Emit(opCode, (EmitField)instruction.Operand);
                    }
                    else if (instruction.Operand is int)
                    {
                        il.Emit(opCode, (int)instruction.Operand);
                    }
                    else if (instruction.Operand is short)
                    {
                        il.Emit(opCode, (short)instruction.Operand);
                    }
                    else if (instruction.Operand is byte)
                    {
                        il.Emit(opCode, (byte)instruction.Operand);
                    }
                    else if (instruction.Operand is sbyte)
                    {
                        il.Emit(opCode, (sbyte)instruction.Operand);
                    }
                    else if (instruction.Operand is long)
                    {
                        il.Emit(opCode, (long)instruction.Operand);
                    }
                    else if (instruction.Operand is double)
                    {
                        il.Emit(opCode, (double)instruction.Operand);
                    }
                    else if (instruction.Operand is float)
                    {
                        il.Emit(opCode, (float)instruction.Operand);
                    }
                    else if (instruction.Operand is string)
                    {
                        il.Emit(opCode, (string)instruction.Operand);
                    }
                    else if (instruction.Operand is EmitLocal)
                    {
                        il.Emit(opCode, locals[(EmitLocal)instruction.Operand]);
                    }
                    else if (instruction.Operand is EmitLabel)
                    {
                        il.Emit(opCode, labels[(EmitLabel)instruction.Operand]);
                    }
                    else if (instruction.Operand is EmitLabel[])
                    {
                        il.Emit(opCode, ((EmitLabel[])instruction.Operand).Select(x => labels[x]).ToArray());
                    }
                    else
                    {
                        throw new Exception("Unexpected operand type: " + instruction.Operand.GetType().FullName);
                    }
                }
            }
Example #30
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;
                }
            }
        }
Example #31
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);
        }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     Expression.Compile(context, il);
     il.Emit(EmitOpCodes.Pop);
 }