private void Invoke(TracingILGenerator il) { ConstructorInfo asConsctructor; if ((asConsctructor = this._method as ConstructorInfo) != null) { if (asConsctructor.DeclaringType.GetIsValueType()) { this._target.LoadValue(il, true); foreach (var argument in this._arguments) { argument.LoadValue(il, false); } il.EmitCallConstructor(asConsctructor); // For compatibility to ref type. this._target.LoadValue(il, false); } else { foreach (var argument in this._arguments) { argument.LoadValue(il, false); } il.EmitNewobj(asConsctructor); } } else { // method if (!this._method.IsStatic) { this._target.LoadValue(il, this._target.ContextType.GetIsValueType()); } foreach (var argument in this._arguments) { argument.LoadValue(il, false); } if (this._method.IsStatic || this._target.ContextType.GetIsValueType()) { il.EmitCall(this._method as MethodInfo); } else { il.EmitCallvirt(this._method as MethodInfo); } } }
/// <summary> /// Emits helper function to avoid lexical closure emitting. /// </summary> /// <param name="il"><see cref="TracingILGenerator"/>.</param> /// <param name="targetOperation"><see cref="MethodInfo"/> of the method to be invoked.</param> /// <param name="tupleTypes">The array of <see cref="Type"/> of nested tuples. The outermost is the first, innermost is the last.</param> /// <param name="itemTypes">The array of <see cref="Type"/> of flatten tuple items.</param> private static void EmitPrivateInvoke(TracingILGenerator il, MethodInfo targetOperation, IList <Type> tupleTypes, Type[] itemTypes) { /* * private void/T PrivateInvoke( object state ) * { * T result; * Dispatcher.BeginOperation(); * try * { * var tuple = state as Tuple<...>; * result = * tuple.Item1.Target( * tuple.Item2, * : * tuple.Rest.Rest....ItemN * ); * } * catch( TheradAbortException ) * { * Dispatcher.HandleThreadAbortException( ex ); * } * finally * { * Dispatcher.EndOperation(); * } * * return result; * } */ var tuple = il.DeclareLocal(tupleTypes.First(), "tuple"); var result = targetOperation.ReturnType == typeof(void) ? null : il.DeclareLocal(targetOperation.ReturnType, "result"); il.EmitAnyLdarg(0); il.EmitCall(_dispatcherBeginOperationMethod); il.BeginExceptionBlock(); il.EmitAnyLdarg(1); il.EmitIsinst(tupleTypes.First()); il.EmitAnyStloc(tuple); int depth = -1; for (int i = 0; i < itemTypes.Length; i++) { if (i % 7 == 0) { depth++; } il.EmitAnyLdloc(tuple); for (int j = 0; j < depth; j++) { // .TRest.TRest ... var rest = tupleTypes[j].GetProperty("Rest"); il.EmitGetProperty(rest); } var itemn = tupleTypes[depth].GetProperty("Item" + ((i % 7) + 1)); il.EmitGetProperty(itemn); } il.EmitAnyCall(targetOperation); if (targetOperation.ReturnType != typeof(void)) { il.EmitAnyStloc(result); } il.BeginCatchBlock(typeof(ThreadAbortException)); var ex = il.DeclareLocal(typeof(ThreadAbortException), "ex"); il.EmitAnyStloc(ex); il.EmitAnyLdarg(0); il.EmitAnyLdloc(ex); il.EmitCall(_dispatcherHandleThreadAbortExceptionMethod); il.BeginFinallyBlock(); il.EmitAnyLdarg(0); il.EmitCall(_dispatcherEndOperationMethod); il.EndExceptionBlock(); if (targetOperation.ReturnType != typeof(void)) { il.EmitAnyLdloc(result); } il.EmitRet(); }
private void Invoke(TracingILGenerator il) { ConstructorInfo asConsctructor; if ((asConsctructor = this._method as ConstructorInfo) != null) { if (asConsctructor.DeclaringType.GetIsValueType()) { this._target.LoadValue(il, true); foreach (var argument in this._arguments) { argument.LoadValue(il, false); } il.EmitCallConstructor(asConsctructor); // For compatibility to ref type. this._target.LoadValue(il, false); } else { foreach (var argument in this._arguments) { argument.LoadValue(il, false); } il.EmitNewobj(asConsctructor); } } else { // method if (!this._method.IsStatic) { this._target.LoadValue(il, this._target.ContextType.ResolveRuntimeType().GetIsValueType()); } foreach (var argument in this._arguments) { argument.LoadValue(il, false); } if (this._method.IsStatic || this._target.ContextType.ResolveRuntimeType().GetIsValueType()) { il.EmitCall(this._method as MethodInfo); } else if (this._interface != null) { // Explicit interface impl il.EmitCallvirt( this._interface.GetRuntimeMethod( this._method.Name.Substring(this._method.Name.LastIndexOf('.') + 1), this._method.GetParameters().Select(p => p.ParameterType).ToArray() ) ); } else { il.EmitCallvirt(this._method as MethodInfo); } } }
public override Func <SerializationContext, PolymorphismSchema, MessagePackSerializer <T> > CreateConstructor <T>() { if (!this._typeBuilder.IsCreated()) { /* * .ctor() : this(null) * {} */ /* * .ctor( SerializationContext context ) * : base( ( context ?? SerializationContext.Default ).CompabilityOptions.PackerCompatibilityOptions ) * { * this._serializer0 = context.GetSerializer<T0>(); * this._serializer1 = context.GetSerializer<T1>(); * this._serializer2 = context.GetSerializer<T2>(); * : * } */ // default { var il = this._defaultConstructorBuilder.GetILGenerator(); // : this(null) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Call, this._contextConstructorBuilder); il.Emit(OpCodes.Ret); } // context { var il = new TracingILGenerator(this._contextConstructorBuilder, TextWriter.Null, this._isDebuggable); // : base() il.EmitLdarg_0(); il.EmitLdarg_1(); #if DEBUG Contract.Assert(this._typeBuilder.BaseType != null, "this._typeBuilder.BaseType != null"); #endif if (this._traits.CollectionType == CollectionKind.NotCollection) { il.EmitCallConstructor( this._typeBuilder.BaseType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, ConstructorParameterTypes, null ) ); } else { il.EmitCall(this._restoreSchemaMethodBuilder); il.EmitCallConstructor( this._typeBuilder.BaseType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, CollectionConstructorParameterTypes, null ) ); } // this._serializerN = context.GetSerializer<T>(); foreach (var entry in this._serializers) { var targetType = Type.GetTypeFromHandle(entry.Key.TypeHandle); MethodInfo getMethod = Metadata._SerializationContext.GetSerializer1_Parameter_Method.MakeGenericMethod(targetType); il.EmitLdarg_0(); il.EmitLdarg_1(); if (targetType.GetIsEnum()) { il.EmitLdarg_1(); il.EmitTypeOf(targetType); il.EmitAnyLdc_I4(( int )entry.Key.EnumSerializationMethod); il.EmitCall(Metadata._EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethodMethod); il.EmitBox(typeof(EnumSerializationMethod)); } else if (DateTimeMessagePackSerializerHelpers.IsDateTime(targetType)) { il.EmitLdarg_1(); il.EmitAnyLdc_I4(( int )entry.Key.DateTimeConversionMethod); il.EmitCall(Metadata._DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethodMethod); il.EmitBox(typeof(DateTimeConversionMethod)); } else { if (entry.Key.PolymorphismSchema == null) { il.EmitLdnull(); } else { entry.Value.SchemaProvider(il); } } il.EmitCallvirt(getMethod); il.EmitStfld(entry.Value.Field); } foreach (var entry in this._fieldInfos) { il.EmitLdarg_0(); il.EmitLdtoken(FieldInfo.GetFieldFromHandle(entry.Key)); il.EmitCall(Metadata._FieldInfo.GetFieldFromHandle); il.EmitStfld(entry.Value); } foreach (var entry in this._methodBases) { il.EmitLdarg_0(); il.EmitLdtoken(MethodBase.GetMethodFromHandle(entry.Key)); il.EmitCall(Metadata._MethodBase.GetMethodFromHandle); il.EmitStfld(entry.Value); } il.EmitRet(); } } var ctor = this._typeBuilder.CreateType().GetConstructor(ConstructorParameterTypes); var contextParameter = Expression.Parameter(typeof(SerializationContext), "context"); var schemaParameter = Expression.Parameter(typeof(PolymorphismSchema), "schema"); #if DEBUG Contract.Assert(ctor != null, "ctor != null"); #endif return (Expression.Lambda <Func <SerializationContext, PolymorphismSchema, MessagePackSerializer <T> > >( Expression.New( ctor, contextParameter ), contextParameter, schemaParameter ).Compile()); }
private void CreateContextfulObjectConstructor( AssemblyBuilderEmittingContext context, Type baseType, TracingILGenerator il, Func <ILConstruct> packActionListInitializerProvider, Func <ILConstruct> packActionTableInitializerProvider, Func <ILConstruct> unpackActionListInitializerProvider, Func <ILConstruct> unpackActionTableInitializerProvider, #if FEATURE_TAP Func <ILConstruct> packAsyncActionListInitializerProvider, Func <ILConstruct> packAsyncActionTableInitializerProvider, Func <ILConstruct> unpackAsyncActionListInitializerProvider, Func <ILConstruct> unpackAsyncActionTableInitializerProvider, #endif // FEATURE_TAP Func <ILConstruct> memberNamesInitializerProvider, Func <ILConstruct> unpackToInitializerProvider ) { /* * .ctor( SerializationContext context ) * : base( ( context ?? SerializationContext.Default ).CompabilityOptions.PackerCompatibilityOptions ) * { * this._serializer0 = context.GetSerializer<T0>(); * this._serializer1 = context.GetSerializer<T1>(); * this._serializer2 = context.GetSerializer<T2>(); * : * } */ // : base() il.EmitLdarg_0(); il.EmitLdarg_1(); if (this._specification.TargetCollectionTraits.CollectionType == CollectionKind.NotCollection) { il.EmitCallConstructor( baseType.GetRuntimeConstructor(ConstructorParameterTypes) ); } else { il.EmitCall(this._methodTable[MethodName.RestoreSchema]); il.EmitCallConstructor( baseType.GetRuntimeConstructor(CollectionConstructorParameterTypes) ); } // this._serializerN = context.GetSerializer<T>(); foreach (var entry in this._serializers) { var targetType = Type.GetTypeFromHandle(entry.Key.TypeHandle); MethodInfo getMethod = Metadata._SerializationContext.GetSerializer1_Parameter_Method.MakeGenericMethod(targetType); il.EmitLdarg_0(); il.EmitLdarg_1(); if (targetType.GetIsEnum()) { il.EmitLdarg_1(); il.EmitTypeOf(targetType); il.EmitAnyLdc_I4(( int )entry.Key.EnumSerializationMethod); il.EmitCall(Metadata._EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethodMethod); il.EmitBox(typeof(EnumSerializationMethod)); } else if (DateTimeMessagePackSerializerHelpers.IsDateTime(targetType)) { il.EmitLdarg_1(); il.EmitAnyLdc_I4(( int )entry.Key.DateTimeConversionMethod); il.EmitCall(Metadata._DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethodMethod); il.EmitBox(typeof(DateTimeConversionMethod)); } else { if (entry.Key.PolymorphismSchema == null) { il.EmitLdnull(); } else { entry.Value.SchemaProvider(il); } } il.EmitCallvirt(getMethod); il.EmitStfld(entry.Value.Field); } foreach (var entry in this._cachedFieldInfos) { il.EmitLdarg_0(); il.EmitLdtoken(entry.Value.Target); il.EmitLdtoken(entry.Value.Target.DeclaringType); il.EmitCall(Metadata._FieldInfo.GetFieldFromHandle); il.EmitStfld(entry.Value.StorageFieldBuilder); } foreach (var entry in this._cachedMethodBases) { il.EmitLdarg_0(); il.EmitLdtoken(entry.Value.Target); il.EmitLdtoken(entry.Value.Target.DeclaringType); il.EmitCall(Metadata._MethodBase.GetMethodFromHandle); il.EmitStfld(entry.Value.StorageFieldBuilder); } if (packActionListInitializerProvider != null) { packActionListInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (packAsyncActionListInitializerProvider != null) { packAsyncActionListInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (packActionTableInitializerProvider != null) { packActionTableInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (packAsyncActionTableInitializerProvider != null) { packAsyncActionTableInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (unpackActionListInitializerProvider != null) { unpackActionListInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (unpackAsyncActionListInitializerProvider != null) { unpackAsyncActionListInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (unpackActionTableInitializerProvider != null) { unpackActionTableInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (unpackAsyncActionTableInitializerProvider != null) { unpackAsyncActionTableInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (memberNamesInitializerProvider != null) { memberNamesInitializerProvider().Evaluate(il); } if (unpackToInitializerProvider != null) { unpackToInitializerProvider().Evaluate(il); } foreach (var cachedDelegateInfo in context.GetCachedDelegateInfos()) { // this for stfld il.EmitLdargThis(); var delegateType = cachedDelegateInfo.BackingField.FieldType.ResolveRuntimeType(); // Declare backing field now. var field = context.GetDeclaredField(cachedDelegateInfo.BackingField.FieldName).ResolveRuntimeField(); if (cachedDelegateInfo.IsThisInstance) { il.EmitLdargThis(); } else { il.EmitLdnull(); } // OK this should not be ldvirtftn because target is private or static. il.EmitLdftn(cachedDelegateInfo.TargetMethod.ResolveRuntimeMethod()); // call extern .ctor(Object, void*) il.EmitNewobj(delegateType.GetConstructors().Single()); il.EmitStfld(field); } il.EmitRet(); }
protected sealed override MessagePackSerializer <TObject> CreateSerializer(SerializingMember[] entries) { MessagePackSerializer <TObject> serializer; using (SerializerEmitter emitter = this._generatorManager.CreateEmitter(typeof(TObject), this._emitterFlavor)) { try { TracingILGenerator packToMethodILGenerator = emitter.GetPackToMethodILGenerator(); try { if (typeof(IPackable).IsAssignableFrom(typeof(TObject))) { if (typeof(TObject).IsValueType) { packToMethodILGenerator.EmitAnyLdarga(2); } else { packToMethodILGenerator.EmitAnyLdarg(2); } packToMethodILGenerator.EmitAnyLdarg(1); packToMethodILGenerator.EmitLdnull(); packToMethodILGenerator.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single <MethodInfo>()); packToMethodILGenerator.EmitRet(); } else { this.EmitPackMembers(emitter, packToMethodILGenerator, entries); } } finally { packToMethodILGenerator.FlushTrace(); } TracingILGenerator unpackFromMethodILGenerator = emitter.GetUnpackFromMethodILGenerator(); try { LocalBuilder target = unpackFromMethodILGenerator.DeclareLocal(typeof(TObject), "result"); Emittion.EmitConstruction(unpackFromMethodILGenerator, target, null); if (typeof(IUnpackable).IsAssignableFrom(typeof(TObject))) { if (typeof(TObject).GetIsValueType()) { unpackFromMethodILGenerator.EmitAnyLdloca(target); } else { unpackFromMethodILGenerator.EmitAnyLdloc(target); } unpackFromMethodILGenerator.EmitAnyLdarg(1); unpackFromMethodILGenerator.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IUnpackable)).TargetMethods.Single <MethodInfo>()); } else { EmittingSerializerBuilder <TObject> .EmitUnpackMembers(emitter, unpackFromMethodILGenerator, entries, target); } unpackFromMethodILGenerator.EmitAnyLdloc(target); unpackFromMethodILGenerator.EmitRet(); } finally { unpackFromMethodILGenerator.FlushTrace(); } serializer = emitter.CreateInstance <TObject>(base.Context); } finally { emitter.FlushTrace(); } } return(serializer); }