summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2017-02-10 20:35:12 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2017-02-10 20:35:12 +0900
commit4b11dc566a5bbfa1378d6266525c281b028abcc8 (patch)
treeb48831a898906734f8884d08b6e18f1144ee2b82 /src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
parentdb20f3f1bb8595633a7e16c8900fd401a453a6b5 (diff)
downloadcoreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.gz
coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.bz2
coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.zip
Imported Upstream version 1.0.0.9910upstream/1.0.0.9910
Diffstat (limited to 'src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs')
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs774
1 files changed, 0 insertions, 774 deletions
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
deleted file mode 100644
index 160a0ab491..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
+++ /dev/null
@@ -1,774 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.InteropServices.TCEAdapterGen {
- using System.Runtime.InteropServices.ComTypes;
- using ubyte = System.Byte;
- using System;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Collections;
- using System.Threading;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- internal class EventProviderWriter
- {
- private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
-
- private readonly Type[] MonitorEnterParamTypes = new Type[] { typeof(Object), Type.GetType("System.Boolean&") };
-
- public EventProviderWriter( ModuleBuilder OutputModule, String strDestTypeName, Type EventItfType, Type SrcItfType, Type SinkHelperType )
- {
- m_OutputModule = OutputModule;
- m_strDestTypeName = strDestTypeName;
- m_EventItfType = EventItfType;
- m_SrcItfType = SrcItfType;
- m_SinkHelperType = SinkHelperType;
- }
-
- public Type Perform()
- {
- // Create the event provider class.
- TypeBuilder OutputTypeBuilder = m_OutputModule.DefineType(
- m_strDestTypeName,
- TypeAttributes.Sealed | TypeAttributes.NotPublic,
- typeof(Object),
- new Type[]{m_EventItfType, typeof(IDisposable)}
- );
-
- // Create the event source field.
- FieldBuilder fbCPC = OutputTypeBuilder.DefineField(
- "m_ConnectionPointContainer",
- typeof(IConnectionPointContainer),
- FieldAttributes.Private
- );
-
- // Create array of event sink helpers.
- FieldBuilder fbSinkHelper = OutputTypeBuilder.DefineField(
- "m_aEventSinkHelpers",
- typeof(ArrayList),
- FieldAttributes.Private
- );
-
- // Define the connection point field.
- FieldBuilder fbEventCP = OutputTypeBuilder.DefineField(
- "m_ConnectionPoint",
- typeof(IConnectionPoint),
- FieldAttributes.Private
- );
-
- // Define the InitXXX method.
- MethodBuilder InitSrcItfMethodBuilder =
- DefineInitSrcItfMethod( OutputTypeBuilder, m_SrcItfType, fbSinkHelper, fbEventCP, fbCPC );
-
- // Process all the methods in the event interface.
- MethodInfo[] aMethods = TCEAdapterGenerator.GetNonPropertyMethods(m_SrcItfType);
- for ( int cMethods = 0; cMethods < aMethods.Length; cMethods++ )
- {
- if ( m_SrcItfType == aMethods[cMethods].DeclaringType )
- {
- // Define the add_XXX method.
- MethodBuilder AddEventMethodBuilder = DefineAddEventMethod(
- OutputTypeBuilder, aMethods[cMethods], m_SinkHelperType, fbSinkHelper, fbEventCP, InitSrcItfMethodBuilder );
-
- // Define the remove_XXX method.
- MethodBuilder RemoveEventMethodBuilder = DefineRemoveEventMethod(
- OutputTypeBuilder, aMethods[cMethods], m_SinkHelperType, fbSinkHelper, fbEventCP );
- }
- }
-
- // Define the constructor.
- DefineConstructor( OutputTypeBuilder, fbCPC );
-
- // Define the finalize method.
- MethodBuilder FinalizeMethod = DefineFinalizeMethod( OutputTypeBuilder, m_SinkHelperType, fbSinkHelper, fbEventCP );
-
- // Define the Dispose method.
- DefineDisposeMethod( OutputTypeBuilder, FinalizeMethod);
-
- return OutputTypeBuilder.CreateType();
- }
-
- private MethodBuilder DefineAddEventMethod( TypeBuilder OutputTypeBuilder, MethodInfo SrcItfMethod, Type SinkHelperClass, FieldBuilder fbSinkHelperArray, FieldBuilder fbEventCP, MethodBuilder mbInitSrcItf )
- {
- Type[] aParamTypes;
-
- // Find the delegate on the event sink helper.
- FieldInfo DelegateField = SinkHelperClass.GetField( "m_" + SrcItfMethod.Name + "Delegate" );
- Debug.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
-
- // Find the cookie on the event sink helper.
- FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
- Debug.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
-
- // Retrieve the sink helper's constructor.
- ConstructorInfo SinkHelperCons = SinkHelperClass.GetConstructor(EventProviderWriter.DefaultLookup | BindingFlags.NonPublic, null, Array.Empty<Type>(), null );
- Debug.Assert(SinkHelperCons != null, "Unable to find the constructor for the sink helper");
-
- // Retrieve the IConnectionPoint.Advise method.
- MethodInfo CPAdviseMethod = typeof(IConnectionPoint).GetMethod( "Advise" );
- Debug.Assert(CPAdviseMethod != null, "Unable to find the method ConnectionPoint.Advise");
-
- // Retrieve the ArrayList.Add method.
- aParamTypes = new Type[1];
- aParamTypes[0] = typeof(Object);
- MethodInfo ArrayListAddMethod = typeof(ArrayList).GetMethod( "Add", aParamTypes, null );
- Debug.Assert(ArrayListAddMethod != null, "Unable to find the method ArrayList.Add");
-
- // Retrieve the Monitor.Enter() method.
- MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod( "Enter", MonitorEnterParamTypes, null );
- Debug.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
-
- // Retrieve the Monitor.Exit() method.
- aParamTypes[0] = typeof(Object);
- MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
- Debug.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
-
- // Define the add_XXX method.
- Type[] parameterTypes;
- parameterTypes = new Type[1];
- parameterTypes[0] = DelegateField.FieldType;
- MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
- "add_" + SrcItfMethod.Name,
- MethodAttributes.Public | MethodAttributes.Virtual,
- null,
- parameterTypes );
-
- ILGenerator il = Meth.GetILGenerator();
-
- // Define a label for the m_IFooEventsCP comparision.
- Label EventCPNonNullLabel = il.DefineLabel();
-
- // Declare the local variables.
- LocalBuilder ltSinkHelper = il.DeclareLocal( SinkHelperClass );
- LocalBuilder ltCookie = il.DeclareLocal( typeof(Int32) );
- LocalBuilder ltLockTaken = il.DeclareLocal( typeof(bool) );
-
- // Generate the following code:
- // try {
- il.BeginExceptionBlock();
-
- // Generate the following code:
- // Monitor.Enter(this, ref lockTaken);
- il.Emit(OpCodes.Ldarg, (short)0);
- il.Emit(OpCodes.Ldloca_S, ltLockTaken);
- il.Emit(OpCodes.Call, MonitorEnterMethod);
-
- // Generate the following code:
- // if ( m_IFooEventsCP != null ) goto EventCPNonNullLabel;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Brtrue, EventCPNonNullLabel );
-
- // Generate the following code:
- // InitIFooEvents();
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Call, mbInitSrcItf );
-
- // Mark this as label to jump to if the CP is not null.
- il.MarkLabel( EventCPNonNullLabel );
-
- // Generate the following code:
- // IFooEvents_SinkHelper SinkHelper = new IFooEvents_SinkHelper;
- il.Emit( OpCodes.Newobj, SinkHelperCons );
- il.Emit( OpCodes.Stloc, ltSinkHelper );
-
- // Generate the following code:
- // dwCookie = 0;
- il.Emit( OpCodes.Ldc_I4_0 );
- il.Emit( OpCodes.Stloc, ltCookie );
-
- // Generate the following code:
- // m_IFooEventsCP.Advise( SinkHelper, dwCookie );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Ldloc, ltSinkHelper );
- il.Emit( OpCodes.Castclass, typeof(Object) );
- il.Emit( OpCodes.Ldloca, ltCookie );
- il.Emit( OpCodes.Callvirt, CPAdviseMethod );
-
- // Generate the following code:
- // SinkHelper.m_dwCookie = dwCookie;
- il.Emit( OpCodes.Ldloc, ltSinkHelper );
- il.Emit( OpCodes.Ldloc, ltCookie );
- il.Emit( OpCodes.Stfld, CookieField );
-
- // Generate the following code:
- // SinkHelper.m_FooDelegate = d;
- il.Emit( OpCodes.Ldloc, ltSinkHelper );
- il.Emit( OpCodes.Ldarg, (short)1 );
- il.Emit( OpCodes.Stfld, DelegateField );
-
- // Generate the following code:
- // m_aIFooEventsHelpers.Add( SinkHelper );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
- il.Emit( OpCodes.Ldloc, ltSinkHelper );
- il.Emit( OpCodes.Castclass, typeof(Object) );
- il.Emit( OpCodes.Callvirt, ArrayListAddMethod );
- il.Emit( OpCodes.Pop );
-
- // Generate the following code:
- // } finally {
- il.BeginFinallyBlock();
-
- // Generate the following code:
- // if (lockTaken)
- // Monitor.Exit(this);
- Label skipExit = il.DefineLabel();
- il.Emit( OpCodes.Ldloc, ltLockTaken );
- il.Emit( OpCodes.Brfalse_S, skipExit );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Call, MonitorExitMethod );
- il.MarkLabel(skipExit);
-
- // Generate the following code:
- // }
- il.EndExceptionBlock();
-
- // Generate the return opcode.
- il.Emit( OpCodes.Ret );
-
- return Meth;
- }
-
- private MethodBuilder DefineRemoveEventMethod( TypeBuilder OutputTypeBuilder, MethodInfo SrcItfMethod, Type SinkHelperClass, FieldBuilder fbSinkHelperArray, FieldBuilder fbEventCP )
- {
- Type[] aParamTypes;
-
- // Find the delegate on the event sink helper.
- FieldInfo DelegateField = SinkHelperClass.GetField( "m_" + SrcItfMethod.Name + "Delegate" );
- Debug.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
-
- // Find the cookie on the event sink helper.
- FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
- Debug.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
-
- // Retrieve the ArrayList.RemoveAt method.
- aParamTypes = new Type[1];
- aParamTypes[0] = typeof(Int32);
- MethodInfo ArrayListRemoveMethod = typeof(ArrayList).GetMethod( "RemoveAt", aParamTypes, null );
- Debug.Assert(ArrayListRemoveMethod != null, "Unable to find the method ArrayList.RemoveAt()");
-
- // Retrieve the ArrayList.Item property get method.
- PropertyInfo ArrayListItemProperty = typeof(ArrayList).GetProperty( "Item" );
- Debug.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
- MethodInfo ArrayListItemGetMethod = ArrayListItemProperty.GetGetMethod();
- Debug.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
-
- // Retrieve the ArrayList.Count property get method.
- PropertyInfo ArrayListSizeProperty = typeof(ArrayList).GetProperty( "Count" );
- Debug.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
- MethodInfo ArrayListSizeGetMethod = ArrayListSizeProperty.GetGetMethod();
- Debug.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
-
- // Retrieve the Delegate.Equals() method.
- aParamTypes[0] = typeof(Delegate);
- MethodInfo DelegateEqualsMethod = typeof(Delegate).GetMethod( "Equals", aParamTypes, null );
- Debug.Assert(DelegateEqualsMethod != null, "Unable to find the method Delegate.Equlals()");
-
- // Retrieve the Monitor.Enter() method.
- MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod("Enter", MonitorEnterParamTypes, null);
- Debug.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
-
- // Retrieve the Monitor.Exit() method.
- aParamTypes[0] = typeof(Object);
- MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
- Debug.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
-
- // Retrieve the ConnectionPoint.Unadvise() method.
- MethodInfo CPUnadviseMethod = typeof(IConnectionPoint).GetMethod( "Unadvise" );
- Debug.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
-
- // Retrieve the Marshal.ReleaseComObject() method.
- MethodInfo ReleaseComObjectMethod = typeof(Marshal).GetMethod( "ReleaseComObject" );
- Debug.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
-
- // Define the remove_XXX method.
- Type[] parameterTypes;
- parameterTypes = new Type[1];
- parameterTypes[0] = DelegateField.FieldType;
- MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
- "remove_" + SrcItfMethod.Name,
- MethodAttributes.Public | MethodAttributes.Virtual,
- null,
- parameterTypes );
-
- ILGenerator il = Meth.GetILGenerator();
-
- // Declare the local variables.
- LocalBuilder ltNumSinkHelpers = il.DeclareLocal( typeof(Int32) );
- LocalBuilder ltSinkHelperCounter = il.DeclareLocal( typeof(Int32) );
- LocalBuilder ltCurrSinkHelper = il.DeclareLocal( SinkHelperClass );
- LocalBuilder ltLockTaken = il.DeclareLocal(typeof(bool));
-
- // Generate the labels for the for loop.
- Label ForBeginLabel = il.DefineLabel();
- Label ForEndLabel = il.DefineLabel();
- Label FalseIfLabel = il.DefineLabel();
- Label MonitorExitLabel = il.DefineLabel();
-
- // Generate the following code:
- // try {
- il.BeginExceptionBlock();
-
- // Generate the following code:
- // Monitor.Enter(this, ref lockTaken);
- il.Emit(OpCodes.Ldarg, (short)0);
- il.Emit(OpCodes.Ldloca_S, ltLockTaken);
- il.Emit(OpCodes.Call, MonitorEnterMethod);
-
- // Generate the following code:
- // if ( m_aIFooEventsHelpers == null ) goto ForEndLabel;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
- il.Emit( OpCodes.Brfalse, ForEndLabel );
-
- // Generate the following code:
- // int NumEventHelpers = m_aIFooEventsHelpers.Count;
- // int cEventHelpers = 0;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
- il.Emit( OpCodes.Callvirt, ArrayListSizeGetMethod );
- il.Emit( OpCodes.Stloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Ldc_I4, 0 );
- il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
-
- // Generate the following code:
- // if ( 0 >= NumEventHelpers ) goto ForEndLabel;
- il.Emit( OpCodes.Ldc_I4, 0 );
- il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Bge, ForEndLabel );
-
- // Mark this as the beginning of the for loop's body.
- il.MarkLabel( ForBeginLabel );
-
- // Generate the following code:
- // CurrentHelper = (IFooEvents_SinkHelper)m_aIFooEventsHelpers.Get( cEventHelpers );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Callvirt, ArrayListItemGetMethod );
- il.Emit( OpCodes.Castclass, SinkHelperClass );
- il.Emit( OpCodes.Stloc, ltCurrSinkHelper );
-
- // Generate the following code:
- // if ( CurrentHelper.m_FooDelegate )
- il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
- il.Emit( OpCodes.Ldfld, DelegateField );
- il.Emit( OpCodes.Ldnull );
- il.Emit( OpCodes.Beq, FalseIfLabel );
-
- // Generate the following code:
- // if ( CurrentHelper.m_FooDelegate.Equals( d ) )
- il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
- il.Emit( OpCodes.Ldfld, DelegateField );
- il.Emit( OpCodes.Ldarg, (short)1 );
- il.Emit( OpCodes.Castclass, typeof(Object) );
- il.Emit( OpCodes.Callvirt, DelegateEqualsMethod );
- il.Emit( OpCodes.Ldc_I4, 0xff );
- il.Emit( OpCodes.And );
- il.Emit( OpCodes.Ldc_I4, 0 );
- il.Emit( OpCodes.Beq, FalseIfLabel );
-
- // Generate the following code:
- // m_aIFooEventsHelpers.RemoveAt( cEventHelpers );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Callvirt, ArrayListRemoveMethod );
-
- // Generate the following code:
- // m_IFooEventsCP.Unadvise( CurrentHelper.m_dwCookie );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
- il.Emit( OpCodes.Ldfld, CookieField );
- il.Emit( OpCodes.Callvirt, CPUnadviseMethod );
-
- // Generate the following code:
- // if ( NumEventHelpers > 1) break;
- il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Ldc_I4, 1 );
- il.Emit( OpCodes.Bgt, ForEndLabel );
-
- // Generate the following code:
- // Marshal.ReleaseComObject(m_IFooEventsCP);
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Call, ReleaseComObjectMethod );
- il.Emit( OpCodes.Pop );
-
- // Generate the following code:
- // m_IFooEventsCP = null;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldnull );
- il.Emit( OpCodes.Stfld, fbEventCP );
-
- // Generate the following code:
- // m_aIFooEventsHelpers = null;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldnull );
- il.Emit( OpCodes.Stfld, fbSinkHelperArray );
-
- // Generate the following code:
- // break;
- il.Emit( OpCodes.Br, ForEndLabel );
-
- // Mark this as the label to jump to when the if statement is false.
- il.MarkLabel( FalseIfLabel );
-
- // Generate the following code:
- // cEventHelpers++;
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Ldc_I4, 1 );
- il.Emit( OpCodes.Add );
- il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
-
- // Generate the following code:
- // if ( cEventHelpers < NumEventHelpers ) goto ForBeginLabel;
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Blt, ForBeginLabel );
-
- // Mark this as the end of the for loop's body.
- il.MarkLabel( ForEndLabel );
-
- // Generate the following code:
- // } finally {
- il.BeginFinallyBlock();
-
- // Generate the following code:
- // if (lockTaken)
- // Monitor.Exit(this);
- Label skipExit = il.DefineLabel();
- il.Emit(OpCodes.Ldloc, ltLockTaken);
- il.Emit(OpCodes.Brfalse_S, skipExit);
- il.Emit(OpCodes.Ldarg, (short)0);
- il.Emit(OpCodes.Call, MonitorExitMethod);
- il.MarkLabel(skipExit);
-
- // Generate the following code:
- // }
- il.EndExceptionBlock();
-
- // Generate the return opcode.
- il.Emit( OpCodes.Ret );
-
- return Meth;
- }
-
- private MethodBuilder DefineInitSrcItfMethod( TypeBuilder OutputTypeBuilder, Type SourceInterface, FieldBuilder fbSinkHelperArray, FieldBuilder fbEventCP, FieldBuilder fbCPC )
- {
- // Retrieve the constructor info for the array list's default constructor.
- ConstructorInfo DefaultArrayListCons = typeof(ArrayList).GetConstructor(EventProviderWriter.DefaultLookup, null, Array.Empty<Type>(), null );
- Debug.Assert(DefaultArrayListCons != null, "Unable to find the constructor for class ArrayList");
-
- // Temp byte array for Guid
- ubyte[] rgByteGuid = new ubyte[16];
-
- // Retrieve the constructor info for the Guid constructor.
- Type[] aParamTypes = new Type[1];
- aParamTypes[0] = typeof(Byte[]);
- ConstructorInfo ByteArrayGUIDCons = typeof(Guid).GetConstructor(EventProviderWriter.DefaultLookup, null, aParamTypes, null );
- Debug.Assert(ByteArrayGUIDCons != null, "Unable to find the constructor for GUID that accepts a string as argument");
-
- // Retrieve the IConnectionPointContainer.FindConnectionPoint() method.
- MethodInfo CPCFindCPMethod = typeof(IConnectionPointContainer).GetMethod( "FindConnectionPoint" );
- Debug.Assert(CPCFindCPMethod != null, "Unable to find the method ConnectionPointContainer.FindConnectionPoint()");
-
- // Define the Init method itself.
- MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
- "Init",
- MethodAttributes.Private,
- null,
- null );
-
- ILGenerator il = Meth.GetILGenerator();
-
- // Declare the local variables.
- LocalBuilder ltCP = il.DeclareLocal( typeof(IConnectionPoint) );
- LocalBuilder ltEvGuid = il.DeclareLocal( typeof(Guid) );
- LocalBuilder ltByteArrayGuid = il.DeclareLocal( typeof(Byte[]) );
-
- // Generate the following code:
- // IConnectionPoint CP = NULL;
- il.Emit( OpCodes.Ldnull );
- il.Emit( OpCodes.Stloc, ltCP );
-
- // Get unsigned byte array for the GUID of the event interface.
- rgByteGuid = SourceInterface.GUID.ToByteArray();
-
- // Generate the following code:
- // ubyte rgByteArray[] = new ubyte [16];
- il.Emit( OpCodes.Ldc_I4, 0x10 );
- il.Emit( OpCodes.Newarr, typeof(Byte) );
- il.Emit( OpCodes.Stloc, ltByteArrayGuid );
-
- // Generate the following code:
- // rgByteArray[i] = rgByteGuid[i];
- for (int i = 0; i < 16; i++ )
- {
- il.Emit( OpCodes.Ldloc, ltByteArrayGuid );
- il.Emit( OpCodes.Ldc_I4, i );
- il.Emit( OpCodes.Ldc_I4, (int) (rgByteGuid[i]) );
- il.Emit( OpCodes.Stelem_I1);
- }
-
- // Generate the following code:
- // EventItfGuid = Guid( ubyte b[] );
- il.Emit( OpCodes.Ldloca, ltEvGuid );
- il.Emit( OpCodes.Ldloc, ltByteArrayGuid );
- il.Emit( OpCodes.Call, ByteArrayGUIDCons );
-
- // Generate the following code:
- // m_ConnectionPointContainer.FindConnectionPoint( EventItfGuid, CP );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbCPC );
- il.Emit( OpCodes.Ldloca, ltEvGuid );
- il.Emit( OpCodes.Ldloca, ltCP );
- il.Emit( OpCodes.Callvirt, CPCFindCPMethod );
-
- // Generate the following code:
- // m_ConnectionPoint = (IConnectionPoint)CP;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldloc, ltCP );
- il.Emit( OpCodes.Castclass, typeof(IConnectionPoint) );
- il.Emit( OpCodes.Stfld, fbEventCP );
-
- // Generate the following code:
- // m_aEventSinkHelpers = new ArrayList;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Newobj, DefaultArrayListCons );
- il.Emit( OpCodes.Stfld, fbSinkHelperArray );
-
- // Generate the return opcode.
- il.Emit( OpCodes.Ret );
-
- return Meth;
- }
-
- private void DefineConstructor( TypeBuilder OutputTypeBuilder, FieldBuilder fbCPC )
- {
- // Retrieve the constructor info for the base class's constructor.
- ConstructorInfo DefaultBaseClsCons = typeof(Object).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null );
- Debug.Assert(DefaultBaseClsCons != null, "Unable to find the object's public default constructor");
-
- // Define the default constructor.
- MethodAttributes ctorAttributes = MethodAttributes.SpecialName | (DefaultBaseClsCons.Attributes & MethodAttributes.MemberAccessMask);
- MethodBuilder Cons = OutputTypeBuilder.DefineMethod(
- ".ctor",
- ctorAttributes,
- null,
- new Type[]{typeof(Object)} );
-
- ILGenerator il = Cons.GetILGenerator();
-
- // Generate the call to the base class constructor.
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Call, DefaultBaseClsCons );
-
- // Generate the following code:
- // m_ConnectionPointContainer = (IConnectionPointContainer)EventSource;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldarg, (short)1 );
- il.Emit( OpCodes.Castclass, typeof(IConnectionPointContainer) );
- il.Emit( OpCodes.Stfld, fbCPC );
-
- // Generate the return opcode.
- il.Emit( OpCodes.Ret );
- }
-
- private MethodBuilder DefineFinalizeMethod( TypeBuilder OutputTypeBuilder, Type SinkHelperClass, FieldBuilder fbSinkHelper, FieldBuilder fbEventCP )
- {
- // Find the cookie on the event sink helper.
- FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
- Debug.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
-
- // Retrieve the ArrayList.Item property get method.
- PropertyInfo ArrayListItemProperty = typeof(ArrayList).GetProperty( "Item" );
- Debug.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
- MethodInfo ArrayListItemGetMethod = ArrayListItemProperty.GetGetMethod();
- Debug.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
-
- // Retrieve the ArrayList.Count property get method.
- PropertyInfo ArrayListSizeProperty = typeof(ArrayList).GetProperty( "Count" );
- Debug.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
- MethodInfo ArrayListSizeGetMethod = ArrayListSizeProperty.GetGetMethod();
- Debug.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
-
- // Retrieve the ConnectionPoint.Unadvise() method.
- MethodInfo CPUnadviseMethod = typeof(IConnectionPoint).GetMethod( "Unadvise" );
- Debug.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
-
- // Retrieve the Marshal.ReleaseComObject() method.
- MethodInfo ReleaseComObjectMethod = typeof(Marshal).GetMethod( "ReleaseComObject" );
- Debug.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
-
- // Retrieve the Monitor.Enter() method.
- MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod("Enter", MonitorEnterParamTypes, null);
- Debug.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
-
- // Retrieve the Monitor.Exit() method.
- Type[] aParamTypes = new Type[1];
- aParamTypes[0] = typeof(Object);
- MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
- Debug.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
-
- // Define the Finalize method itself.
- MethodBuilder Meth = OutputTypeBuilder.DefineMethod( "Finalize", MethodAttributes.Public | MethodAttributes.Virtual, null, null );
-
- ILGenerator il = Meth.GetILGenerator();
-
- // Declare the local variables.
- LocalBuilder ltNumSinkHelpers = il.DeclareLocal( typeof(Int32) );
- LocalBuilder ltSinkHelperCounter = il.DeclareLocal( typeof(Int32) );
- LocalBuilder ltCurrSinkHelper = il.DeclareLocal( SinkHelperClass );
- LocalBuilder ltLockTaken = il.DeclareLocal(typeof(bool));
-
- // Generate the following code:
- // try {
- il.BeginExceptionBlock();
-
- // Generate the following code:
- // Monitor.Enter(this, ref lockTaken);
- il.Emit(OpCodes.Ldarg, (short)0);
- il.Emit(OpCodes.Ldloca_S, ltLockTaken);
- il.Emit(OpCodes.Call, MonitorEnterMethod);
-
- // Generate the labels.
- Label ForBeginLabel = il.DefineLabel();
- Label ReleaseComObjectLabel = il.DefineLabel();
- Label AfterReleaseComObjectLabel = il.DefineLabel();
-
- // Generate the following code:
- // if ( m_IFooEventsCP == null ) goto AfterReleaseComObjectLabel;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Brfalse, AfterReleaseComObjectLabel );
-
- // Generate the following code:
- // int NumEventHelpers = m_aIFooEventsHelpers.Count;
- // int cEventHelpers = 0;
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelper );
- il.Emit( OpCodes.Callvirt, ArrayListSizeGetMethod );
- il.Emit( OpCodes.Stloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Ldc_I4, 0 );
- il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
-
- // Generate the following code:
- // if ( 0 >= NumEventHelpers ) goto ReleaseComObjectLabel;
- il.Emit( OpCodes.Ldc_I4, 0 );
- il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Bge, ReleaseComObjectLabel );
-
- // Mark this as the beginning of the for loop's body.
- il.MarkLabel( ForBeginLabel );
-
- // Generate the following code:
- // CurrentHelper = (IFooEvents_SinkHelper)m_aIFooEventsHelpers.Get( cEventHelpers );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbSinkHelper );
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Callvirt, ArrayListItemGetMethod );
- il.Emit( OpCodes.Castclass, SinkHelperClass );
- il.Emit( OpCodes.Stloc, ltCurrSinkHelper );
-
- // Generate the following code:
- // m_IFooEventsCP.Unadvise( CurrentHelper.m_dwCookie );
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
- il.Emit( OpCodes.Ldfld, CookieField );
- il.Emit( OpCodes.Callvirt, CPUnadviseMethod );
-
- // Generate the following code:
- // cEventHelpers++;
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Ldc_I4, 1 );
- il.Emit( OpCodes.Add );
- il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
-
- // Generate the following code:
- // if ( cEventHelpers < NumEventHelpers ) goto ForBeginLabel;
- il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
- il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
- il.Emit( OpCodes.Blt, ForBeginLabel );
-
- // Mark this as the end of the for loop's body.
- il.MarkLabel( ReleaseComObjectLabel );
-
- // Generate the following code:
- // Marshal.ReleaseComObject(m_IFooEventsCP);
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Ldfld, fbEventCP );
- il.Emit( OpCodes.Call, ReleaseComObjectMethod );
- il.Emit( OpCodes.Pop );
-
- // Mark this as the end of the for loop's body.
- il.MarkLabel( AfterReleaseComObjectLabel );
-
- // Generate the following code:
- // } catch {
- il.BeginCatchBlock(typeof(System.Exception));
- il.Emit( OpCodes.Pop );
-
- // Generate the following code:
- // } finally {
- il.BeginFinallyBlock();
-
- // Generate the following code:
- // if (lockTaken)
- // Monitor.Exit(this);
- Label skipExit = il.DefineLabel();
- il.Emit(OpCodes.Ldloc, ltLockTaken);
- il.Emit(OpCodes.Brfalse_S, skipExit);
- il.Emit(OpCodes.Ldarg, (short)0);
- il.Emit(OpCodes.Call, MonitorExitMethod);
- il.MarkLabel(skipExit);
-
- // Generate the following code:
- // }
- il.EndExceptionBlock();
-
- // Generate the return opcode.
- il.Emit( OpCodes.Ret );
-
- return Meth;
- }
-
- private void DefineDisposeMethod( TypeBuilder OutputTypeBuilder, MethodBuilder FinalizeMethod )
- {
- // Retrieve the method info for GC.SuppressFinalize().
- MethodInfo SuppressFinalizeMethod = typeof(GC).GetMethod("SuppressFinalize");
- Debug.Assert(SuppressFinalizeMethod != null, "Unable to find the GC.SuppressFinalize");
-
- // Define the Finalize method itself.
- MethodBuilder Meth = OutputTypeBuilder.DefineMethod( "Dispose", MethodAttributes.Public | MethodAttributes.Virtual, null, null );
-
- ILGenerator il = Meth.GetILGenerator();
-
- // Generate the following code:
- // Finalize()
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Callvirt, FinalizeMethod );
-
- // Generate the following code:
- // GC.SuppressFinalize()
- il.Emit( OpCodes.Ldarg, (short)0 );
- il.Emit( OpCodes.Call, SuppressFinalizeMethod );
-
- // Generate the return opcode.
- il.Emit( OpCodes.Ret );
- }
-
- private ModuleBuilder m_OutputModule;
- private String m_strDestTypeName;
- private Type m_EventItfType;
- private Type m_SrcItfType;
- private Type m_SinkHelperType;
- }
-}