Пример #1
0
        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;
            }
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
        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());
        }
Пример #5
0
        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());
        }
Пример #6
0
 public static void WriteTypeCode(BinaryWriter writer, Type type)
 {
     writer.Write((byte)ObjectWriter.GetTypeTag(type));
 }