Exemple #1
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)
 {
     foreach (var variable in Variables)
     {
         var local = il.DeclareLocal(variable.Type);
         variable.SetData(context, local);
     }
 }
Exemple #3
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 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)
        {
            // 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);
        }
        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);
        }
        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)
        {
            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;
                }
            }
        }
        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;
            }
            }
        }