public static void EmitThrowException <T>(this ILGenerator il, string s = null) where T : Exception { var invalidcast = typeof(T); il.Emit(OpCodes.Ldstr, s ?? "message"); il.Emit(OpCodes.Newobj, invalidcast.GetConstructor(new[] { typeof(string) })); il.ThrowException(invalidcast); }
protected override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder, System.Reflection.Emit.ILGenerator il) { var convention = config.Conventions.OfType <TransactionProxyConvention>().First(); var stringEqual = typeof(string).GetMethod("op_Equality", new Type[] { typeof(string), typeof(string) }); var getValueEntriesMethod = typeof(TransactionProxyHelper).GetMethod("GetValueEntries"); var propertyLabels = new Dictionary <TransactionProxyConvention.TransactionProxyProperty, Label>(); var returnLabel = il.DefineLabel(); var notFoundLabel = il.DefineLabel(); foreach (var item in convention.TransactionProxyProperties) { var label = il.DefineLabel(); propertyLabels.Add(item, label); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldstr, item.Property.Name); il.Emit(OpCodes.Call, stringEqual); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, label); il.Emit(OpCodes.Nop); } il.Emit(OpCodes.Br, notFoundLabel); foreach (var item in propertyLabels) { var method = getValueEntriesMethod.MakeGenericMethod(item.Key.Property.PropertyType, convention.ItemType); il.MarkLabel(item.Value); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.Key.ValuesProperty.BackingField); il.EmitCall(OpCodes.Call, method, null); il.Emit(OpCodes.Br, returnLabel); } var exceptionType = typeof(ArgumentOutOfRangeException); il.MarkLabel(notFoundLabel); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Newobj, exceptionType.GetConstructor(new Type[] { typeof(string) })); il.ThrowException(exceptionType); il.MarkLabel(returnLabel); il.Emit(OpCodes.Ret); }
static void GenerateDeserializerSwitch(CodeGenContext ctx, ILGenerator il, IDictionary<Type, TypeData> map) { // arg0: stream, arg1: out object D(il, "deser switch"); var idLocal = il.DeclareLocal(typeof(ushort)); // read typeID il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloca_S, idLocal); il.EmitCall(OpCodes.Call, ctx.GetReaderMethodInfo(typeof(ushort)), null); // +1 for 0 (null) var jumpTable = new Label[map.Count + 1]; jumpTable[0] = il.DefineLabel(); foreach (var kvp in map) jumpTable[kvp.Value.TypeID] = il.DefineLabel(); il.Emit(OpCodes.Ldloc_S, idLocal); il.Emit(OpCodes.Switch, jumpTable); D(il, "eihx"); il.ThrowException(typeof(Exception)); /* null case */ il.MarkLabel(jumpTable[0]); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stind_Ref); il.Emit(OpCodes.Ret); /* cases for types */ foreach (var kvp in map) { var type = kvp.Key; var data = kvp.Value; il.MarkLabel(jumpTable[data.TypeID]); var local = il.DeclareLocal(type); // call deserializer for this typeID il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloca_S, local); if (data.WriterMethodInfo.IsGenericMethodDefinition) { Debug.Assert(type.IsGenericType); var genArgs = type.GetGenericArguments(); il.EmitCall(OpCodes.Call, data.ReaderMethodInfo.MakeGenericMethod(genArgs), null); } else { il.EmitCall(OpCodes.Call, data.ReaderMethodInfo, null); } // write result object to out object il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloc_S, local); if (type.IsValueType) il.Emit(OpCodes.Box, type); il.Emit(OpCodes.Stind_Ref); D(il, "deser switch done"); il.Emit(OpCodes.Ret); } }
static void GenerateSerializerSwitch(CodeGenContext ctx, ILGenerator il, IDictionary<Type, TypeData> map) { // arg0: Stream, arg1: object var idLocal = il.DeclareLocal(typeof(ushort)); // get TypeID from object's Type var getTypeIDMethod = typeof(Serializer).GetMethod("GetTypeID", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(object) }, null); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Call, getTypeIDMethod, null); il.Emit(OpCodes.Stloc_S, idLocal); // write typeID il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloc_S, idLocal); il.EmitCall(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(ushort)), null); // +1 for 0 (null) var jumpTable = new Label[map.Count + 1]; jumpTable[0] = il.DefineLabel(); foreach (var kvp in map) jumpTable[kvp.Value.TypeID] = il.DefineLabel(); il.Emit(OpCodes.Ldloc_S, idLocal); il.Emit(OpCodes.Switch, jumpTable); D(il, "eihx"); il.ThrowException(typeof(Exception)); /* null case */ il.MarkLabel(jumpTable[0]); il.Emit(OpCodes.Ret); /* cases for types */ foreach (var kvp in map) { var type = kvp.Key; var data = kvp.Value; il.MarkLabel(jumpTable[data.TypeID]); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type); if (data.WriterMethodInfo.IsGenericMethodDefinition) { Debug.Assert(type.IsGenericType); var genArgs = type.GetGenericArguments(); il.EmitCall(OpCodes.Call, data.WriterMethodInfo.MakeGenericMethod(genArgs), null); } else { il.EmitCall(OpCodes.Call, data.WriterMethodInfo, null); } il.Emit(OpCodes.Ret); } }