Esempio n. 1
0
        private void EmitTypeBinaryExpression(Expression expr)
        {
            TypeBinaryExpression node = (TypeBinaryExpression)expr;

            if (node.NodeType == ExpressionType.TypeEqual)
            {
                EmitExpression(node.ReduceTypeEqual());
                return;
            }

            Type type = node.Expression.Type;

            // Try to determine the result statically
            AnalyzeTypeIsResult result = ConstantCheck.AnalyzeTypeIs(node);

            if (result == AnalyzeTypeIsResult.KnownTrue ||
                result == AnalyzeTypeIsResult.KnownFalse)
            {
                // Result is known statically, so just emit the expression for
                // its side effects and return the result
                EmitExpressionAsVoid(node.Expression);
                _ilg.EmitBoolean(result == AnalyzeTypeIsResult.KnownTrue);
                return;
            }

            if (result == AnalyzeTypeIsResult.KnownAssignable)
            {
                // We know the type can be assigned, but still need to check
                // for null at runtime
                if (type.IsNullableType())
                {
                    EmitAddress(node.Expression, type);
                    _ilg.EmitHasValue(type);
                    return;
                }

                Debug.Assert(!type.GetTypeInfo().IsValueType);
                EmitExpression(node.Expression);
                _ilg.Emit(OpCodes.Ldnull);
                _ilg.Emit(OpCodes.Ceq);
                _ilg.Emit(OpCodes.Ldc_I4_0);
                _ilg.Emit(OpCodes.Ceq);
                return;
            }

            Debug.Assert(result == AnalyzeTypeIsResult.Unknown);

            // Emit a full runtime "isinst" check
            EmitExpression(node.Expression);
            if (type.GetTypeInfo().IsValueType)
            {
                _ilg.Emit(OpCodes.Box, type);
            }
            _ilg.Emit(OpCodes.Isinst, node.TypeOperand);
            _ilg.Emit(OpCodes.Ldnull);
            _ilg.Emit(OpCodes.Cgt_Un);
        }
Esempio n. 2
0
        /// <summary>
        /// 取值。
        /// </summary>
        /// <param name="ilg">指令。</param>
        public override void Load(ILGenerator ilg)
        {
            var type = body.RuntimeType;

            AnalyzeTypeIsResult result = AnalyzeTypeIs(type, isType);

            if (result == AnalyzeTypeIsResult.KnownTrue ||
                result == AnalyzeTypeIsResult.KnownFalse)
            {
                if (result == AnalyzeTypeIsResult.KnownTrue)
                {
                    ilg.Emit(OpCodes.Ldc_I4_1);
                }
                else
                {
                    ilg.Emit(OpCodes.Ldc_I4_0);
                }

                return;
            }

            if (result == AnalyzeTypeIsResult.KnownAssignable)
            {
                if (IsNullable(type))
                {
                    body.Load(ilg);

                    MethodInfo mi = type.GetMethod("get_HasValue", BindingFlags.Instance | BindingFlags.Public);

                    ilg.Emit(OpCodes.Call, mi);

                    return;
                }

                body.Load(ilg);

                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Ceq);
                ilg.Emit(OpCodes.Ldc_I4_0);
                ilg.Emit(OpCodes.Ceq);

                return;
            }

            body.Load(ilg);

            if (type.IsValueType)
            {
                ilg.Emit(OpCodes.Box, type);
            }

            ilg.Emit(OpCodes.Isinst, isType);
            ilg.Emit(OpCodes.Ldnull);
            ilg.Emit(OpCodes.Cgt_Un);
        }
Esempio n. 3
0
        internal static bool IsConstant(Expression e, bool value)
        {
            switch (e.NodeType)
            {
            case ExpressionType.AndAlso:
                return(CheckAndAlso((BinaryExpression)e, value));

            case ExpressionType.OrElse:
                return(CheckOrElse((BinaryExpression)e, value));

            case ExpressionType.Constant:
                return(value.Equals(((ConstantExpression)e).Value));

            case ExpressionType.TypeIs:
                AnalyzeTypeIsResult result = AnalyzeTypeIs((TypeBinaryExpression)e);
                if (value)
                {
                    return(result == AnalyzeTypeIsResult.KnownTrue);
                }
                return(result == AnalyzeTypeIsResult.KnownFalse);
            }
            return(false);
        }