public Box ( PrimitiveType type ) : void | ||
type | PrimitiveType | The type of value to box. This should be a value type. |
Résultat | void |
/// <summary> /// Pops the value on the stack, converts it to an object, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToAny(ILGenerator generator, PrimitiveType fromType) { if (PrimitiveTypeUtilities.IsValueType(fromType)) { generator.Box(fromType); } }
/// <summary> /// Pops the value on the stack, converts it to a primitive value, then pushes the result /// onto the stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> /// <param name="preferredType"> Specifies whether toString() or valueOf() should be /// preferred when converting to a primitive. </param> public static void ToPrimitive(ILGenerator generator, PrimitiveType fromType, PrimitiveTypeHint preferredType) { switch (fromType) { case PrimitiveType.Undefined: case PrimitiveType.Null: case PrimitiveType.Bool: case PrimitiveType.String: case PrimitiveType.ConcatenatedString: case PrimitiveType.Int32: case PrimitiveType.UInt32: case PrimitiveType.Number: // These are primitives already. break; case PrimitiveType.Any: case PrimitiveType.Object: // Otherwise, fall back to calling TypeConverter.ToPrimitive() if (PrimitiveTypeUtilities.IsValueType(fromType)) { generator.Box(fromType); } generator.LoadInt32((int)preferredType); generator.Call(ReflectionHelpers.TypeConverter_ToPrimitive); break; default: throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType)); } }
/// <summary> /// Pops the value on the stack, converts it to a string, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToString(ILGenerator generator, PrimitiveType fromType) { // Check that a conversion is actually necessary. if (fromType == PrimitiveType.String) { return; } switch (fromType) { case PrimitiveType.Undefined: // Converting from undefined produces "undefined". generator.Pop(); generator.LoadString("undefined"); break; case PrimitiveType.Null: // Converting from null produces "null". generator.Pop(); generator.LoadString("null"); break; case PrimitiveType.Bool: // Converting from a boolean produces "false" if the boolean is false, or "true" if the boolean is true. var elseClause = generator.CreateLabel(); var endOfIf = generator.CreateLabel(); generator.BranchIfFalse(elseClause); generator.LoadString("true"); generator.Branch(endOfIf); generator.DefineLabelPosition(elseClause); generator.LoadString("false"); generator.DefineLabelPosition(endOfIf); break; case PrimitiveType.ConcatenatedString: generator.Call(ReflectionHelpers.ConcatenatedString_ToString); break; case PrimitiveType.Int32: case PrimitiveType.UInt32: case PrimitiveType.Number: case PrimitiveType.Any: case PrimitiveType.Object: // Otherwise, fall back to calling TypeConverter.ToString() if (PrimitiveTypeUtilities.IsValueType(fromType)) { generator.Box(fromType); } generator.Call(ReflectionHelpers.TypeConverter_ToString); break; default: throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType)); } }
/// <summary> /// Pops the value on the stack, converts it to an object, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToAny(ILGenerator generator, PrimitiveType fromType) { if (PrimitiveTypeUtilities.IsValueType(fromType)) { generator.Box(fromType); } else { generator.ReinterpretCast(typeof(object)); } }
/// <summary> /// Pops the value on the stack, converts it to a concatenated string, then pushes the result /// onto the stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToConcatenatedString(ILGenerator generator, PrimitiveType fromType) { // Check that a conversion is actually necessary. if (fromType == PrimitiveType.ConcatenatedString) { return; } switch (fromType) { case PrimitiveType.Undefined: case PrimitiveType.Null: case PrimitiveType.Bool: case PrimitiveType.String: // Convert as per ToString, then create a new ConcatenatedString instance. ToString(generator, fromType); generator.NewObject(ReflectionHelpers.ConcatenatedString_Constructor_String); break; case PrimitiveType.Int32: case PrimitiveType.UInt32: case PrimitiveType.Number: case PrimitiveType.Any: case PrimitiveType.Object: // Otherwise, fall back to calling TypeConverter.ToConcatenatedString() if (PrimitiveTypeUtilities.IsValueType(fromType)) { generator.Box(fromType); } generator.Call(ReflectionHelpers.TypeConverter_ToConcatenatedString); break; default: throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType)); } }
/// <summary> /// Pops the value on the stack, converts it to a string, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToString(ILGenerator generator, PrimitiveType fromType) { // Check that a conversion is actually necessary. if (fromType == PrimitiveType.String) return; switch (fromType) { case PrimitiveType.Undefined: // Converting from undefined produces "undefined". generator.Pop(); generator.LoadString("undefined"); break; case PrimitiveType.Null: // Converting from null produces "null". generator.Pop(); generator.LoadString("null"); break; case PrimitiveType.Bool: // Converting from a boolean produces "false" if the boolean is false, or "true" if the boolean is true. var elseClause = generator.CreateLabel(); var endOfIf = generator.CreateLabel(); generator.BranchIfFalse(elseClause); generator.LoadString("true"); generator.Branch(endOfIf); generator.DefineLabelPosition(elseClause); generator.LoadString("false"); generator.DefineLabelPosition(endOfIf); break; case PrimitiveType.ConcatenatedString: generator.Call(ReflectionHelpers.ConcatenatedString_ToString); break; case PrimitiveType.Int32: case PrimitiveType.UInt32: case PrimitiveType.Number: case PrimitiveType.Any: case PrimitiveType.Object: // Otherwise, fall back to calling TypeConverter.ToString() if (PrimitiveTypeUtilities.IsValueType(fromType)) generator.Box(fromType); generator.Call(ReflectionHelpers.TypeConverter_ToString); break; default: throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType)); } }
/// <summary> /// Pops the value on the stack, converts it to a concatenated string, then pushes the result /// onto the stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToConcatenatedString(ILGenerator generator, PrimitiveType fromType) { // Check that a conversion is actually necessary. if (fromType == PrimitiveType.ConcatenatedString) return; switch (fromType) { case PrimitiveType.Undefined: case PrimitiveType.Null: case PrimitiveType.Bool: case PrimitiveType.String: // Convert as per ToString, then create a new ConcatenatedString instance. ToString(generator, fromType); generator.NewObject(ReflectionHelpers.ConcatenatedString_Constructor_String); break; case PrimitiveType.Int32: case PrimitiveType.UInt32: case PrimitiveType.Number: case PrimitiveType.Any: case PrimitiveType.Object: // Otherwise, fall back to calling TypeConverter.ToConcatenatedString() if (PrimitiveTypeUtilities.IsValueType(fromType)) generator.Box(fromType); generator.Call(ReflectionHelpers.TypeConverter_ToConcatenatedString); break; default: throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType)); } }
/// <summary> /// Pops the value on the stack, converts it to an object, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> public static void ToAny(ILGenerator generator, PrimitiveType fromType) { if (PrimitiveTypeUtilities.IsValueType(fromType)) generator.Box(fromType); }
/// <summary> /// Pops the value on the stack, converts it to a primitive value, then pushes the result /// onto the stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> /// <param name="preferredType"> Specifies whether toString() or valueOf() should be /// preferred when converting to a primitive. </param> public static void ToPrimitive(ILGenerator generator, PrimitiveType fromType, PrimitiveTypeHint preferredType) { switch (fromType) { case PrimitiveType.Undefined: case PrimitiveType.Null: case PrimitiveType.Bool: case PrimitiveType.String: case PrimitiveType.ConcatenatedString: case PrimitiveType.Int32: case PrimitiveType.UInt32: case PrimitiveType.Number: // These are primitives already. break; case PrimitiveType.Any: case PrimitiveType.Object: // Otherwise, fall back to calling TypeConverter.ToPrimitive() if (PrimitiveTypeUtilities.IsValueType(fromType)) generator.Box(fromType); generator.LoadInt32((int)preferredType); generator.Call(ReflectionHelpers.TypeConverter_ToPrimitive); break; default: throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType)); } }
/// <summary> /// Pops the value on the stack, converts it to an object, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> internal static void EmitConversionToObject(ILGenerator generator, Type fromType) { // If the from type is a reference type, check for null. ILLabel endOfNullCheck = null; if (fromType.IsValueType == false) { var startOfElse = generator.CreateLabel(); endOfNullCheck = generator.CreateLabel(); generator.Duplicate(); generator.BranchIfNotNull(startOfElse); generator.Pop(); EmitHelpers.EmitNull(generator); generator.Branch(endOfNullCheck); generator.DefineLabelPosition(startOfElse); } switch (Type.GetTypeCode(fromType)) { case TypeCode.Boolean: generator.Box(typeof(bool)); break; case TypeCode.Byte: generator.Box(typeof(int)); break; case TypeCode.Char: generator.LoadInt32(1); generator.NewObject(ReflectionHelpers.String_Constructor_Char_Int); break; case TypeCode.DBNull: throw new NotSupportedException("DBNull is not a supported return type."); case TypeCode.Decimal: generator.Call(ReflectionHelpers.Decimal_ToDouble); generator.Box(typeof(double)); break; case TypeCode.Double: generator.Box(typeof(double)); break; case TypeCode.Empty: throw new NotSupportedException("Empty is not a supported return type."); case TypeCode.Int16: generator.Box(typeof(int)); break; case TypeCode.Int32: generator.Box(typeof(int)); break; case TypeCode.Int64: generator.ConvertToDouble(); generator.Box(typeof(double)); break; case TypeCode.DateTime: case TypeCode.Object: // Check if the type must be wrapped with a ClrInstanceWrapper. // Note: if the type is a value type it cannot be a primitive or it would // have been handled elsewhere in the switch. ILLabel endOfWrapCheck = null; if (fromType.IsValueType == false) { generator.Duplicate(); generator.Call(ReflectionHelpers.TypeUtilities_IsPrimitiveOrObject); endOfWrapCheck = generator.CreateLabel(); generator.BranchIfTrue(endOfWrapCheck); } // The type must be wrapped. var temp = generator.CreateTemporaryVariable(fromType); generator.StoreVariable(temp); generator.LoadArgument(0); generator.LoadVariable(temp); if (fromType.IsValueType == true) generator.Box(fromType); generator.ReleaseTemporaryVariable(temp); generator.NewObject(ReflectionHelpers.ClrInstanceWrapper_Constructor); // End of wrap check. if (fromType.IsValueType == false) generator.DefineLabelPosition(endOfWrapCheck); break; case TypeCode.SByte: generator.Box(typeof(int)); break; case TypeCode.Single: generator.Box(typeof(double)); break; case TypeCode.String: break; case TypeCode.UInt16: generator.Box(typeof(int)); break; case TypeCode.UInt32: generator.Box(typeof(uint)); break; case TypeCode.UInt64: generator.ConvertUnsignedToDouble(); generator.Box(typeof(double)); break; } // Label the end of the null check. if (fromType.IsValueType == false) generator.DefineLabelPosition(endOfNullCheck); }
/// <summary> /// Pops the value on the stack, converts it to an object, then pushes the result onto the /// stack. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> internal static void EmitConversionToObject(ILGenerator generator, Type fromType) { // If the from type is a reference type, check for null. ILLabel endOfNullCheck = null; if (fromType.IsValueType == false) { var startOfElse = generator.CreateLabel(); endOfNullCheck = generator.CreateLabel(); generator.Duplicate(); generator.BranchIfNotNull(startOfElse); generator.Pop(); EmitHelpers.EmitNull(generator); generator.Branch(endOfNullCheck); generator.DefineLabelPosition(startOfElse); } // Handle Nullable<>. var isNullable = fromType.IsGenericType && fromType.GetGenericTypeDefinition() == typeof(Nullable <>); if (isNullable) { endOfNullCheck = generator.CreateLabel(); var v = generator.CreateTemporaryVariable(fromType); generator.StoreVariable(v); generator.LoadAddressOfVariable(v); var hasValue = ReflectionHelpers.GetInstanceMethod(fromType, "get_HasValue"); generator.Call(hasValue); generator.BranchIfTrue(endOfNullCheck); // Return null. generator.LoadNull(); generator.Return(); // Jump here if it was NOT null. generator.DefineLabelPosition(endOfNullCheck); // Get the underlying value. generator.LoadAddressOfVariable(v); var getValue = ReflectionHelpers.GetInstanceMethod(fromType, "get_Value"); generator.Call(getValue); // Now let the normal conversion work. fromType = fromType.GenericTypeArguments[0]; } switch (Type.GetTypeCode(fromType)) { case TypeCode.Boolean: generator.Box(typeof(bool)); break; case TypeCode.Byte: generator.Box(typeof(int)); break; case TypeCode.Char: generator.LoadInt32(1); generator.NewObject(ReflectionHelpers.String_Constructor_Char_Int); break; case TypeCode.DBNull: throw new NotSupportedException("DBNull is not a supported return type."); case TypeCode.Decimal: generator.Call(ReflectionHelpers.Decimal_ToDouble); generator.Box(typeof(double)); break; case TypeCode.Double: generator.Box(typeof(double)); break; case TypeCode.Empty: throw new NotSupportedException("Empty is not a supported return type."); case TypeCode.Int16: generator.Box(typeof(int)); break; case TypeCode.Int32: generator.Box(typeof(int)); break; case TypeCode.Int64: generator.ConvertToDouble(); generator.Box(typeof(double)); break; case TypeCode.DateTime: case TypeCode.Object: // Check if the type must be wrapped with a ClrInstanceWrapper. // Note: if the type is a value type it cannot be a primitive or it would // have been handled elsewhere in the switch. ILLabel endOfWrapCheck = null; if (fromType.IsValueType == false) { generator.Duplicate(); generator.Call(ReflectionHelpers.TypeUtilities_IsPrimitiveOrObject); endOfWrapCheck = generator.CreateLabel(); generator.BranchIfTrue(endOfWrapCheck); } // The type must be wrapped. var temp = generator.CreateTemporaryVariable(fromType); generator.StoreVariable(temp); generator.LoadArgument(0); generator.LoadVariable(temp); if (fromType.IsValueType == true) { generator.Box(fromType); } generator.ReleaseTemporaryVariable(temp); generator.CallStatic(ReflectionHelpers.ClrInstanceWrapper_Create); // End of wrap check. if (fromType.IsValueType == false) { generator.DefineLabelPosition(endOfWrapCheck); } break; case TypeCode.SByte: generator.Box(typeof(int)); break; case TypeCode.Single: generator.Box(typeof(double)); break; case TypeCode.String: break; case TypeCode.UInt16: generator.Box(typeof(int)); break; case TypeCode.UInt32: generator.Box(typeof(uint)); break; case TypeCode.UInt64: generator.ConvertUnsignedToDouble(); generator.Box(typeof(double)); break; } // Label the end of the null check. if (fromType.IsValueType == false) { generator.DefineLabelPosition(endOfNullCheck); } }