Beispiel #1
0
        void EmitLiftedToNullBinary(EmitContext ec)
        {
            var ig     = ec.ig;
            var left   = ec.EmitStored(this.left);
            var right  = ec.EmitStored(this.right);
            var result = ig.DeclareLocal(Type);

            var has_value = ig.DefineLabel();
            var done      = ig.DefineLabel();

            ec.EmitNullableHasValue(left);
            ec.EmitNullableHasValue(right);
            ig.Emit(OpCodes.And);
            ig.Emit(OpCodes.Brtrue, has_value);

            ec.EmitNullableInitialize(result);

            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(has_value);

            ec.EmitNullableGetValueOrDefault(left);
            ec.EmitNullableGetValueOrDefault(right);

            EmitBinaryOperator(ec);

            ec.EmitNullableNew(result.LocalType);

            ig.MarkLabel(done);
        }
Beispiel #2
0
        private void EmitUserDefinedLiftedLogicalShortCircuit(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            bool         flag   = base.NodeType == ExpressionType.AndAlso;
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();
            Label        label3 = ig.DefineLabel();
            Label        label4 = ig.DefineLabel();
            LocalBuilder local  = ec.EmitStored(left);

            ec.EmitNullableHasValue(local);
            ig.Emit(OpCodes.Brfalse, (!flag) ? label : label3);
            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitCall((!flag) ? GetTrueOperator() : GetFalseOperator());
            ig.Emit(OpCodes.Brtrue, label2);
            ig.MarkLabel(label);
            LocalBuilder local2 = ec.EmitStored(right);

            ec.EmitNullableHasValue(local2);
            ig.Emit(OpCodes.Brfalse, label3);
            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitNullableGetValueOrDefault(local2);
            ec.EmitCall(method);
            ec.EmitNullableNew(base.Type);
            ig.Emit(OpCodes.Br, label4);
            ig.MarkLabel(label2);
            ec.EmitLoad(local);
            ig.Emit(OpCodes.Br, label4);
            ig.MarkLabel(label3);
            LocalBuilder local3 = ig.DeclareLocal(base.Type);

            ec.EmitNullableInitialize(local3);
            ig.MarkLabel(label4);
        }
Beispiel #3
0
        void EmitLiftedToNullUserDefinedOperator(EmitContext ec)
        {
            var ig = ec.ig;

            var ret  = ig.DefineLabel();
            var done = ig.DefineLabel();

            var left  = ec.EmitStored(this.left);
            var right = ec.EmitStored(this.right);

            ec.EmitNullableHasValue(left);
            ec.EmitNullableHasValue(right);
            ig.Emit(OpCodes.And);
            ig.Emit(OpCodes.Brfalse, ret);

            ec.EmitNullableGetValueOrDefault(left);
            ec.EmitNullableGetValueOrDefault(right);
            ec.EmitCall(method);
            ec.EmitNullableNew(Type);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret);
            var temp = ig.DeclareLocal(Type);

            ec.EmitNullableInitialize(temp);

            ig.MarkLabel(done);
        }
Beispiel #4
0
        void EmitLiftedLogicalShortCircuit(EmitContext ec)
        {
            var ig            = ec.ig;
            var and           = NodeType == ExpressionType.AndAlso;
            var left_is_null  = ig.DefineLabel();
            var ret_from_left = ig.DefineLabel();
            var ret_null      = ig.DefineLabel();
            var ret_new       = ig.DefineLabel();
            var done          = ig.DefineLabel();

            var left = ec.EmitStored(this.left);

            ec.EmitNullableHasValue(left);
            ig.Emit(OpCodes.Brfalse, left_is_null);

            ec.EmitNullableGetValueOrDefault(left);

            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ceq);
            ig.Emit(and ? OpCodes.Brtrue : OpCodes.Brfalse, ret_from_left);

            ig.MarkLabel(left_is_null);
            var right = ec.EmitStored(this.right);

            ec.EmitNullableHasValue(right);
            ig.Emit(OpCodes.Brfalse_S, ret_null);

            ec.EmitNullableGetValueOrDefault(right);

            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ceq);

            ig.Emit(and ? OpCodes.Brtrue : OpCodes.Brfalse, ret_from_left);

            ec.EmitNullableHasValue(left);
            ig.Emit(OpCodes.Brfalse, ret_null);

            ig.Emit(and ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Br_S, ret_new);

            ig.MarkLabel(ret_from_left);
            ig.Emit(and ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);

            ig.MarkLabel(ret_new);
            ec.EmitNullableNew(Type);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret_null);
            var ret = ig.DeclareLocal(Type);

            ec.EmitNullableInitialize(ret);

            ig.MarkLabel(done);
        }
Beispiel #5
0
        void EmitLiftedRelationalBinary(EmitContext ec)
        {
            var ig    = ec.ig;
            var left  = ec.EmitStored(this.left);
            var right = ec.EmitStored(this.right);

            var ret  = ig.DefineLabel();
            var done = ig.DefineLabel();

            ec.EmitNullableGetValueOrDefault(left);
            ec.EmitNullableGetValueOrDefault(right);

            switch (NodeType)
            {
            case ExpressionType.Equal:
            case ExpressionType.NotEqual:
                ig.Emit(OpCodes.Bne_Un, ret);
                break;

            default:
                EmitBinaryOperator(ec);
                ig.Emit(OpCodes.Brfalse, ret);
                break;
            }

            ec.EmitNullableHasValue(left);
            ec.EmitNullableHasValue(right);

            switch (NodeType)
            {
            case ExpressionType.Equal:
                ig.Emit(OpCodes.Ceq);
                break;

            case ExpressionType.NotEqual:
                ig.Emit(OpCodes.Ceq);
                ig.Emit(OpCodes.Ldc_I4_0);
                ig.Emit(OpCodes.Ceq);
                break;

            default:
                ig.Emit(OpCodes.And);
                break;
            }

            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret);

            ig.Emit(NodeType == ExpressionType.NotEqual ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);

            ig.MarkLabel(done);
        }
Beispiel #6
0
        void EmitLiftedUserDefinedOperator(EmitContext ec)
        {
            var ig = ec.ig;

            var ret_true  = ig.DefineLabel();
            var ret_false = ig.DefineLabel();
            var done      = ig.DefineLabel();

            var left  = ec.EmitStored(this.left);
            var right = ec.EmitStored(this.right);

            ec.EmitNullableHasValue(left);
            ec.EmitNullableHasValue(right);
            switch (NodeType)
            {
            case ExpressionType.Equal:
                ig.Emit(OpCodes.Bne_Un, ret_false);
                ec.EmitNullableHasValue(left);
                ig.Emit(OpCodes.Brfalse, ret_true);
                break;

            case ExpressionType.NotEqual:
                ig.Emit(OpCodes.Bne_Un, ret_true);
                ec.EmitNullableHasValue(left);
                ig.Emit(OpCodes.Brfalse, ret_false);
                break;

            default:
                ig.Emit(OpCodes.And);
                ig.Emit(OpCodes.Brfalse, ret_false);
                break;
            }

            ec.EmitNullableGetValueOrDefault(left);
            ec.EmitNullableGetValueOrDefault(right);
            ec.EmitCall(method);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret_true);
            ig.Emit(OpCodes.Ldc_I4_1);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret_false);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(done);
        }
Beispiel #7
0
        void EmitLiftedLogical(EmitContext ec)
        {
            var ig    = ec.ig;
            var and   = NodeType == ExpressionType.And;
            var left  = ec.EmitStored(this.left);
            var right = ec.EmitStored(this.right);

            var ret_from_left  = ig.DefineLabel();
            var ret_from_right = ig.DefineLabel();
            var done           = ig.DefineLabel();

            ec.EmitNullableGetValueOrDefault(left);
            ig.Emit(OpCodes.Brtrue, ret_from_left);
            ec.EmitNullableGetValueOrDefault(right);
            ig.Emit(OpCodes.Brtrue, ret_from_right);

            ec.EmitNullableHasValue(left);
            ig.Emit(OpCodes.Brfalse, ret_from_left);

            ig.MarkLabel(ret_from_right);
            ec.EmitLoad(and ? left : right);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret_from_left);
            ec.EmitLoad(and ? right : left);

            ig.MarkLabel(done);
        }
        private void EmitLeftLiftedToNullBinary(EmitContext ec)
        {
            var ig = ec.ig;

            var ret  = ig.DefineLabel();
            var done = ig.DefineLabel();

            var left = ec.EmitStored(this.left);

            ec.EmitNullableHasValue(left);
            ig.Emit(OpCodes.Brfalse, ret);

            ec.EmitNullableGetValueOrDefault(left);
            ec.Emit(right);

            EmitBinaryOperator(ec);

            ec.EmitNullableNew(Type);

            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret);

            var temp = ig.DeclareLocal(Type);

            ec.EmitNullableInitialize(temp);

            ig.MarkLabel(done);
        }
Beispiel #9
0
        void EmitConvertedCoalesce(EmitContext ec)
        {
            var ig         = ec.ig;
            var done       = ig.DefineLabel();
            var load_right = ig.DefineLabel();

            var left = ec.EmitStored(this.left);

            if (left.LocalType.IsNullable())
            {
                ec.EmitNullableHasValue(left);
            }
            else
            {
                ec.EmitLoad(left);
            }

            ig.Emit(OpCodes.Brfalse, load_right);

            ec.Emit(conversion);
            ec.EmitLoad(left);
            ig.Emit(OpCodes.Callvirt, conversion.Type.GetInvokeMethod());

            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(load_right);
            ec.Emit(this.right);

            ig.MarkLabel(done);
        }
Beispiel #10
0
        private void EmitCoalesce(EmitContext ec)
        {
            ILGenerator  ig           = ec.ig;
            Label        label        = ig.DefineLabel();
            Label        label2       = ig.DefineLabel();
            LocalBuilder localBuilder = ec.EmitStored(left);
            bool         flag         = localBuilder.LocalType.IsNullable();

            if (flag)
            {
                ec.EmitNullableHasValue(localBuilder);
            }
            else
            {
                ec.EmitLoad(localBuilder);
            }
            ig.Emit(OpCodes.Brfalse, label2);
            if (flag && !base.Type.IsNullable())
            {
                ec.EmitNullableGetValue(localBuilder);
            }
            else
            {
                ec.EmitLoad(localBuilder);
            }
            ig.Emit(OpCodes.Br, label);
            ig.MarkLabel(label2);
            ec.Emit(right);
            ig.MarkLabel(label);
        }
Beispiel #11
0
        void EmitNullEquality(EmitContext ec, Expression e)
        {
            var ig = ec.ig;

            if (IsLiftedToNull)
            {
                e.Emit(ec);
                if (e.Type != typeof(void))
                {
                    ig.Emit(OpCodes.Pop);
                }

                ec.EmitNullableNew(typeof(bool?));
                return;
            }

            var se = ec.EmitStored(e);

            ec.EmitNullableHasValue(se);
            if (NodeType == ExpressionType.Equal)
            {
                ig.Emit(OpCodes.Ldc_I4_0);
                ig.Emit(OpCodes.Ceq);
            }
        }
Beispiel #12
0
        void EmitLiftedUnary(EmitContext ec)
        {
            var ig = ec.ig;

            var from = ec.EmitStored(operand);
            var to   = ig.DeclareLocal(Type);

            var has_value = ig.DefineLabel();
            var done      = ig.DefineLabel();

            ec.EmitNullableHasValue(from);
            ig.Emit(OpCodes.Brtrue, has_value);

            // if not has value
            ec.EmitNullableInitialize(to);

            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(has_value);
            // if has value
            ec.EmitNullableGetValueOrDefault(from);

            EmitUnaryOperator(ec);

            ec.EmitNullableNew(Type);

            ig.MarkLabel(done);
        }
        private void EmitLiftedRelationalBinary(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            LocalBuilder local  = ec.EmitStored(this.left);
            LocalBuilder local2 = ec.EmitStored(this.right);
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();

            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitNullableGetValueOrDefault(local2);
            ExpressionType nodeType = base.NodeType;

            if (nodeType != ExpressionType.Equal && nodeType != ExpressionType.NotEqual)
            {
                this.EmitBinaryOperator(ec);
                ig.Emit(OpCodes.Brfalse, label);
            }
            else
            {
                ig.Emit(OpCodes.Bne_Un, label);
            }
            ec.EmitNullableHasValue(local);
            ec.EmitNullableHasValue(local2);
            nodeType = base.NodeType;
            if (nodeType != ExpressionType.Equal)
            {
                if (nodeType != ExpressionType.NotEqual)
                {
                    ig.Emit(OpCodes.And);
                }
                else
                {
                    ig.Emit(OpCodes.Ceq);
                    ig.Emit(OpCodes.Ldc_I4_0);
                    ig.Emit(OpCodes.Ceq);
                }
            }
            else
            {
                ig.Emit(OpCodes.Ceq);
            }
            ig.Emit(OpCodes.Br, label2);
            ig.MarkLabel(label);
            ig.Emit((base.NodeType != ExpressionType.NotEqual) ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
            ig.MarkLabel(label2);
        }
        private void EmitLiftedUserDefinedOperator(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();
            Label        label3 = ig.DefineLabel();
            LocalBuilder local  = ec.EmitStored(this.left);
            LocalBuilder local2 = ec.EmitStored(this.right);

            ec.EmitNullableHasValue(local);
            ec.EmitNullableHasValue(local2);
            ExpressionType nodeType = base.NodeType;

            if (nodeType != ExpressionType.Equal)
            {
                if (nodeType != ExpressionType.NotEqual)
                {
                    ig.Emit(OpCodes.And);
                    ig.Emit(OpCodes.Brfalse, label2);
                }
                else
                {
                    ig.Emit(OpCodes.Bne_Un, label);
                    ec.EmitNullableHasValue(local);
                    ig.Emit(OpCodes.Brfalse, label2);
                }
            }
            else
            {
                ig.Emit(OpCodes.Bne_Un, label2);
                ec.EmitNullableHasValue(local);
                ig.Emit(OpCodes.Brfalse, label);
            }
            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitNullableGetValueOrDefault(local2);
            ec.EmitCall(this.method);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label);
            ig.Emit(OpCodes.Ldc_I4_1);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label2);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label3);
        }
Beispiel #15
0
        void EmitUserDefinedLiftedLogicalShortCircuit(EmitContext ec)
        {
            var ig  = ec.ig;
            var and = NodeType == ExpressionType.AndAlso;

            var left_is_null = ig.DefineLabel();
            var ret_left     = ig.DefineLabel();
            var ret_null     = ig.DefineLabel();
            var done         = ig.DefineLabel();

            var left = ec.EmitStored(this.left);

            ec.EmitNullableHasValue(left);
            ig.Emit(OpCodes.Brfalse, and ? ret_null : left_is_null);

            ec.EmitNullableGetValueOrDefault(left);
            ec.EmitCall(and ? GetFalseOperator() : GetTrueOperator());
            ig.Emit(OpCodes.Brtrue, ret_left);

            ig.MarkLabel(left_is_null);
            var right = ec.EmitStored(this.right);

            ec.EmitNullableHasValue(right);
            ig.Emit(OpCodes.Brfalse, ret_null);

            ec.EmitNullableGetValueOrDefault(left);
            ec.EmitNullableGetValueOrDefault(right);
            ec.EmitCall(method);

            ec.EmitNullableNew(Type);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret_left);
            ec.EmitLoad(left);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret_null);
            var ret = ig.DeclareLocal(Type);

            ec.EmitNullableInitialize(ret);

            ig.MarkLabel(done);
        }
Beispiel #16
0
        private void EmitLiftedUserDefinedOperator(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();
            Label        label3 = ig.DefineLabel();
            LocalBuilder local  = ec.EmitStored(left);
            LocalBuilder local2 = ec.EmitStored(right);

            ec.EmitNullableHasValue(local);
            ec.EmitNullableHasValue(local2);
            switch (base.NodeType)
            {
            case ExpressionType.Equal:
                ig.Emit(OpCodes.Bne_Un, label2);
                ec.EmitNullableHasValue(local);
                ig.Emit(OpCodes.Brfalse, label);
                break;

            case ExpressionType.NotEqual:
                ig.Emit(OpCodes.Bne_Un, label);
                ec.EmitNullableHasValue(local);
                ig.Emit(OpCodes.Brfalse, label2);
                break;

            default:
                ig.Emit(OpCodes.And);
                ig.Emit(OpCodes.Brfalse, label2);
                break;
            }
            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitNullableGetValueOrDefault(local2);
            ec.EmitCall(method);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label);
            ig.Emit(OpCodes.Ldc_I4_1);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label2);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label3);
        }
Beispiel #17
0
        private void EmitLiftedLogicalShortCircuit(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            bool         flag   = base.NodeType == ExpressionType.AndAlso;
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();
            Label        label3 = ig.DefineLabel();
            Label        label4 = ig.DefineLabel();
            Label        label5 = ig.DefineLabel();
            LocalBuilder local  = ec.EmitStored(left);

            ec.EmitNullableHasValue(local);
            ig.Emit(OpCodes.Brfalse, label);
            ec.EmitNullableGetValueOrDefault(local);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ceq);
            ig.Emit((!flag) ? OpCodes.Brfalse : OpCodes.Brtrue, label2);
            ig.MarkLabel(label);
            LocalBuilder local2 = ec.EmitStored(right);

            ec.EmitNullableHasValue(local2);
            ig.Emit(OpCodes.Brfalse_S, label3);
            ec.EmitNullableGetValueOrDefault(local2);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ceq);
            ig.Emit((!flag) ? OpCodes.Brfalse : OpCodes.Brtrue, label2);
            ec.EmitNullableHasValue(local);
            ig.Emit(OpCodes.Brfalse, label3);
            ig.Emit((!flag) ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
            ig.Emit(OpCodes.Br_S, label4);
            ig.MarkLabel(label2);
            ig.Emit((!flag) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
            ig.MarkLabel(label4);
            ec.EmitNullableNew(base.Type);
            ig.Emit(OpCodes.Br, label5);
            ig.MarkLabel(label3);
            LocalBuilder local3 = ig.DeclareLocal(base.Type);

            ec.EmitNullableInitialize(local3);
            ig.MarkLabel(label5);
        }
Beispiel #18
0
        private void EmitLiftedToNullBinary(EmitContext ec)
        {
            ILGenerator  ig           = ec.ig;
            LocalBuilder local        = ec.EmitStored(left);
            LocalBuilder local2       = ec.EmitStored(right);
            LocalBuilder localBuilder = ig.DeclareLocal(base.Type);
            Label        label        = ig.DefineLabel();
            Label        label2       = ig.DefineLabel();

            ec.EmitNullableHasValue(local);
            ec.EmitNullableHasValue(local2);
            ig.Emit(OpCodes.And);
            ig.Emit(OpCodes.Brtrue, label);
            ec.EmitNullableInitialize(localBuilder);
            ig.Emit(OpCodes.Br, label2);
            ig.MarkLabel(label);
            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitNullableGetValueOrDefault(local2);
            EmitBinaryOperator(ec);
            ec.EmitNullableNew(localBuilder.LocalType);
            ig.MarkLabel(label2);
        }
Beispiel #19
0
        private void EmitLiftedToNullUserDefinedOperator(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();
            LocalBuilder local  = ec.EmitStored(left);
            LocalBuilder local2 = ec.EmitStored(right);

            ec.EmitNullableHasValue(local);
            ec.EmitNullableHasValue(local2);
            ig.Emit(OpCodes.And);
            ig.Emit(OpCodes.Brfalse, label);
            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitNullableGetValueOrDefault(local2);
            ec.EmitCall(method);
            ec.EmitNullableNew(base.Type);
            ig.Emit(OpCodes.Br, label2);
            ig.MarkLabel(label);
            LocalBuilder local3 = ig.DeclareLocal(base.Type);

            ec.EmitNullableInitialize(local3);
            ig.MarkLabel(label2);
        }
Beispiel #20
0
        private void EmitLiftedUnary(EmitContext ec)
        {
            ILGenerator  ig     = ec.ig;
            LocalBuilder local  = ec.EmitStored(this.operand);
            LocalBuilder local2 = ig.DeclareLocal(base.Type);
            Label        label  = ig.DefineLabel();
            Label        label2 = ig.DefineLabel();

            ec.EmitNullableHasValue(local);
            ig.Emit(OpCodes.Brtrue, label);
            ec.EmitNullableInitialize(local2);
            ig.Emit(OpCodes.Br, label2);
            ig.MarkLabel(label);
            ec.EmitNullableGetValueOrDefault(local);
            this.EmitUnaryOperator(ec);
            ec.EmitNullableNew(base.Type);
            ig.MarkLabel(label2);
        }
Beispiel #21
0
        private void EmitLiftedLogical(EmitContext ec)
        {
            ILGenerator  ig            = ec.ig;
            bool         flag          = base.NodeType == ExpressionType.And;
            LocalBuilder localBuilder  = ec.EmitStored(left);
            LocalBuilder localBuilder2 = ec.EmitStored(right);
            Label        label         = ig.DefineLabel();
            Label        label2        = ig.DefineLabel();
            Label        label3        = ig.DefineLabel();

            ec.EmitNullableGetValueOrDefault(localBuilder);
            ig.Emit(OpCodes.Brtrue, label);
            ec.EmitNullableGetValueOrDefault(localBuilder2);
            ig.Emit(OpCodes.Brtrue, label2);
            ec.EmitNullableHasValue(localBuilder);
            ig.Emit(OpCodes.Brfalse, label);
            ig.MarkLabel(label2);
            ec.EmitLoad((!flag) ? localBuilder2 : localBuilder);
            ig.Emit(OpCodes.Br, label3);
            ig.MarkLabel(label);
            ec.EmitLoad((!flag) ? localBuilder : localBuilder2);
            ig.MarkLabel(label3);
        }
        private void EmitUserDefinedLiftedToNullOperator(EmitContext ec)
        {
            var ig    = ec.ig;
            var local = ec.EmitStored(operand);

            var ret  = ig.DefineLabel();
            var done = ig.DefineLabel();

            ec.EmitNullableHasValue(local);
            ig.Emit(OpCodes.Brfalse, ret);

            ec.EmitNullableGetValueOrDefault(local);
            ec.EmitCall(method);
            ec.EmitNullableNew(Type);
            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(ret);

            var temp = ig.DeclareLocal(Type);

            ec.EmitNullableInitialize(temp);

            ig.MarkLabel(done);
        }
Beispiel #23
0
        private void EmitConvertedCoalesce(EmitContext ec)
        {
            ILGenerator  ig           = ec.ig;
            Label        label        = ig.DefineLabel();
            Label        label2       = ig.DefineLabel();
            LocalBuilder localBuilder = ec.EmitStored(left);

            if (localBuilder.LocalType.IsNullable())
            {
                ec.EmitNullableHasValue(localBuilder);
            }
            else
            {
                ec.EmitLoad(localBuilder);
            }
            ig.Emit(OpCodes.Brfalse, label2);
            ec.Emit(conversion);
            ec.EmitLoad(localBuilder);
            ig.Emit(OpCodes.Callvirt, conversion.Type.GetInvokeMethod());
            ig.Emit(OpCodes.Br, label);
            ig.MarkLabel(label2);
            ec.Emit(right);
            ig.MarkLabel(label);
        }
Beispiel #24
0
        void EmitCoalesce(EmitContext ec)
        {
            var ig         = ec.ig;
            var done       = ig.DefineLabel();
            var load_right = ig.DefineLabel();

            var left             = ec.EmitStored(this.left);
            var left_is_nullable = left.LocalType.IsNullable();

            if (left_is_nullable)
            {
                ec.EmitNullableHasValue(left);
            }
            else
            {
                ec.EmitLoad(left);
            }

            ig.Emit(OpCodes.Brfalse, load_right);

            if (left_is_nullable && !Type.IsNullable())
            {
                ec.EmitNullableGetValue(left);
            }
            else
            {
                ec.EmitLoad(left);
            }

            ig.Emit(OpCodes.Br, done);

            ig.MarkLabel(load_right);
            ec.Emit(this.right);

            ig.MarkLabel(done);
        }