private void GenerateAddCallbackToInvokeList(WriterGenerationContext context, LocalBuilder valueLocal, Type actualType, Type attributeType) { var actionCtor = typeof(Action).GetConstructor(new[] { typeof(object), typeof(IntPtr) }); var addToListMethod = Helpers.GetMethodInfo <List <Action> >(x => x.Add(null)); var methodsWithAttribute = Helpers.GetMethodsWithAttribute(attributeType, actualType).ToList(); var count = methodsWithAttribute.Count; if (count > 0) { context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, List <Action> >(x => x.postSerializationHooks); } for (var i = 1; i < count; i++) { context.Generator.Emit(OpCodes.Dup); } foreach (var method in methodsWithAttribute) { // let's make the delegate if (method.IsStatic) { context.Generator.Emit(OpCodes.Ldnull); } else { context.Generator.PushLocalValueOntoStack(valueLocal); } context.Generator.Emit(OpCodes.Ldftn, method); context.Generator.Emit(OpCodes.Newobj, actionCtor); // and add it to invoke list context.Generator.Emit(OpCodes.Call, addToListMethod); } }
private void GenerateDynamicCode(WriterGenerationContext context, Type typeToGenerate) { var objectToSerialize = new Variable(1, typeToGenerate); // preserialization callbacks var exceptionBlockNeeded = Helpers.GetMethodsWithAttribute(typeof(PostSerializationAttribute), typeToGenerate).Any() || Helpers.GetMethodsWithAttribute(typeof(LatePostSerializationAttribute), typeToGenerate).Any(); if (exceptionBlockNeeded) { context.Generator.BeginExceptionBlock(); } GenerateInvokeCallback(context, objectToSerialize, typeToGenerate, typeof(PreSerializationAttribute)); if (!GenerateSpecialWrite(context, typeToGenerate, objectToSerialize, !treatCollectionAsUserObject)) { GenerateWriteFields(context, objectToSerialize, typeToGenerate); } if (exceptionBlockNeeded) { context.Generator.BeginFinallyBlock(); } if (exceptionBlockNeeded) { context.Generator.EndExceptionBlock(); } context.Generator.Emit(OpCodes.Ret); }
protected override bool InnerGenerate(WriterGenerationContext context) { var value = new Variable(1); WriteMethodGenerator.GenerateWriteDeferredReference(context, value, type); return(true); }
private static void GenerateWriteMultidimensionalArray(WriterGenerationContext context, Variable arrayLocal, Type actualType, int rank) { var elementType = actualType.GetElementType(); var indexLocals = new LocalBuilder[rank]; var lengthLocals = new LocalBuilder[rank]; for (var i = 0; i < rank; i++) { indexLocals[i] = context.Generator.DeclareLocal(typeof(int)); lengthLocals[i] = context.Generator.DeclareLocal(typeof(int)); context.Generator.PushIntegerOntoStack(0); context.Generator.StoreLocalValueFromStack(indexLocals[i]); context.Generator.PushVariableOntoStack(arrayLocal); context.Generator.PushIntegerOntoStack(i); context.Generator.Call <Array>(x => x.GetLength(0)); context.Generator.StoreLocalValueFromStack(lengthLocals[i]); } // writing elements var currentElementLocal = context.Generator.DeclareLocal(elementType); var currentElementVariable = new Variable(currentElementLocal); GenerateArrayWriteLoop(context, 0, rank, indexLocals, lengthLocals, arrayLocal, currentElementVariable, actualType, elementType); }
private static void GenerateWriteArray(WriterGenerationContext context, Variable arrayLocal, Type actualType) { var rank = actualType.GetArrayRank(); if (rank != 1) { GenerateWriteMultidimensionalArray(context, arrayLocal, actualType, rank); return; } var elementType = actualType.GetElementType(); var currentElementLocal = context.Generator.DeclareLocal(elementType); var lengthLocal = context.Generator.DeclareLocal(typeof(int)); var currentElementVariable = new Variable(currentElementLocal); context.Generator.PushVariableOntoStack(arrayLocal); context.Generator.Emit(OpCodes.Ldlen); context.Generator.StoreLocalValueFromStack(lengthLocal); GeneratorHelper.GenerateLoop(context, lengthLocal, c => { context.Generator.PushVariableOntoStack(arrayLocal); context.Generator.PushLocalValueOntoStack(c); context.Generator.Emit(OpCodes.Ldelem, elementType); context.Generator.StoreLocalValueFromStack(currentElementLocal); GenerateWriteField(context, currentElementVariable, elementType); }); }
internal static bool GenerateSpecialWrite(WriterGenerationContext context, Type actualType, Variable value, bool checkForCollections) { if (actualType.IsValueType) { // value type encountered here means it is in fact boxed value type // according to protocol it is written as it would be written inlined GenerateWriteValue(context, value, actualType); return(true); } if (actualType.IsArray) { GenerateWriteArray(context, value, actualType); return(true); } if (typeof(MulticastDelegate).IsAssignableFrom(actualType)) { GenerateWriteDelegate(context, value); return(true); } if (checkForCollections) { CollectionMetaToken collectionToken; if (CollectionMetaToken.TryGetCollectionMetaToken(actualType, out collectionToken)) { GenerateWriteEnumerable(context, value, collectionToken); return(true); } } return(false); }
private static void GenerateInvokeCallbacksAndExecute(WriterGenerationContext context, bool generatePreSerializationCallback, bool generatePostSerializationCallback, Variable valueLocal, Type type, Action <WriterGenerationContext> bodyBuilder) { if (generatePreSerializationCallback || generatePostSerializationCallback) { context.Generator.BeginExceptionBlock(); } if (generatePreSerializationCallback) { context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, Action <object> >(x => x.preSerializationCallback); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Call <Action <object> >(x => x.Invoke(null)); } bodyBuilder(context); if (generatePreSerializationCallback || generatePostSerializationCallback) { context.Generator.BeginFinallyBlock(); } if (generatePostSerializationCallback) { context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, Action <object> >(x => x.postSerializationCallback); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Call <Action <object> >(x => x.Invoke(null)); } if (generatePreSerializationCallback || generatePostSerializationCallback) { context.Generator.EndExceptionBlock(); } }
protected override bool InnerGenerate(WriterGenerationContext context) { Variable value; if (type.IsValueType) { var valueLocal = context.Generator.DeclareLocal(type); context.Generator.Emit(OpCodes.Ldarg_1); context.Generator.Emit(OpCodes.Unbox_Any, type); context.Generator.StoreLocalValueFromStack(valueLocal); value = new Variable(valueLocal); } else { value = new Variable(1); } var objectForSurrogatesIndex = objectsForSurrogates == null ? -1 : objectsForSurrogates.FindMatchingIndex(type); context.PushPrimitiveWriterOntoStack(); context.Generator.PushIntegerOntoStack(objectForSurrogatesIndex != -1 ? 1 : 0); context.Generator.Call <PrimitiveWriter>(x => x.Write(false)); if (objectForSurrogatesIndex != -1) { context.PushObjectWriterOntoStack(); context.Generator.Emit(OpCodes.Dup); context.Generator.PushFieldValueOntoStack <ObjectWriter, SwapList>(x => x.objectsForSurrogates); context.Generator.PushIntegerOntoStack(objectForSurrogatesIndex); context.Generator.Call <SwapList>(x => x.GetByIndex(0)); var delegateType = typeof(Func <,>).MakeGenericType(type, typeof(object)); context.Generator.Emit(OpCodes.Castclass, delegateType); context.Generator.Emit(OpCodes.Ldarg_1); context.Generator.Emit(OpCodes.Call, delegateType.GetMethod("Invoke")); // here should be a primitive writer on a stack context.Generator.Call <object>(x => x.GetType()); context.Generator.Call <ObjectWriter>(x => x.TouchAndWriteTypeId(typeof(void))); context.Generator.Emit(OpCodes.Pop); } if (WriteMethodGenerator.GenerateTryWriteObjectInline(context, generatePreSerializationCallback, generatePostSerializationCallback, value, type)) { context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, HashSet <int> >(x => x.objectsWrittenInline); context.Generator.Emit(OpCodes.Ldarg_2); // reference identifier context.Generator.Call <HashSet <int> >(x => x.Add(0)); context.Generator.Emit(OpCodes.Pop); } return(true); }
private static void GenerateWriteValue(WriterGenerationContext context, Variable valueLocal, Type formalType) { ObjectWriter.CheckLegality(formalType); if (formalType.IsEnum) { formalType = Enum.GetUnderlyingType(formalType); } var writeMethod = typeof(PrimitiveWriter).GetMethod("Write", new[] { formalType }); // if this method is null, then it is a non-primitive (i.e. custom) struct if (writeMethod != null) { context.PushPrimitiveWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Emit(OpCodes.Call, writeMethod); return; } var nullableUnderlyingType = Nullable.GetUnderlyingType(formalType); if (nullableUnderlyingType != null) { var hasValueLabel = context.Generator.DefineLabel(); var finishLabel = context.Generator.DefineLabel(); var underlyingValueLocal = context.Generator.DeclareLocal(nullableUnderlyingType); var underlyingVariable = new Variable(underlyingValueLocal); context.PushPrimitiveWriterOntoStack(); context.Generator.PushVariableAddressOntoStack(valueLocal); context.Generator.Emit(OpCodes.Call, formalType.GetProperty("HasValue").GetGetMethod()); context.Generator.Emit(OpCodes.Brtrue_S, hasValueLabel); context.Generator.PushIntegerOntoStack(0); context.Generator.Call <PrimitiveWriter>(x => x.Write(false)); context.Generator.Emit(OpCodes.Br_S, finishLabel); context.Generator.MarkLabel(hasValueLabel); context.Generator.PushIntegerOntoStack(1); context.Generator.Call <PrimitiveWriter>(x => x.Write(false)); context.Generator.PushVariableAddressOntoStack(valueLocal); context.Generator.Emit(OpCodes.Call, formalType.GetProperty("Value").GetGetMethod()); context.Generator.StoreLocalValueFromStack(underlyingValueLocal); GenerateWriteValue(context, underlyingVariable, nullableUnderlyingType); context.Generator.MarkLabel(finishLabel); return; } GenerateWriteFields(context, valueLocal, formalType); }
private void GenerateInvokeCallback(WriterGenerationContext context, Variable value, Type actualType, Type attributeType) { var methodsWithAttribute = Helpers.GetMethodsWithAttribute(attributeType, actualType); foreach (var method in methodsWithAttribute) { if (!method.IsStatic) { context.Generator.PushVariableOntoStack(value); } context.Generator.Emit(method.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, method); } }
private static void GenerateWriteDelegate(WriterGenerationContext context, Variable valueLocal) { var array = context.Generator.DeclareLocal(typeof(Delegate[])); var loopLength = context.Generator.DeclareLocal(typeof(int)); var element = context.Generator.DeclareLocal(typeof(Delegate)); var delegateTargetLocal = context.Generator.DeclareLocal(typeof(object)); var delegateTargetVariable = new Variable(delegateTargetLocal); context.PushPrimitiveWriterOntoStack(); context.PushObjectWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Call <ObjectWriter>(x => x.GetDelegatesWithNonTransientTargets(null)); context.Generator.Emit(OpCodes.Castclass, typeof(Delegate[])); context.Generator.Emit(OpCodes.Dup); context.Generator.StoreLocalValueFromStack(array); // array refrence should be on the top of stack here context.Generator.Emit(OpCodes.Ldlen); context.Generator.Emit(OpCodes.Dup); context.Generator.StoreLocalValueFromStack(loopLength); // primitive writer should be on the stack // array length should be on the stack context.Generator.Call <PrimitiveWriter>(x => x.Write(0)); GeneratorHelper.GenerateLoop(context, loopLength, c => { context.Generator.PushLocalValueOntoStack(array); context.Generator.PushLocalValueOntoStack(c); context.Generator.Emit(OpCodes.Ldelem, element.LocalType); context.Generator.Emit(OpCodes.Dup); context.Generator.StoreLocalValueFromStack(element); // element reference should be on the stack context.Generator.PushPropertyValueOntoStack <MulticastDelegate, object>(x => x.Target); context.Generator.StoreLocalValueFromStack(delegateTargetLocal); GenerateWriteDeferredReference(context, delegateTargetVariable, typeof(object)); context.PushObjectWriterOntoStack(); context.Generator.PushPropertyValueOntoStack <ObjectWriter, IdentifiedElementsDictionary <MethodDescriptor> >(x => x.Methods); context.Generator.PushLocalValueOntoStack(element); context.Generator.PushPropertyValueOntoStack <MulticastDelegate, MethodInfo>(x => x.Method); context.Generator.Emit(OpCodes.Newobj, Helpers.GetConstructorInfo <MethodDescriptor>(typeof(MethodInfo))); context.Generator.Call <IdentifiedElementsDictionary <MethodDescriptor> >(x => x.TouchAndWriteId(null)); context.Generator.Emit(OpCodes.Pop); }); }
internal static bool GenerateTryWriteObjectInline(WriterGenerationContext context, bool generatePreSerializationCallback, bool generatePostSerializationCallback, Variable valueLocal, Type actualType) { if (actualType.IsArray) { var rank = actualType.GetArrayRank(); // write rank context.PushPrimitiveWriterOntoStack(); context.Generator.PushIntegerOntoStack(rank); context.Generator.Call <PrimitiveWriter>(x => x.Write(0)); if (rank == 1) { // write length context.PushPrimitiveWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Emit(OpCodes.Castclass, actualType); context.Generator.Emit(OpCodes.Ldlen); context.Generator.Call <PrimitiveWriter>(x => x.Write(0)); } else { // write lengths in loop for (var i = 0; i < rank; i++) { context.PushPrimitiveWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.PushIntegerOntoStack(i); context.Generator.Call <Array>(x => x.GetLength(0)); context.Generator.Call <PrimitiveWriter>(x => x.Write(0)); } } return(false); } if (actualType == typeof(string)) { GenerateInvokeCallbacksAndExecute(context, generatePreSerializationCallback, generatePostSerializationCallback, valueLocal, actualType, c => { c.PushPrimitiveWriterOntoStack(); c.Generator.PushVariableOntoStack(valueLocal); c.Generator.Call <PrimitiveWriter>(x => x.Write((string)null)); }); return(true); } return(GenerateSpecialWrite(context, actualType, valueLocal, false)); }
protected override MethodInfo GenerateInner() { var dynamicMethod = new DynamicMethod(name, returnType, parameterTypes, typeof(Serializer), true); var generator = dynamicMethod.GetILGenerator(); var context = new WriterGenerationContext(generator, disableStamping, treatCollectionAsUserObject, objectWriterArgument); if (!InnerGenerate(context)) { return(null); } context.Generator.Emit(OpCodes.Ret); #if DEBUG_FORMAT GeneratorHelper.DumpToLibrary <T>(context, x => InnerGenerate((WriterGenerationContext)x), name); #endif return(dynamicMethod); }
private static void GenerateWriteField(WriterGenerationContext context, Variable valueLocal, Type formalType) { switch (Helpers.GetSerializationType(formalType)) { case SerializationType.Transient: // just omit it return; case SerializationType.Value: GenerateWriteValue(context, valueLocal, formalType); break; case SerializationType.Reference: GenerateWriteDeferredReference(context, valueLocal, formalType); break; } }
internal static void GenerateWriteDeferredReference(WriterGenerationContext context, Variable valueLocal, Type formalType) { var finish = context.Generator.DefineLabel(); var isNotNull = context.Generator.DefineLabel(); var isNotTransient = context.Generator.DefineLabel(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Emit(OpCodes.Brtrue_S, isNotNull); context.PushNullReferenceOnStack(); context.Generator.Emit(OpCodes.Br, finish); context.Generator.MarkLabel(isNotNull); var formalTypeIsActualType = (formalType.Attributes & TypeAttributes.Sealed) != 0; if (!formalTypeIsActualType) { context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Call(() => Helpers.IsTransient((object)null)); context.Generator.Emit(OpCodes.Brfalse_S, isNotTransient); context.PushNullReferenceOnStack(); context.Generator.Emit(OpCodes.Br, finish); context.Generator.MarkLabel(isNotTransient); context.PushObjectWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Call <ObjectWriter>(x => x.WriteDeferredReference(null)); } else { if (Helpers.IsTransient(formalType)) { context.PushNullReferenceOnStack(); } else { context.PushObjectWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Call <ObjectWriter>(x => x.WriteDeferredReference(null)); } } context.Generator.MarkLabel(finish); }
private static void GenerateWriteFields(WriterGenerationContext context, Variable value, Type actualType) { var fields = StampHelpers.GetFieldsInSerializationOrder(actualType); foreach (var field in fields) { var fieldValueLocal = context.Generator.DeclareLocal(field.FieldType); var fieldValue = new Variable(fieldValueLocal); context.Generator.PushVariableOntoStack(value); if (!actualType.IsValueType) { context.Generator.Emit(OpCodes.Castclass, actualType); } context.Generator.Emit(OpCodes.Ldfld, field); context.Generator.StoreLocalValueFromStack(fieldValueLocal); GenerateWriteField(context, fieldValue, field.FieldType); } }
private static void GenerateArrayWriteLoop(WriterGenerationContext context, int currentDimension, int rank, LocalBuilder[] indexLocals, LocalBuilder[] lengthLocals, Variable arrayLocal, Variable currentElementVariable, Type arrayType, Type elementType) { GeneratorHelper.GenerateLoop(context, lengthLocals[currentDimension], indexLocals[currentDimension], () => { if (currentDimension == rank - 1) { context.Generator.PushVariableOntoStack(arrayLocal); for (var i = 0; i < rank; i++) { context.Generator.PushLocalValueOntoStack(indexLocals[i]); } // jeśli to nie zadziała to użyć: context.Generator.Emit(OpCodes.Call, arrayType.GetMethod("Get")); context.Generator.StoreVariableValueFromStack(currentElementVariable); GenerateWriteField(context, currentElementVariable, elementType); } else { GenerateArrayWriteLoop(context, currentDimension + 1, rank, indexLocals, lengthLocals, arrayLocal, currentElementVariable, arrayType, elementType); } }); }
private static void GenerateWriteEnumerable(WriterGenerationContext context, Variable valueLocal, CollectionMetaToken token) { var genericTypes = new[] { token.FormalElementType }; var enumerableType = token.IsGeneric ? typeof(IEnumerable <>).MakeGenericType(genericTypes) : typeof(IEnumerable); var enumeratorType = token.IsGeneric ? typeof(IEnumerator <>).MakeGenericType(genericTypes) : typeof(IEnumerator); var iteratorLocal = context.Generator.DeclareLocal(enumeratorType); var currentElementLocal = context.Generator.DeclareLocal(token.FormalElementType); var elementVariable = new Variable(currentElementLocal); var loopBegin = context.Generator.DefineLabel(); var finish = context.Generator.DefineLabel(); context.PushPrimitiveWriterOntoStack(); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Emit(token.CountMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, token.CountMethod); context.Generator.Call <PrimitiveWriter>(x => x.Write(0)); var getEnumeratorMethod = enumerableType.GetMethod("GetEnumerator"); context.Generator.PushVariableOntoStack(valueLocal); context.Generator.Emit(OpCodes.Callvirt, getEnumeratorMethod); context.Generator.StoreLocalValueFromStack(iteratorLocal); context.Generator.MarkLabel(loopBegin); context.Generator.PushLocalValueOntoStack(iteratorLocal); context.Generator.Callvirt <IEnumerator>(x => x.MoveNext()); context.Generator.Emit(OpCodes.Brfalse, finish); context.Generator.PushLocalValueOntoStack(iteratorLocal); context.Generator.Emit(OpCodes.Callvirt, enumeratorType.GetProperty("Current").GetGetMethod()); context.Generator.StoreLocalValueFromStack(currentElementLocal); GenerateWriteField(context, elementVariable, token.FormalElementType); context.Generator.Emit(OpCodes.Br, loopBegin); context.Generator.MarkLabel(finish); }
protected override bool InnerGenerate(WriterGenerationContext context) { var surrogateId = surrogatesForObjects.FindMatchingIndex(type); if (surrogateId == -1) { return(false); } var objVariable = new Variable(1); context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, SwapList>(x => x.surrogatesForObjects); context.Generator.PushIntegerOntoStack(surrogateId); context.Generator.Call <SwapList>(x => x.GetByIndex(0)); // call surrogate factory to obtain surrogate object var delegateType = typeof(Func <,>).MakeGenericType(type, typeof(object)); context.Generator.Emit(OpCodes.Castclass, delegateType); context.Generator.PushVariableOntoStack(objVariable); if (type.IsValueType) { context.Generator.Emit(OpCodes.Unbox_Any, type); } context.Generator.Emit(OpCodes.Call, delegateType.GetMethod("Invoke")); context.Generator.StoreVariableValueFromStack(objVariable); context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, ObjectIdentifier>(x => x.identifier); context.Generator.PushVariableOntoStack(objVariable); // object reference context.Generator.Emit(OpCodes.Ldarg_2); // reference id context.Generator.Call <ObjectIdentifier>(x => x.SetIdentifierForObject(null, 0)); context.Generator.PushVariableOntoStack(objVariable); return(true); }
protected override MethodInfo GenerateInner() { DynamicMethod dynamicMethod = null; if (!type.IsArray) { dynamicMethod = new DynamicMethod(string.Format("Write_{0}", type.Name), returnType, parameterTypes, type, true); } else { var methodNo = Interlocked.Increment(ref WriteArrayMethodCounter); dynamicMethod = new DynamicMethod(string.Format("WriteArray{0}_{1}", methodNo, type.Name), returnType, parameterTypes, true); } var generator = dynamicMethod.GetILGenerator(); var context = new WriterGenerationContext(generator, false, treatCollectionAsUserObject, OpCodes.Ldarg_0); #if DEBUG_FORMAT GeneratorHelper.DumpToLibrary <WriteMethodDelegate>(context, c => GenerateDynamicCode((WriterGenerationContext)c, type), type.Name); #endif GenerateDynamicCode(context, type); return(dynamicMethod); }
protected override bool InnerGenerate(WriterGenerationContext context) { var result = false; var methods = Helpers.GetMethodsWithAttribute(typeof(PostSerializationAttribute), type).ToArray(); foreach (var method in methods) { if (!method.IsStatic) { context.Generator.Emit(OpCodes.Ldarg_1); context.Generator.Emit(OpCodes.Castclass, method.ReflectedType); } if (method.IsVirtual) { context.Generator.Emit(OpCodes.Callvirt, method); } else { context.Generator.Emit(OpCodes.Call, method); } result = true; } methods = Helpers.GetMethodsWithAttribute(typeof(LatePostSerializationAttribute), type).ToArray(); foreach (var method in methods) { context.PushObjectWriterOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectWriter, List <Action> >(x => x.postSerializationHooks); context.Generator.PushTypeOntoStack(typeof(Action)); if (method.IsStatic) { context.Generator.Emit(OpCodes.Ldnull); } else { context.Generator.Emit(OpCodes.Ldarg_1); context.Generator.Emit(OpCodes.Castclass, method.ReflectedType); } context.Generator.Emit(OpCodes.Ldtoken, method); if (method.DeclaringType.IsGenericType) { context.Generator.Emit(OpCodes.Ldtoken, method.DeclaringType); context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <object, MethodBase>(x => MethodBase.GetMethodFromHandle(new RuntimeMethodHandle(), new RuntimeTypeHandle()))); } else { context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <object, MethodBase>(x => MethodBase.GetMethodFromHandle(new RuntimeMethodHandle()))); } context.Generator.Emit(OpCodes.Castclass, typeof(MethodInfo)); context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <object, Delegate>(x => Delegate.CreateDelegate(null, null, method))); context.Generator.Emit(OpCodes.Castclass, typeof(Action)); context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <List <Action> >(x => x.Add(null))); result = true; } return(result); }
protected abstract bool InnerGenerate(WriterGenerationContext context);