public void EmitDeserialize(PropertyInfo property, ref EmitHelper deserializeEmit) { var propertyType = property.PropertyType; var propertyNullLabel = deserializeEmit.DefineLabel(); var propertyNotNullLabel = deserializeEmit.DefineLabel(); var propertyInstanceType = deserializeEmit.DeclareLocal(typeof(Type)); var indexLocal = deserializeEmit.DeclareLocal(typeof(int)); var objectExistsLocal = deserializeEmit.DefineLabel(); var objectNotExistsLocal = deserializeEmit.DefineLabel(); deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt32")) .stloc(indexLocal) .ldloc(indexLocal) .ldc_i4_m1 .ceq .brfalse(propertyNotNullLabel) .ldarg_0 .ldnull .call(property.GetSetMethod()) .br(propertyNullLabel) .MarkLabel(propertyNotNullLabel) .ldarg_2 .ldloc(indexLocal) .call(typeof(IDictionary<int, object>).GetMethod("ContainsKey", new Type[] { typeof(int) })) .brfalse(objectNotExistsLocal) .ldarg_0 .ldarg_2 .ldloc(indexLocal) .call(typeof(IDictionary<int, object>).GetMethod("get_Item", new Type[] { typeof(int) })) .castclass(propertyType) .call(property.GetSetMethod()) .br(objectExistsLocal) .MarkLabel(objectNotExistsLocal) .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .call(typeof(Type).GetMethod("GetType", new Type[] { typeof(string) })) .stloc(propertyInstanceType) .ldarg_0 .ldloc(propertyInstanceType) .call(typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type) })) .call(typeof(Converter).GetMethod("Convert", new[] { typeof(object) })) .castclass(propertyType) .call(property.GetSetMethod()) .ldarg_2 .ldloc(indexLocal) .ldarg_0 .call(property.GetGetMethod()) .call(typeof(IDictionary<int, object>).GetMethod("Add", new[] { typeof(int), typeof(object) })) .ldarg_0 .call(property.GetGetMethod()) .castclass(typeof(ISerializable)) .ldarg_1 .ldarg_2 .call(typeof(ISerializable).GetMethod("Deserialize", new Type[] { typeof(BinaryReader), typeof(IDictionary<int, object>) })) .MarkLabel(objectExistsLocal) .MarkLabel(propertyNullLabel); }
public void EmitSerialize(PropertyInfo property, ref EmitHelper serializerEmit) { var obj = serializerEmit.DeclareLocal(typeof(object)); var propertyNullLabel = serializerEmit.DefineLabel(); var propertyNotNullLabel = serializerEmit.DefineLabel(); var objectExistsLocal = serializerEmit.DefineLabel(); var objectNotExistsLocal = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .call(property.GetGetMethod()) .stloc(obj) .ldloc(obj) .brtrue(propertyNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .br(propertyNullLabel) .MarkLabel(propertyNotNullLabel) .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(propertyNullLabel); }
private void CheckNull(EmitHelper emit) { if (_throwExceptionIfNull == false && string.IsNullOrEmpty(_exceptionMessage)) { emit .brfalse (Context.ReturnLabel) ; } else { string message = string.Format( string.IsNullOrEmpty(_exceptionMessage)? "'{0}.{1}' is not initialized." : _exceptionMessage, _targetInterface.Name, _memberName, _targetInterface.FullName); Label label = emit.DefineLabel(); emit .brtrue (label) .ldstr (message) .newobj (typeof(InvalidOperationException), typeof(string)) .@throw .MarkLabel (label) ; } }
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); }
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 CreateAbstractInitContextInstance( FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; MethodInfo memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod(); LocalBuilder parentField = (LocalBuilder)Context.Items["$BLToolkit.InitContext.Parent"]; if (parentField == null) { Context.Items["$BLToolkit.InitContext.Parent"] = parentField = emit.DeclareLocal(typeof(object)); Label label = emit.DefineLabel(); emit .ldarg_1 .brtrue_s (label) .newobj (InitContextType.GetPublicDefaultConstructor()) .starg (1) .ldarg_1 .ldc_i4_1 .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod()) .MarkLabel (label) .ldarg_1 .callvirt (InitContextType.GetProperty("Parent").GetGetMethod()) .stloc (parentField) ; } emit .ldarg_1 .ldarg_0 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) ; object isDirty = Context.Items["$BLToolkit.InitContext.DirtyParameters"]; if (parameters != null) { emit .ldarg_1 .ldsfld (GetParameterField()) .callvirt (memberParams) ; } else if (isDirty != null && (bool)isDirty) { emit .ldarg_1 .ldnull .callvirt (memberParams) ; } Context.Items["$BLToolkit.InitContext.DirtyParameters"] = parameters != null; if (objectType.IsAbstract) { emit .ldarg_0 .ldsfld (GetTypeAccessorField()) .ldarg_1 .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) .isinst (objectType) ; } else { emit .ldarg_0 .ldarg_1 .newobj (objectType.GetPublicConstructor(typeof(InitContext))) ; } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
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 () ; } } }
private void EmitCookie(EmitHelper emit) { string fieldName = "_cookie$" + Context.CurrentMethod.Name; FieldBuilder field = Context.GetField(fieldName) ?? Context.CreateField(fieldName, typeof(AsyncCallState), FieldAttributes.Private); Label checkCookie = emit.DefineLabel(); emit .ldarg_0 .ldfld (field) .dup .brtrue_s (checkCookie) .pop .ldarg_0 .dup .newobj (typeof(AsyncCallState)) .stfld (field) .ldfld (field) .MarkLabel (checkCookie) ; }
public void Emit(FieldInfo field, ref EmitHelper serializerEmit, ref EmitHelper deserializeEmit) { var fieldType = field.FieldType; var writerMethod = typeof(BinaryWriter).GetMethod("Write", new Type[] { fieldType }); var readerMethod = typeof(BinaryReader).GetMethod("Read" + fieldType.Name); if (fieldType.IsPrimitive || fieldType == typeof(decimal)) { serializerEmit .ldarg_1 .ldarg_0 .ldfld(field) .call(writerMethod); deserializeEmit .ldarg_0 .ldarg_1 .call(readerMethod) .stfld(field); } else if (fieldType == typeof(DateTime)) { var writeLongMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(long) }); var readLongMethod = typeof(BinaryReader).GetMethod("ReadInt64"); serializerEmit.DeclareLocal(typeof(DateTime)); serializerEmit .ldarg_1 .ldarg_0 .ldfld(field) .stloc_0 .ldloca(0) .call(typeof(DateTime).GetMethod("get_Ticks")) .call(writeLongMethod); deserializeEmit .ldarg_0 .ldarg_1 .call(readLongMethod) .newobj(typeof(DateTime), new[] { typeof(long) }) .stfld(field); } else if (fieldType == typeof(string)) { var stringLocal = serializerEmit.DeclareLocal(fieldType); var stringNullLabel = serializerEmit.DefineLabel(); var stringNotNullLabel = serializerEmit.DefineLabel(); serializerEmit .ldarg_0 .ldfld(field) .stloc(stringLocal) .ldloc(stringLocal) .brtrue(stringNotNullLabel) .ldarg_1 .ldc_i4_m1 .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .br(stringNullLabel) .MarkLabel(stringNotNullLabel) .ldarg_1 .ldloc(stringLocal) .call(typeof(string).GetMethod("get_Length")) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(int) })) .ldarg_1 .ldloc(stringLocal) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(string) })) .MarkLabel(stringNullLabel); var valueNotNullLabel = deserializeEmit.DefineLabel(); var valueNullLabel = deserializeEmit.DefineLabel(); deserializeEmit .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadInt32")) .ldc_i4_m1 .ceq .brfalse(valueNotNullLabel) .ldarg_0 .ldnull .stfld(field) .br(valueNullLabel) .MarkLabel(valueNotNullLabel) .ldarg_0 .ldarg_1 .call(typeof(BinaryReader).GetMethod("ReadString")) .stfld(field) .MarkLabel(valueNullLabel); } }