public static TypeInfo BuildType(DynamicAssembly assembly, Type type, bool forceStringKey) { var serializationInfo = MessagePack.Internal.ObjectSerializationInfo.CreateOrNull(type, forceStringKey); if (serializationInfo == null) { return(null); } var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); var typeBuilder = assembly.ModuleBuilder.DefineType("MessagePack.Formatters." + type.FullName.Replace(".", "_") + "Formatter", TypeAttributes.Public | TypeAttributes.Sealed, null, new[] { formatterType }); FieldBuilder dictionaryField = null; // string key needs string->int mapper for deserialize switch statement if (serializationInfo.IsStringKey) { var method = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); dictionaryField = typeBuilder.DefineField("keyMapping", typeof(Dictionary <string, int>), FieldAttributes.Private | FieldAttributes.InitOnly); var il = method.GetILGenerator(); BuildConstructor(type, serializationInfo, method, dictionaryField, il); } { var method = typeBuilder.DefineMethod("Serialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, typeof(int), new Type[] { typeof(byte[]).MakeByRefType(), typeof(int), type, typeof(IFormatterResolver) }); var il = method.GetILGenerator(); BuildSerialize(type, serializationInfo, method, il); } { var method = typeBuilder.DefineMethod("Deserialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, type, new Type[] { typeof(byte[]), typeof(int), typeof(IFormatterResolver), typeof(int).MakeByRefType() }); var il = method.GetILGenerator(); BuildDeserialize(type, serializationInfo, method, dictionaryField, il); } return(typeBuilder.CreateTypeInfo()); }
public static MethodInfo GetGetKeyMethod() { if (dynamicGetKeyMethod == null) { lock (gate) { if (dynamicGetKeyMethod == null) { dynamicAssembly = new DynamicAssembly("AutomataKeyGenHelper"); var helperType = dynamicAssembly.DefineType("AutomataKeyGen", TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract, null); var dm = helperType.DefineMethod("GetKey", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, typeof(ulong), new[] { typeof(byte).MakePointerType().MakeByRefType(), typeof(int).MakeByRefType() }); var il = dm.GetILGenerator(); il.DeclareLocal(typeof(int)); // var readSize il.DeclareLocal(typeof(ulong)); // var key = il.DeclareLocal(typeof(int)); // var _local = var elseLabel = il.DefineLabel(); var endLabel = il.DefineLabel(); var case0 = il.DefineLabel(); var case1 = il.DefineLabel(); var case2 = il.DefineLabel(); var case3 = il.DefineLabel(); var case4 = il.DefineLabel(); var case5 = il.DefineLabel(); var case6 = il.DefineLabel(); var case7 = il.DefineLabel(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldind_I4); il.Emit(OpCodes.Ldc_I4_8); il.Emit(OpCodes.Blt_S, elseLabel); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_I8); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_8); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(elseLabel); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldind_I4); il.Emit(OpCodes.Stloc_2); il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Switch, new[] { case0, case1, case2, case3, case4, case5, case6, case7 }); il.Emit(OpCodes.Br, case0); // default il.MarkLabel(case1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U1); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case2); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U2); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_2); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case3); il.DeclareLocal(typeof(ushort)); // _3 il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldind_U2); il.Emit(OpCodes.Stloc_3); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldloc_3); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldc_I4_8); il.Emit(OpCodes.Shl); il.Emit(OpCodes.Or); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_3); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case4); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U4); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_4); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case5); il.DeclareLocal(typeof(uint)); // _4 il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldind_U4); il.Emit(OpCodes.Stloc_S, 4); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldloc_S, 4); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldc_I4_8); il.Emit(OpCodes.Shl); il.Emit(OpCodes.Or); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_5); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case6); il.DeclareLocal(typeof(ulong)); // _5 il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U2); il.Emit(OpCodes.Conv_U8); // [x] il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldc_I4_2); il.Emit(OpCodes.Add); // [x, y] il.Emit(OpCodes.Ldind_U4); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Stloc_S, 5); // [x] il.Emit(OpCodes.Ldloc_S, 5); il.Emit(OpCodes.Ldc_I4_S, 16); il.Emit(OpCodes.Shl); il.Emit(OpCodes.Or); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_6); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case7); il.DeclareLocal(typeof(ushort)); // _6 il.DeclareLocal(typeof(uint)); // _7 il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldind_U1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldind_U2); il.Emit(OpCodes.Stloc_S, 6); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldc_I4_3); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldind_U4); il.Emit(OpCodes.Stloc_S, 7); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldloc_S, 6); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldc_I4_8); il.Emit(OpCodes.Shl); il.Emit(OpCodes.Or); il.Emit(OpCodes.Ldloc_S, 7); il.Emit(OpCodes.Conv_U8); il.Emit(OpCodes.Ldc_I4_S, 24); il.Emit(OpCodes.Shl); il.Emit(OpCodes.Or); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldc_I4_7); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(case0); il.Emit(OpCodes.Ldstr, "Not Supported Length"); il.Emit(OpCodes.Newobj, typeof(InvalidOperationException).GetConstructor(new[] { typeof(string) })); il.Emit(OpCodes.Throw); il.MarkLabel(endLabel); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_I); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stind_I); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldind_I4); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Stind_I4); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ret); var genereatedType = helperType.CreateTypeInfo().AsType(); dynamicGetKeyMethod = genereatedType.GetMethods().First(); } } } return(dynamicGetKeyMethod); }