@@ -65,39 +65,49 @@ public void AddMethod(MethodDefinition method)
6565 public InstructionBlock PushMethodInfoOnStack ( MethodDefinition method , VariablePersistable variablePersistable )
6666 {
6767 var fieldDefinition = _fieldsCache [ method ] ;
68- var instruction = Instruction . Create ( OpCodes . Ldsfld , fieldDefinition ) ;
68+ var getMethodFromHandle2 = ImportGetMethodFromHandleArg2 ( ) ;
69+
70+ var instructions = new List < Instruction > ( ) ;
71+ if ( ContainsOpenTypeRecursive ( method ) )
72+ {
73+ instructions . Add ( Instruction . Create ( OpCodes . Ldtoken , method ) ) ;
74+ instructions . Add ( Instruction . Create ( OpCodes . Ldtoken , method . DeclaringType ) ) ;
75+ instructions . Add ( Instruction . Create ( OpCodes . Call , getMethodFromHandle2 ) ) ;
76+ }
77+ else
78+ instructions . Add ( Instruction . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
79+
6980 var store = variablePersistable . Store (
70- new InstructionBlock ( "" , instruction ) ,
81+ new InstructionBlock ( "" , instructions ) ,
7182 variablePersistable . PersistedType ) ;
7283 return new InstructionBlock ( $ "Load method info for '{ method . Name } '", store . Instructions ) ;
7384 }
7485
7586 public void Finish ( )
7687 {
77- if ( _fieldsCache . Any ( ) )
78- CreateStaticCtor ( ) ;
88+ CreateStaticCtor ( ) ;
7989 }
80-
81- public bool CanWeave ( MethodDefinition method )
90+
91+ private static bool ContainsOpenTypeRecursive ( MethodDefinition method )
8292 {
83- // no support for open generic types
84- if ( IsOpenType ( method ) )
85- return false ;
93+ if ( ContainsOpenType ( method ) )
94+ return true ;
8695
8796 var parentType = method . DeclaringType ;
8897 while ( parentType != null )
8998 {
90- if ( IsOpenType ( parentType ) )
91- return false ;
99+ if ( ContainsOpenType ( parentType ) )
100+ return true ;
101+
92102 parentType = parentType . DeclaringType ;
93103 }
94104
95- return true ;
105+ return false ;
96106 }
97107
98- private static bool IsOpenType ( IGenericParameterProvider method )
108+ private static bool ContainsOpenType ( IGenericParameterProvider method )
99109 {
100- return method . GenericParameters . Any ( x => x . IsGenericParameter ) ;
110+ return method . GenericParameters . Any ( x => x . ContainsGenericParameter ) ;
101111 }
102112
103113 private string CreateIdentifier ( MemberReference method )
@@ -120,15 +130,21 @@ private void CreateStaticCtor()
120130 var cctor = new MethodDefinition ( ".cctor" , staticConstructorAttributes , typeReferenceVoid ) ;
121131
122132 // taken from https://gist.github.com/jbevain/390902
123- var getMethodFromHandle = ImportGetMethodFromHandle ( ) ;
133+ var getMethodFromHandle = ImportGetMethodFromHandleArg1 ( ) ;
124134 var cctorInstructions = new List < Instruction > ( ) ;
125135 foreach ( var entry in _fieldsCache )
126136 {
137+ if ( ContainsOpenTypeRecursive ( entry . Key ) )
138+ continue ; // method info has to be resolved during runtime so we don't need a cache entry
139+
127140 cctorInstructions . Add ( Instruction . Create ( OpCodes . Ldtoken , entry . Key ) ) ;
128141 cctorInstructions . Add ( Instruction . Create ( OpCodes . Call , getMethodFromHandle ) ) ;
129142 cctorInstructions . Add ( Instruction . Create ( OpCodes . Stsfld , entry . Value ) ) ;
130143 }
131144
145+ if ( ! cctorInstructions . Any ( ) )
146+ return ;
147+
132148 cctorInstructions . Add ( Instruction . Create ( OpCodes . Ret ) ) ;
133149
134150 foreach ( var methodInstruction in cctorInstructions )
@@ -153,18 +169,24 @@ private TypeReference GetTypeReference(string name)
153169 return _mainModule . TypeSystem . Void ;
154170 default :
155171 {
156- var splitted = name . Split ( '.' ) ;
157- var namespaceName = string . Join ( "." , splitted . Take ( splitted . Length - 1 ) ) ;
158- var typeName = splitted . Last ( ) ;
172+ var split = name . Split ( '.' ) ;
173+ var namespaceName = string . Join ( "." , split . Take ( split . Length - 1 ) ) ;
174+ var typeName = split . Last ( ) ;
159175 return new TypeReference ( namespaceName , typeName , _mainModule , _mainModule . TypeSystem . CoreLibrary ) ;
160176 }
161177 }
162178 }
163179
164- private MethodReference ImportGetMethodFromHandle ( )
180+ private MethodReference ImportGetMethodFromHandleArg1 ( )
165181 {
166182 return _mainModule . ImportReference ( typeof ( MethodBase )
167183 . GetMethod ( "GetMethodFromHandle" , new [ ] { typeof ( RuntimeMethodHandle ) } ) ) ;
168184 }
185+
186+ private MethodReference ImportGetMethodFromHandleArg2 ( )
187+ {
188+ return _mainModule . ImportReference ( typeof ( MethodBase )
189+ . GetMethod ( "GetMethodFromHandle" , new [ ] { typeof ( RuntimeMethodHandle ) , typeof ( RuntimeTypeHandle ) } ) ) ;
190+ }
169191 }
170192}
0 commit comments