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); }
/// <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); }
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); }