protected override void ResetLeakedStateRecursively()
 {
     base.ResetLeakedStateRecursively();
     OperandExtensions.SetLeakedState(_assignment, false);
 }
Beispiel #2
0
 protected override void ResetLeakedStateRecursively()
 {
     OperandExtensions.SetLeakedState(_op, false);
     base.ResetLeakedStateRecursively();
 }
        protected internal override void EmitBranch(CodeGen g, OptionalLabel labelTrue, OptionalLabel labelFalse)
        {
            OperandExtensions.SetLeakedState(this, false);

            foreach (LocalCache lc in _caches)
            {
                lc.Clear();
            }

            bool argsEmitted = false;

            var branchSet = BranchSet.Normal;

            // value type handling
            if (_operands.Length == 2)
            {
                var  valueOperand = _operands[0] ?? _operands[1];
                Type returnType   = valueOperand?.GetReturnType(g.TypeMapper);
                if (returnType?.IsValueType ?? false)
                {
                    if (ReferenceEquals(_operands[0], null) || ReferenceEquals(_operands[1], null))
                    {
                        bool isNullable = Helpers.GetNullableUnderlyingType(returnType) != null;

                        var op = branchSet.Get(_op.BranchOp, true);
                        if (op == OpCodes.Bne_Un || op == OpCodes.Bne_Un_S)
                        {
                            if (isNullable)
                            {
                                valueOperand.Property("HasValue", g.TypeMapper).EmitBranch(g, labelTrue, labelFalse);
                            }
                            else
                            {
                                // ValueType != null, should return true
                                if (labelTrue != null && labelTrue.IsLabelExist) // otherwise default path
                                {
                                    g.IL.Emit(OpCodes.Br, labelTrue.Value);
                                }
                            }
                            return;
                        }
                        else if (op == OpCodes.Beq || op == OpCodes.Beq_S)
                        {
                            if (isNullable)
                            {
                                valueOperand.Property("HasValue", g.TypeMapper).EmitBranch(g, labelFalse, labelTrue);
                            }
                            else
                            {
                                // ValueType == null, should return false
                                if (labelFalse != null && labelFalse.IsLabelExist) // otherwise default path
                                {
                                    g.IL.Emit(OpCodes.Br, labelFalse.Value);
                                }
                            }
                            return;
                        }
                        else if (_op.IsLogical)                                // 5? > null, 5 <= null, ...
                        {
                            if (labelFalse != null && labelFalse.IsLabelExist) // otherwise default path
                            {
                                g.IL.Emit(OpCodes.Br, labelFalse.Value);
                            }
                        }
                    }
                }
            }

            PrepareAf(g.TypeMapper);

            if (!ReferenceEquals(_afInterceptor, null))
            {
                _afInterceptor.EmitBranch(g, labelTrue, labelFalse);
                return;
            }

            IStandardOperation stdOp = _af.Method as IStandardOperation;

            if (_op.BranchOp == 0 || stdOp == null)
            {
                base.EmitBranch(g, labelTrue, labelFalse);
                return;
            }

            if (!argsEmitted)
            {
                _af.EmitArgs(g, _operands);
            }

            bool inverted = false;

            if (labelTrue == null || !labelTrue.IsLabelExist)
            {
                if (labelFalse == null)
                {
                    throw new InvalidOperationException("No labels passed");
                }
                if (!labelFalse.IsLabelExist)
                {
                    throw new InvalidOperationException("No existing labels were passed");
                }
                labelTrue = labelFalse;
                branchSet = branchSet.GetInverted();
                inverted  = true;
            }
            g.IL.Emit(branchSet.Get(_op.BranchOp, stdOp.IsUnsigned), labelTrue.Value);
            if (!inverted && labelFalse != null && labelFalse.IsLabelExist)
            {
                g.IL.Emit(OpCodes.Br, labelFalse.Value);
            }
        }
Beispiel #4
0
 protected internal override void EmitGet(CodeGen g)
 {
     OperandExtensions.SetLeakedState(this, false);
     g.EmitI8Helper(Value, _t == typeof(long));
 }
        protected internal override void EmitGet(CodeGen g)
        {
            OperandExtensions.SetLeakedState(this, false);

            foreach (LocalCache lc in _caches)
            {
                lc.Clear();
            }

            // value type handling
            if (_operands.Length == 2)
            {
                var  valueOperand = _operands[0] ?? _operands[1];
                Type returnType   = valueOperand?.GetReturnType(g.TypeMapper);
                if ((ReferenceEquals(_operands[0], null) || ReferenceEquals(_operands[1], null)) && (returnType?.IsValueType ?? false))
                {
                    bool isNullable = Helpers.GetNullableUnderlyingType(returnType) != null;
                    if (_op.BranchOp == BranchInstruction.Ne)
                    {
                        if (isNullable)
                        {
                            valueOperand.Property("HasValue", g.TypeMapper).EmitGet(g);
                        }
                        else
                        {
                            g.EmitI4Helper(1);
                        }
                        return;
                    }
                    else if (_op.BranchOp == BranchInstruction.Eq)
                    {
                        if (isNullable)
                        {
                            valueOperand.Property("HasValue", g.TypeMapper).LogicalNot().EmitGet(g);
                        }
                        else
                        {
                            g.EmitI4Helper(0);
                        }
                        return;
                    }
                    else if (_op.IsLogical) // 5? > null, 5 <= null, ...
                    {
                        g.EmitI4Helper(0);
                        return;
                    }
                }
            }


            PrepareAf(g.TypeMapper);

            if (!ReferenceEquals(_afInterceptor, null))
            {
                _afInterceptor.EmitGet(g);
                return;
            }

            _af.EmitArgs(g, _operands);

            IStandardOperation sop = _af.Method as IStandardOperation;

            if (sop != null)
            {
                sop.Emit(g, _op);
            }
            else
            {
                g.IL.Emit(OpCodes.Call, (MethodInfo)_af.Method.Member);
            }
        }