private static void EmitWriteTypeSpec(ILGenerator gen, Type type, string member) { switch (ObjectWriter.GetTypeTag(type)) { case TypeTag.PrimitiveType: gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4_S, BinaryCommon.GetTypeCode(type)); CodeGenerator.EmitWrite(gen, typeof(byte)); break; case TypeTag.RuntimeType: gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldstr, type.FullName); CodeGenerator.EmitWrite(gen, typeof(string)); break; case TypeTag.GenericType: gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldstr, type.FullName); CodeGenerator.EmitWrite(gen, typeof(string)); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldarg_1); CodeGenerator.EmitLoadTypeAssembly(gen, type, member); gen.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null); gen.Emit(OpCodes.Conv_I4); CodeGenerator.EmitWrite(gen, typeof(int)); break; case TypeTag.ArrayOfPrimitiveType: gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4_S, BinaryCommon.GetTypeCode(type.GetElementType())); CodeGenerator.EmitWrite(gen, typeof(byte)); break; } }
public static void EmitWriteTypeSpec(ILGenerator gen, Type type, string member) { // WARNING Keep in sync with WriteTypeSpec switch (ObjectWriter.GetTypeTag(type)) { case TypeTag.PrimitiveType: // EMIT writer.Write (BinaryCommon.GetTypeCode (type)); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4_S, (byte)BinaryCommon.GetTypeCode(type)); EmitWrite(gen, typeof(byte)); break; case TypeTag.RuntimeType: // EMIT writer.Write (type.FullName); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldstr, type.FullName); EmitWrite(gen, typeof(string)); break; case TypeTag.GenericType: // EMIT writer.Write (type.FullName); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldstr, type.FullName); EmitWrite(gen, typeof(string)); // EMIT writer.Write ((int)ow.GetAssemblyId (type.Assembly)); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldarg_1); EmitLoadTypeAssembly(gen, type, member); gen.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null); gen.Emit(OpCodes.Conv_I4); EmitWrite(gen, typeof(int)); break; case TypeTag.ArrayOfPrimitiveType: // EMIT writer.Write (BinaryCommon.GetTypeCode (type.GetElementType())); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4_S, (byte)BinaryCommon.GetTypeCode(type.GetElementType())); EmitWrite(gen, typeof(byte)); break; default: // Type spec not needed break; } }
public void WriteTypeSpec(BinaryWriter writer, Type type) { switch (ObjectWriter.GetTypeTag(type)) { case TypeTag.PrimitiveType: writer.Write(BinaryCommon.GetTypeCode(type)); break; case TypeTag.RuntimeType: { string value = type.FullName; if (this._context.State == StreamingContextStates.Remoting) { if (type == typeof(MonoType)) { value = "System.RuntimeType"; } else if (type == typeof(MonoType[])) { value = "System.RuntimeType[]"; } } writer.Write(value); break; } case TypeTag.GenericType: writer.Write(type.FullName); writer.Write(this.GetAssemblyId(type.Assembly)); break; case TypeTag.ArrayOfPrimitiveType: writer.Write(BinaryCommon.GetTypeCode(type.GetElementType())); break; } }
static public Type GenerateMetadataType(Type type, StreamingContext context) { string name = type.Name + "__TypeMetadata"; string sufix = ""; int n = 0; while (_module.GetType(name + sufix) != null) { sufix = (++n).ToString(); } name += sufix; MemberInfo[] members = FormatterServices.GetSerializableMembers(type, context); TypeBuilder typeBuilder = _module.DefineType(name, TypeAttributes.Public, typeof(ClrTypeMetadata)); Type[] parameters; MethodBuilder method; ILGenerator gen; // ********************* // METHOD public constructor (Type t): base (t); parameters = new Type[0]; ConstructorBuilder ctor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameters); ConstructorInfo baseCtor = typeof(ClrTypeMetadata).GetConstructor(new Type[] { typeof(Type) }); gen = ctor.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldtoken, type); gen.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null); gen.Emit(OpCodes.Call, baseCtor); gen.Emit(OpCodes.Ret); // ********************* // METHOD public override void WriteAssemblies (ObjectWriter ow, BinaryWriter writer); parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter) }; method = typeBuilder.DefineMethod("WriteAssemblies", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters); gen = method.GetILGenerator(); foreach (FieldInfo field in members) { Type memberType = field.FieldType; while (memberType.IsArray) { memberType = memberType.GetElementType(); } if (memberType.Assembly != ObjectWriter.CorlibAssembly) { // EMIT ow.WriteAssembly (writer, memberType.Assembly); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Ldarg_2); EmitLoadTypeAssembly(gen, memberType, field.Name); gen.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null); gen.Emit(OpCodes.Pop); } } gen.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(method, typeof(TypeMetadata).GetMethod("WriteAssemblies")); // ********************* // METHOD public override void WriteTypeData (ObjectWriter ow, BinaryWriter writer, bool writeTypes); parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(bool) }; method = typeBuilder.DefineMethod("WriteTypeData", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters); gen = method.GetILGenerator(); // EMIT writer.Write (members.Length); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4, members.Length); EmitWrite(gen, typeof(int)); // Names of fields foreach (FieldInfo field in members) { // EMIT writer.Write (name); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldstr, field.Name); EmitWrite(gen, typeof(string)); } Label falseLabel = gen.DefineLabel(); gen.Emit(OpCodes.Ldarg_3); gen.Emit(OpCodes.Brfalse, falseLabel); // Types of fields foreach (FieldInfo field in members) { // EMIT writer.Write ((byte) ObjectWriter.GetTypeTag (type)); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4_S, (byte)ObjectWriter.GetTypeTag(field.FieldType)); EmitWrite(gen, typeof(byte)); } // Type specs of fields foreach (FieldInfo field in members) { // EMIT ow.WriteTypeSpec (writer, field.FieldType); EmitWriteTypeSpec(gen, field.FieldType, field.Name); } gen.MarkLabel(falseLabel); gen.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(method, typeof(TypeMetadata).GetMethod("WriteTypeData")); // ********************* // METHOD public override void WriteObjectData (ObjectWriter ow, BinaryWriter writer, object data) parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(object) }; method = typeBuilder.DefineMethod("WriteObjectData", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters); gen = method.GetILGenerator(); LocalBuilder localBuilder = gen.DeclareLocal(type); OpCode lload = OpCodes.Ldloc; gen.Emit(OpCodes.Ldarg_3); if (type.IsValueType) { gen.Emit(OpCodes.Unbox, type); LoadFromPtr(gen, type); lload = OpCodes.Ldloca_S; } else { gen.Emit(OpCodes.Castclass, type); } gen.Emit(OpCodes.Stloc, localBuilder); foreach (FieldInfo field in members) { // EMIT ow.WriteValue (writer, ((FieldInfo)members[n]).FieldType, values[n]); Type ftype = field.FieldType; if (BinaryCommon.IsPrimitive(ftype)) { gen.Emit(OpCodes.Ldarg_2); gen.Emit(lload, localBuilder); if (ftype == typeof(DateTime) || ftype == typeof(TimeSpan) || ftype == typeof(decimal)) { gen.Emit(OpCodes.Ldflda, field); } else { gen.Emit(OpCodes.Ldfld, field); } EmitWritePrimitiveValue(gen, ftype); } else { gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldtoken, ftype); gen.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null); gen.Emit(lload, localBuilder); gen.Emit(OpCodes.Ldfld, field); if (ftype.IsValueType) { gen.Emit(OpCodes.Box, ftype); } gen.EmitCall(OpCodes.Call, typeof(ObjectWriter).GetMethod("WriteValue"), null); } } gen.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(method, typeof(TypeMetadata).GetMethod("WriteObjectData")); return(typeBuilder.CreateType()); }
public static Type GenerateMetadataTypeInternal(Type type, StreamingContext context) { string text = type.Name + "__TypeMetadata"; string str = string.Empty; int num = 0; while (CodeGenerator._module.GetType(text + str) != null) { int num2; num = (num2 = num + 1); str = num2.ToString(); } text += str; MemberInfo[] serializableMembers = FormatterServices.GetSerializableMembers(type, context); TypeBuilder typeBuilder = CodeGenerator._module.DefineType(text, TypeAttributes.Public, typeof(ClrTypeMetadata)); Type[] parameterTypes = Type.EmptyTypes; ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes); ConstructorInfo constructor = typeof(ClrTypeMetadata).GetConstructor(new Type[] { typeof(Type) }); ILGenerator ilgenerator = constructorBuilder.GetILGenerator(); ilgenerator.Emit(OpCodes.Ldarg_0); ilgenerator.Emit(OpCodes.Ldtoken, type); ilgenerator.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null); ilgenerator.Emit(OpCodes.Call, constructor); ilgenerator.Emit(OpCodes.Ret); parameterTypes = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter) }; MethodBuilder methodBuilder = typeBuilder.DefineMethod("WriteAssemblies", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, typeof(void), parameterTypes); ilgenerator = methodBuilder.GetILGenerator(); foreach (FieldInfo fieldInfo in serializableMembers) { Type type2 = fieldInfo.FieldType; while (type2.IsArray) { type2 = type2.GetElementType(); } if (type2.Assembly != ObjectWriter.CorlibAssembly) { ilgenerator.Emit(OpCodes.Ldarg_1); ilgenerator.Emit(OpCodes.Ldarg_2); CodeGenerator.EmitLoadTypeAssembly(ilgenerator, type2, fieldInfo.Name); ilgenerator.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null); ilgenerator.Emit(OpCodes.Pop); } } ilgenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, typeof(TypeMetadata).GetMethod("WriteAssemblies")); parameterTypes = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(bool) }; methodBuilder = typeBuilder.DefineMethod("WriteTypeData", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, typeof(void), parameterTypes); ilgenerator = methodBuilder.GetILGenerator(); ilgenerator.Emit(OpCodes.Ldarg_2); ilgenerator.Emit(OpCodes.Ldc_I4, serializableMembers.Length); CodeGenerator.EmitWrite(ilgenerator, typeof(int)); foreach (FieldInfo fieldInfo2 in serializableMembers) { ilgenerator.Emit(OpCodes.Ldarg_2); ilgenerator.Emit(OpCodes.Ldstr, fieldInfo2.Name); CodeGenerator.EmitWrite(ilgenerator, typeof(string)); } Label label = ilgenerator.DefineLabel(); ilgenerator.Emit(OpCodes.Ldarg_3); ilgenerator.Emit(OpCodes.Brfalse, label); foreach (FieldInfo fieldInfo3 in serializableMembers) { ilgenerator.Emit(OpCodes.Ldarg_2); ilgenerator.Emit(OpCodes.Ldc_I4_S, (byte)ObjectWriter.GetTypeTag(fieldInfo3.FieldType)); CodeGenerator.EmitWrite(ilgenerator, typeof(byte)); } foreach (FieldInfo fieldInfo4 in serializableMembers) { CodeGenerator.EmitWriteTypeSpec(ilgenerator, fieldInfo4.FieldType, fieldInfo4.Name); } ilgenerator.MarkLabel(label); ilgenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, typeof(TypeMetadata).GetMethod("WriteTypeData")); parameterTypes = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(object) }; methodBuilder = typeBuilder.DefineMethod("WriteObjectData", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, typeof(void), parameterTypes); ilgenerator = methodBuilder.GetILGenerator(); LocalBuilder local = ilgenerator.DeclareLocal(type); OpCode opcode = OpCodes.Ldloc; ilgenerator.Emit(OpCodes.Ldarg_3); if (type.IsValueType) { ilgenerator.Emit(OpCodes.Unbox, type); CodeGenerator.LoadFromPtr(ilgenerator, type); opcode = OpCodes.Ldloca_S; } else { ilgenerator.Emit(OpCodes.Castclass, type); } ilgenerator.Emit(OpCodes.Stloc, local); foreach (FieldInfo fieldInfo5 in serializableMembers) { Type fieldType = fieldInfo5.FieldType; if (BinaryCommon.IsPrimitive(fieldType)) { ilgenerator.Emit(OpCodes.Ldarg_2); ilgenerator.Emit(opcode, local); if (fieldType == typeof(DateTime) || fieldType == typeof(TimeSpan) || fieldType == typeof(decimal)) { ilgenerator.Emit(OpCodes.Ldflda, fieldInfo5); } else { ilgenerator.Emit(OpCodes.Ldfld, fieldInfo5); } CodeGenerator.EmitWritePrimitiveValue(ilgenerator, fieldType); } else { ilgenerator.Emit(OpCodes.Ldarg_1); ilgenerator.Emit(OpCodes.Ldarg_2); ilgenerator.Emit(OpCodes.Ldtoken, fieldType); ilgenerator.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null); ilgenerator.Emit(opcode, local); ilgenerator.Emit(OpCodes.Ldfld, fieldInfo5); if (fieldType.IsValueType) { ilgenerator.Emit(OpCodes.Box, fieldType); } ilgenerator.EmitCall(OpCodes.Call, typeof(ObjectWriter).GetMethod("WriteValue"), null); } } ilgenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, typeof(TypeMetadata).GetMethod("WriteObjectData")); return(typeBuilder.CreateType()); }
public static void WriteTypeCode(BinaryWriter writer, Type type) { writer.Write((byte)ObjectWriter.GetTypeTag(type)); }