public void Emit(FieldInfo field, ref EmitHelper serializerEmit, ref EmitHelper deserializeEmit) { var fieldType = field.FieldType; var writeIntMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) }); var dictNotNullLabel = serializerEmit.DefineLabel(); var dictNullLabel = serializerEmit.DefineLabel(); var keyType = fieldType.GetGenericArguments()[0]; if (!keyType.IsPrimitive && !(keyType == typeof(DateTime)) && !(keyType == typeof(string)) && !(keyType == typeof(decimal))) { throw new ArgumentException("Key type does not supported: " + keyType); } var valueType = fieldType.GetGenericArguments()[1]; if (!valueType.IsPrimitive && !(valueType == typeof(DateTime)) && !(valueType == typeof(string)) && !(valueType == typeof(decimal))) { throw new ArgumentException("Value type does not supported: " + valueType); } var dictLocal = serializerEmit.DeclareLocal(fieldType); //construct ICollection<elementType> to call getCount method var keyValuePairType = typeof(KeyValuePair<,>); keyValuePairType = keyValuePairType.MakeGenericType(keyType, valueType); var getKeyMethod = keyValuePairType.GetMethod("get_Key"); var getValueMethod = keyValuePairType.GetMethod("get_Value"); var icollectionType = typeof(ICollection<>).MakeGenericType(keyValuePairType); var getCountMethod = icollectionType.GetMethod("get_Count"); var enumeratorType = typeof(IEnumerator<>).MakeGenericType(keyValuePairType); var getEmumeratorMethod = typeof(IEnumerable<>).MakeGenericType(keyValuePairType).GetMethod("GetEnumerator"); var getCurrentElementMethod = enumeratorType.GetMethod("get_Current"); var keyValuePairLocal = serializerEmit.DeclareLocal(keyValuePairType); var enumeratorLocal = serializerEmit.DeclareLocal(enumeratorType); var startWhileLocal = serializerEmit.DefineLabel(); var startWhileBodyLocal = serializerEmit.DefineLabel(); var valueLocal = serializerEmit.DeclareLocal(valueType); var endFinallyLabel = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .ldfld(field) .stloc(dictLocal) .ldloc(dictLocal) .brtrue(dictNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(writeIntMethod) .br(dictNullLabel) .MarkLabel(dictNotNullLabel); var exTryCatchFinallyLabel = serializerEmit.BeginExceptionBlock(); serializerEmit .ldloc(dictLocal) .call(getEmumeratorMethod) .stloc(enumeratorLocal) .ldarg_1 .ldloc(dictLocal) .call(getCountMethod) .call(writeIntMethod) .br(startWhileLocal) .MarkLabel(startWhileBodyLocal) .ldloc(enumeratorLocal) .call(getCurrentElementMethod) .stloc(keyValuePairLocal) .ldarg_1 .ldloca(keyValuePairLocal) .call(getKeyMethod) .call(typeof(BinaryWriter).GetMethod("Write", new[] { keyType })); if (valueType == typeof(string)) { var valueLocalNotNullLabel = serializerEmit.DefineLabel(); var valueLocalNullLabel = serializerEmit.DefineLabel(); serializerEmit .ldloca(keyValuePairLocal) .call(getValueMethod) .stloc(valueLocal) .ldloc(valueLocal) .brtrue(valueLocalNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .br(valueLocalNullLabel) .MarkLabel(valueLocalNotNullLabel) .ldarg_1 .ldloc(valueLocal) .call(typeof(string).GetMethod("get_Length")) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .ldarg_1 .ldloc(valueLocal) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(string) })) .MarkLabel(valueLocalNullLabel); } else if (valueType.IsPrimitive) { serializerEmit .ldarg_1 .ldloca(keyValuePairLocal) .call(getValueMethod) .call(typeof(BinaryWriter).GetMethod("Write", new[] { valueType })); } serializerEmit .MarkLabel(startWhileLocal) .ldloc(enumeratorLocal) .call(typeof(IEnumerator).GetMethod("MoveNext")) .brtrue(startWhileBodyLocal) .leave(exTryCatchFinallyLabel) .BeginFinallyBlock() .ldloc(enumeratorLocal) .brfalse(endFinallyLabel) .ldloc(enumeratorLocal) .call(typeof(IDisposable).GetMethod("Dispose")) .MarkLabel(endFinallyLabel) .EndExceptionBlock() .MarkLabel(dictNullLabel); var readIntMethod = typeof(BinaryReader).GetMethod("ReadInt32"); var addElementMethod = typeof(IDictionary<,>).MakeGenericType(keyType, valueType).GetMethod("Add", new[] { keyType, valueType }); var dictNotNullLabel2 = deserializeEmit.DefineLabel(); var dictNullLabel2 = deserializeEmit.DefineLabel(); var deserializeDictLocal = deserializeEmit.DeclareLocal(fieldType); var len = deserializeEmit.DeclareLocal(typeof(int)); var i = deserializeEmit.DeclareLocal(typeof(int)); var beginForLabel = deserializeEmit.DefineLabel(); var beginForBodyLabel = deserializeEmit.DefineLabel(); var dictType = fieldType.IsInterface ? typeof(Dictionary<,>).MakeGenericType(keyType, valueType) : fieldType; var keyLocal = deserializeEmit.DeclareLocal(keyType); var valueLocal2 = deserializeEmit.DeclareLocal(valueType); deserializeEmit = deserializeEmit .ldarg_1 .call(readIntMethod) .stloc(len) .ldloc(len) .ldc_i4_m1 .ceq .brfalse(dictNotNullLabel2) .ldarg_0 .ldnull .stfld(field) .br(dictNullLabel2) .MarkLabel(dictNotNullLabel2) .ldloc(len) .newobj(dictType, typeof(int)) .stloc(deserializeDictLocal) .ldc_i4_0 .stloc(i) .br(beginForLabel) .MarkLabel(beginForBodyLabel); if (keyType.IsPrimitive || keyType == typeof(decimal)) { deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("Read" + keyType.Name)) .stloc(keyLocal); } else if (keyType == typeof(DateTime)) { deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt64")) .newobj(typeof(DateTime), typeof(long)) .stloc(keyLocal); } else if (keyType == typeof(string)) { deserializeEmit .ldloca(keyLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .stobj(typeof(string)); } if (valueType.IsPrimitive || valueType == typeof(decimal)) { deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("Read" + keyType.Name)) .stloc(valueLocal2); } else if (valueType == typeof(DateTime)) { deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt64")) .newobj(typeof(DateTime), typeof(long)) .stloc(valueLocal2); } else if (valueType == typeof(string)) { var strNullLabel = deserializeEmit.DefineLabel(); var strNotNullLabel = deserializeEmit.DefineLabel(); deserializeEmit .ldarg_1 .call(readIntMethod) .ldc_i4_m1 .ceq .brfalse(strNotNullLabel) .ldnull .stloc(valueLocal2) .br(strNullLabel) .MarkLabel(strNotNullLabel) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .stloc(valueLocal2) .MarkLabel(strNullLabel); } deserializeEmit .ldloc(deserializeDictLocal) .ldloc(keyLocal) .ldloc(valueLocal2) .call(addElementMethod) .ldloc(i) .ldc_i4_1 .add .stloc(i) .MarkLabel(beginForLabel) .ldloc(i) .ldloc(len) .clt .brtrue(beginForBodyLabel) .ldarg_0 .ldloc(deserializeDictLocal) .stfld(field) .MarkLabel(dictNullLabel2); }
public void Emit(FieldInfo field, ref EmitHelper serializerEmit, ref EmitHelper deserializeEmit) { var writeIntMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) }); var writeStringMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(string) }); var arrayNotNullLabel = serializerEmit.DefineLabel(); var arrayNullLabel = serializerEmit.DefineLabel(); var whileLabel = serializerEmit.DefineLabel(); var endWhileLabel = serializerEmit.DefineLabel(); var elementType = field.FieldType.GetElementType(); var iLocal = serializerEmit.DeclareLocal(typeof(int)); var lenLocal = serializerEmit.DeclareLocal(typeof(int)); serializerEmit .ldarg_0 .ldfld(field) .brtrue(arrayNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(writeIntMethod) .br(arrayNullLabel); serializerEmit .MarkLabel(arrayNotNullLabel) .ldc_i4_0 .stloc(iLocal) .ldarg_0 .ldfld(field) .ldlen .conv_i4 .stloc(lenLocal) .ldarg_1 .ldloc(lenLocal) .call(writeIntMethod) .br(endWhileLabel) .MarkLabel(whileLabel); #region string if (elementType == typeof(string)) { var strElement = serializerEmit.DeclareLocal(typeof(string)); var strElementNullLbl = serializerEmit.DefineLabel(); var strElementNotNullLbl = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .ldfld(field) .ldloc(iLocal) .ldelem_ref .stloc(strElement) .ldloc(strElement) .brtrue(strElementNotNullLbl) .ldarg_1 .ldc_i4_m1 .call(writeIntMethod) .br(strElementNullLbl) .MarkLabel(strElementNotNullLbl) .ldarg_1 .ldloc(strElement) .call(typeof(string).GetMethod("get_Length")) .call(writeIntMethod) .ldarg_1 .ldloc(strElement) .call(writeStringMethod) .MarkLabel(strElementNullLbl) .ldloc(iLocal) .ldc_i4_1 .add .stloc(iLocal); } #endregion #region Primitive, DateTime, decimal else if (elementType.IsPrimitive || elementType == typeof(DateTime) || elementType == typeof(decimal)) { serializerEmit .ldarg_1 .ldarg_0 .ldfld(field) .ldloc(iLocal) .dup .ldc_i4_1 .add .stloc(iLocal); if (elementType == typeof(bool) || elementType == typeof(sbyte)) { serializerEmit = serializerEmit.ldelem_i1; } else if (elementType == typeof(byte)) { serializerEmit = serializerEmit.ldelem_u1; } else if (elementType == typeof(char) || elementType == typeof(ushort)) { serializerEmit = serializerEmit.ldelem_u2; } else if (elementType == typeof(short)) { serializerEmit = serializerEmit.ldelem_i2; } else if (elementType == typeof(int)) { serializerEmit = serializerEmit.ldelem_i4; } else if (elementType == typeof(uint)) { serializerEmit = serializerEmit.ldelem_u4; } else if (elementType == typeof(float)) { serializerEmit = serializerEmit.ldelem_r4; } else if (elementType == typeof(long) || elementType == typeof(ulong)) { serializerEmit = serializerEmit.ldelem_i8; } else if (elementType == typeof(double)) { serializerEmit = serializerEmit.ldelem_r8; } else if (elementType == typeof(decimal)) { serializerEmit = serializerEmit.ldelema(elementType).ldobj(elementType); } else if (elementType == typeof(DateTime)) { serializerEmit = serializerEmit.ldelema(elementType).call(typeof(DateTime).GetMethod("get_Ticks")); } var writeElementType = elementType != typeof(DateTime) ? elementType : typeof(long); serializerEmit .call(typeof(BinaryWriter).GetMethod("Write", new[] { writeElementType })); } #endregion #region object else if (elementType.IsClass) { var obj = serializerEmit.DeclareLocal(typeof(object)); var elementNullLabel = serializerEmit.DefineLabel(); var elementNotNullLabel = serializerEmit.DefineLabel(); var objectExistsLocal = serializerEmit.DefineLabel(); var objectNotExistsLocal = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .ldfld(field) .ldloc(iLocal) .ldelem_ref .stloc(obj) .ldloc(obj) .brtrue(elementNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .br(elementNullLabel) .MarkLabel(elementNotNullLabel) .ldarg_2 .ldloc(obj) .call(typeof(IDictionary<object, int>).GetMethod("ContainsKey", new[] { typeof(object) })) .brtrue(objectExistsLocal) .ldarg_1 .ldarg_3 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .ldloc(obj) .castclass(typeof(ISerializable)) .ldarg_1 .ldarg_2 .ldarg_3 .call(typeof(ISerializable).GetMethod("Serialize")) .br(objectNotExistsLocal) .MarkLabel(objectExistsLocal) .ldarg_1 .ldarg_2 .ldloc(obj) .call(typeof(IDictionary<object, int>).GetMethod("get_Item", new[] { typeof(object) })) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .MarkLabel(objectNotExistsLocal) .MarkLabel(elementNullLabel) .ldloc(iLocal) .ldc_i4_1 .add .stloc(iLocal); } #endregion serializerEmit .MarkLabel(endWhileLabel) .ldloc(iLocal) .ldloc(lenLocal) .blt(whileLabel) .MarkLabel(arrayNullLabel); var readIntMethod = typeof(BinaryReader).GetMethod("ReadInt32"); var arrayNotNullLabel2 = deserializeEmit.DefineLabel(); var arrayNullLabel2 = deserializeEmit.DefineLabel(); var arrayLocal = deserializeEmit.DeclareLocal(field.FieldType); var len = deserializeEmit.DeclareLocal(typeof(int)); var i = deserializeEmit.DeclareLocal(typeof(int)); var beginForLabel = deserializeEmit.DefineLabel(); var beginForBodyLabel = deserializeEmit.DefineLabel(); deserializeEmit = deserializeEmit .ldarg_1 .call(readIntMethod) .stloc(len) .ldloc(len) .ldc_i4_m1 .ceq .brfalse(arrayNotNullLabel2) .ldarg_0 .ldnull .stfld(field) .br(arrayNullLabel2) .MarkLabel(arrayNotNullLabel2) .ldloc(len) .newarr(elementType) .stloc(arrayLocal) .ldc_i4_0 .stloc(i) .br(beginForLabel) .MarkLabel(beginForBodyLabel); #region Primitive, decimal, DateTime if (elementType.IsPrimitive) { deserializeEmit .ldloc(arrayLocal) .ldloc(i) .ldarg_1 .call(typeof(BinaryReader).GetMethod("Read" + elementType.Name)); if (elementType == typeof(bool) || elementType == typeof(sbyte) || elementType == typeof(byte)) { deserializeEmit = deserializeEmit.stelem_i1; } else if (elementType == typeof(char) || elementType == typeof(ushort) || elementType == typeof(short)) { deserializeEmit = deserializeEmit.stelem_i2; } else if (elementType == typeof(int) || elementType == typeof(uint)) { deserializeEmit = deserializeEmit.stelem_i4; } else if (elementType == typeof(float)) { deserializeEmit = deserializeEmit.stelem_r4; } else if (elementType == typeof(long) || elementType == typeof(ulong)) { deserializeEmit = deserializeEmit.stelem_i8; } else if (elementType == typeof(double)) { deserializeEmit = deserializeEmit.stelem_r8; } } else if (elementType == typeof(decimal)) { deserializeEmit .ldloc(arrayLocal) .ldloc(i) .ldelema(typeof(decimal)) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadDecimal")) .stobj(typeof(decimal)); } else if (elementType == typeof(DateTime)) { deserializeEmit .ldloc(arrayLocal) .ldloc(i) .ldelema(typeof(DateTime)) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt64")) .newobj(typeof(DateTime), typeof(long)) .stobj(typeof(DateTime)); } #endregion #region string else if (elementType == typeof(string)) { var strLen = deserializeEmit.DeclareLocal(typeof(int)); var strNullLabel = deserializeEmit.DefineLabel(); var strNotNullLabel = deserializeEmit.DefineLabel(); deserializeEmit .ldarg_1 .call(readIntMethod) .stloc(strLen) .ldloc(strLen) .ldc_i4_m1 .ceq .brfalse(strNotNullLabel) .ldloc(arrayLocal) .ldloc(i) .ldelema(typeof(string)) .ldnull .stobj(typeof(string)) .br(strNullLabel) .MarkLabel(strNotNullLabel) .ldloc(arrayLocal) .ldloc(i) .ldelema(typeof(string)) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .stobj(typeof(string)) .MarkLabel(strNullLabel); } #endregion #region object var desElementNullLabel = deserializeEmit.DefineLabel(); var desElementNotNullLabel = deserializeEmit.DefineLabel(); var propertyInstanceType = deserializeEmit.DeclareLocal(typeof(Type)); var indexLocal = deserializeEmit.DeclareLocal(typeof(int)); var desobjectExistsLocal = deserializeEmit.DefineLabel(); var desobjectNotExistsLocal = deserializeEmit.DefineLabel(); deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt32")) .stloc(indexLocal) .ldloc(indexLocal) .ldc_i4_m1 .ceq .brfalse(desElementNotNullLabel) .ldloc(arrayLocal) .ldloc(i) .ldelema(elementType) .ldnull .stobj(elementType) .br(desElementNullLabel) .MarkLabel(desElementNotNullLabel) .ldarg_2 .ldloc(indexLocal) .call(typeof(IDictionary<int, object>).GetMethod("ContainsKey", new Type[] { typeof(int) })) .brfalse(desobjectNotExistsLocal) .ldloc(arrayLocal) .ldloc(i) .ldelema(elementType) .ldarg_2 .ldloc(indexLocal) .call(typeof(IDictionary<int, object>).GetMethod("get_Item", new Type[] { typeof(int) })) .castclass(elementType) .stobj(elementType) .br(desobjectExistsLocal) .MarkLabel(desobjectNotExistsLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .call(typeof(Type).GetMethod("GetType", new Type[] { typeof(string) })) .stloc(propertyInstanceType) .ldloc(arrayLocal) .ldloc(i) .ldelema(elementType) .ldloc(propertyInstanceType) .call(typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type) })) .castclass(elementType) .stobj(elementType) .ldarg_2 .ldloc(indexLocal) .ldloc(arrayLocal) .ldloc(i) .ldelem_ref .call(typeof(IDictionary<int, object>).GetMethod("Add", new[] { typeof(int), typeof(object) })) .ldloc(arrayLocal) .ldloc(i) .ldelem_ref .castclass(typeof(ISerializable)) .ldarg_1 .ldarg_2 .call(typeof(ISerializable).GetMethod("Deserialize", new Type[] { typeof(BinaryReader), typeof(IDictionary<int, object>) })) .MarkLabel(desobjectExistsLocal) .MarkLabel(desElementNullLabel); #endregion deserializeEmit .ldloc(i) .ldc_i4_1 .add .stloc(i) .MarkLabel(beginForLabel) .ldloc(i) .ldloc(len) .clt .brtrue(beginForBodyLabel) .ldarg_0 .ldloc(arrayLocal) .stfld(field) .MarkLabel(arrayNullLabel2); }
private void CreateInitContextDefaultInstance( string initContextName, FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; LocalBuilder initField = GetInitContextBuilder(initContextName, emit); MethodInfo memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod(); if (parameters != null) { emit .ldloc (initField) .ldsfld (GetParameterField()) .callvirt (memberParams) ; } else if ((bool)Context.Items["$BLToolkit.Default.DirtyParameters"]) { emit .ldloc (initField) .ldnull .callvirt (memberParams) ; } Context.Items["$BLToolkit.Default.DirtyParameters"] = parameters != null; if (objectType.IsAbstract) { emit .ldarg_0 .ldsfld (GetTypeAccessorField()) .ldloc (initField) .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) .isinst (objectType) ; } else { emit .ldarg_0 .ldloc (initField) .newobj (objectType.GetPublicConstructor(typeof(InitContext))) ; } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
public void Emit(FieldInfo field, ref EmitHelper serializerEmit, ref EmitHelper deserializeEmit) { var fieldType = field.FieldType; var writeStringMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(string) }); var writeIntMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) }); var listNotNullLabel = serializerEmit.DefineLabel(); var listNullLabel = serializerEmit.DefineLabel(); var whileLabel = serializerEmit.DefineLabel(); var endWhileLabel = serializerEmit.DefineLabel(); var elementType = fieldType.GetGenericArguments()[0]; var iLocal = serializerEmit.DeclareLocal(typeof(int)); var lenLocal = serializerEmit.DeclareLocal(typeof(int)); //construct ICollection<elementType> to call getCount method var icollectionType = typeof(ICollection<>).MakeGenericType(elementType); var getCountMethod = icollectionType.GetMethod("get_Count"); serializerEmit .ldarg_0 .ldfld(field) .brtrue(listNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(writeIntMethod) .br(listNullLabel) .MarkLabel(listNotNullLabel) .ldc_i4_0 .stloc(iLocal) .ldarg_0 .ldfld(field) .call(getCountMethod) .stloc(lenLocal) .ldarg_1 .ldloc(lenLocal) .call(writeIntMethod) .br(endWhileLabel) .MarkLabel(whileLabel); if (elementType == typeof(string)) { var strElement = serializerEmit.DeclareLocal(typeof(string)); var strElementNullLbl = serializerEmit.DefineLabel(); var strElementNotNullLbl = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .ldfld(field) .ldloc(iLocal) .call(fieldType.GetMethod("get_Item")) .stloc(strElement) .ldloc(strElement) .brtrue(strElementNotNullLbl) .ldarg_1 .ldc_i4_m1 .call(writeIntMethod) .br(strElementNullLbl) .MarkLabel(strElementNotNullLbl) .ldarg_1 .ldloc(strElement) .call(typeof(string).GetMethod("get_Length")) .call(writeIntMethod) .ldarg_1 .ldloc(strElement) .call(writeStringMethod) .MarkLabel(strElementNullLbl) .ldloc(iLocal) .ldc_i4_1 .add .stloc(iLocal); } else if (elementType.IsPrimitive || elementType == typeof(DateTime) || elementType == typeof(decimal)) { serializerEmit .ldarg_1 .ldarg_0 .ldfld(field) .ldloc(iLocal) .dup .ldc_i4_1 .add .stloc(iLocal) .call(fieldType.GetMethod("get_Item")); var writeElementType = elementType != typeof(DateTime) ? elementType : typeof(long); serializerEmit .call(typeof(BinaryWriter).GetMethod("Write", new[] { writeElementType })); } else if (elementType.IsClass) { var obj = serializerEmit.DeclareLocal(typeof(object)); var elementNullLabel = serializerEmit.DefineLabel(); var elementNotNullLabel = serializerEmit.DefineLabel(); var objectExistsLocal = serializerEmit.DefineLabel(); var objectNotExistsLocal = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .ldfld(field) .ldloc(iLocal) .call(fieldType.GetMethod("get_Item")) .stloc(obj) .ldloc(obj) .brtrue(elementNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .br(elementNullLabel) .MarkLabel(elementNotNullLabel) .ldarg_2 .ldloc(obj) .call(typeof(IDictionary<object, int>).GetMethod("ContainsKey", new[] { typeof(object) })) .brtrue(objectExistsLocal) .ldarg_1 .ldarg_3 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .ldloc(obj) .castclass(typeof(ISerializable)) .ldarg_1 .ldarg_2 .ldarg_3 .call(typeof(ISerializable).GetMethod("Serialize")) .br(objectNotExistsLocal) .MarkLabel(objectExistsLocal) .ldarg_1 .ldarg_2 .ldloc(obj) .call(typeof(IDictionary<object, int>).GetMethod("get_Item", new[] { typeof(object) })) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .MarkLabel(objectNotExistsLocal) .MarkLabel(elementNullLabel) .ldloc(iLocal) .ldc_i4_1 .add .stloc(iLocal); } else { throw new ArgumentException("Element type does not supported: " + elementType); } serializerEmit .MarkLabel(endWhileLabel) .ldloc(iLocal) .ldloc(lenLocal) .blt(whileLabel) .MarkLabel(listNullLabel); var readIntMethod = typeof(BinaryReader).GetMethod("ReadInt32"); var addElementMethod = typeof(ICollection<>).MakeGenericType(elementType).GetMethod("Add"); var listNotNullLabel2 = deserializeEmit.DefineLabel(); var listNullLabel2 = deserializeEmit.DefineLabel(); var listLocal = deserializeEmit.DeclareLocal(fieldType); var len = deserializeEmit.DeclareLocal(typeof(int)); var i = deserializeEmit.DeclareLocal(typeof(int)); var beginForLabel = deserializeEmit.DefineLabel(); var beginForBodyLabel = deserializeEmit.DefineLabel(); var listType = fieldType.IsInterface ? typeof(List<>).MakeGenericType(elementType) : fieldType; deserializeEmit = deserializeEmit .ldarg_1 .call(readIntMethod) .stloc(len) .ldloc(len) .ldc_i4_m1 .ceq .brfalse(listNotNullLabel2) .ldarg_0 .ldnull .stfld(field) .br(listNullLabel2) .MarkLabel(listNotNullLabel2) .ldloc(len) .newobj(listType, typeof(int)) .stloc(listLocal) .ldc_i4_0 .stloc(i) .br(beginForLabel) .MarkLabel(beginForBodyLabel); if (elementType.IsPrimitive) { deserializeEmit .ldloc(listLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("Read" + elementType.Name)) .call(addElementMethod); } else if (elementType == typeof(DateTime)) { deserializeEmit .ldloc(listLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt64")) .newobj(typeof(DateTime), typeof(long)) .call(addElementMethod); } else if (elementType == typeof(string)) { var strLen = deserializeEmit.DeclareLocal(typeof(int)); var strNullLabel = deserializeEmit.DefineLabel(); var strNotNullLabel = deserializeEmit.DefineLabel(); deserializeEmit .ldarg_1 .call(readIntMethod) .stloc(strLen) .ldloc(strLen) .ldc_i4_m1 .ceq .brfalse(strNotNullLabel) .ldloc(listLocal) .ldnull .call(addElementMethod) .br(strNullLabel) .MarkLabel(strNotNullLabel) .ldloc(listLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .call(addElementMethod) .MarkLabel(strNullLabel); } else if (elementType.IsClass) { var desElementNullLabel = deserializeEmit.DefineLabel(); var desElementNotNullLabel = deserializeEmit.DefineLabel(); var propertyInstanceType = deserializeEmit.DeclareLocal(typeof(Type)); var indexLocal = deserializeEmit.DeclareLocal(typeof(int)); var desobjectExistsLocal = deserializeEmit.DefineLabel(); var desobjectNotExistsLocal = deserializeEmit.DefineLabel(); var tmpObjectLocal = deserializeEmit.DeclareLocal(elementType); var desTypeName = deserializeEmit.DeclareLocal(typeof(string)); deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt32")) .stloc(indexLocal) .ldloc(indexLocal) .ldc_i4_m1 .ceq .brfalse(desElementNotNullLabel) .ldloc(listLocal) .ldnull .call(addElementMethod) .br(desElementNullLabel) .MarkLabel(desElementNotNullLabel) .ldarg_2 .ldloc(indexLocal) .call(typeof(IDictionary<int, object>).GetMethod("ContainsKey", new Type[] { typeof(int) })) .brfalse(desobjectNotExistsLocal) .ldloc(listLocal) .ldarg_2 .ldloc(indexLocal) .callvirt(typeof(IDictionary<int, object>).GetMethod("get_Item", new Type[] { typeof(int) })) .castclass(elementType) .call(addElementMethod) .br(desobjectExistsLocal) .MarkLabel(desobjectNotExistsLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .stloc(desTypeName) .ldloc(desTypeName) .ldc_i4_1 .call(typeof(Type).GetMethod("GetType", new Type[] { typeof(string), typeof(bool) })) .stloc(propertyInstanceType) .ldloc(propertyInstanceType) .call(typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type) })) .castclass(elementType) .stloc(tmpObjectLocal) .ldarg_2 .ldloc(indexLocal) .ldloc(tmpObjectLocal) .call(typeof(IDictionary<int, object>).GetMethod("Add", new[] { typeof(int), typeof(object) })) .ldloc(tmpObjectLocal) .castclass(typeof(ISerializable)) .ldarg_1 .ldarg_2 .call(typeof(ISerializable).GetMethod("Deserialize", new Type[] { typeof(BinaryReader), typeof(IDictionary<int, object>) })) .ldloc(listLocal) .ldloc(tmpObjectLocal) .call(addElementMethod) .MarkLabel(desobjectExistsLocal) .MarkLabel(desElementNullLabel); } deserializeEmit .ldloc(i) .ldc_i4_1 .add .stloc(i) .MarkLabel(beginForLabel) .ldloc(i) .ldloc(len) .clt .brtrue(beginForBodyLabel) .ldarg_0 .ldloc(listLocal) .stfld(field) .MarkLabel(listNullLabel2); }
private void EmitSyncCall(List<ParameterInfo> parameters, EmitHelper emit) { Context.MethodBuilder.MethodBuilder.SetCustomAttribute(_soapDocumentAttributeBuilder); bool withOutParameters = EmitParameters(emit, parameters); bool callGeneric = !withOutParameters && Context.CurrentMethod.ReturnType != typeof(void); // Use Invoke<T>() for methods with return value but // Invoke() for methods with no return value or with out/ref parameters. // MethodInfo invoke = TypeHelper.GetMethod( typeof(WebClientBase), callGeneric, "Invoke", BindingFlags.Public | BindingFlags.Instance); if (callGeneric) { emit .call (invoke.MakeGenericMethod(Context.CurrentMethod.ReturnType)) .stloc (Context.ReturnValue) ; } else { if (withOutParameters) { LocalBuilder ret = emit.DeclareLocal(typeof(object[])); Label exit = emit.DefineLabel(); emit .call (invoke) .dup .stloc (ret) .brfalse_s (exit) ; int idx = 0; if (Context.CurrentMethod.ReturnType != typeof(void)) { emit .ldloc (ret) .ldc_i4_0 .ldelem_ref .CastFromObject (Context.CurrentMethod.ReturnType) .stloc (Context.ReturnValue) ; ++idx; } for (int i = 0; i < parameters.Count; ++i) { ParameterInfo pi = parameters[i]; Type type = pi.ParameterType; if (!type.IsByRef) continue; // Get ride of ref // type = type.GetElementType(); emit .ldarg (pi) .ldloc (ret) .ldc_i4_ (idx) .ldelem_ref .CastFromObject (type) .stind (type) ; ++idx; } emit.MarkLabel(exit); } else { emit .call (invoke) .pop .end () ; } } }