@@ -28,7 +28,47 @@ public int Run()
2828
2929 void TryToReuseTheDynamicMethod ( TestContext t )
3030 {
31- t . Fail ( "TryToReuseTheDynamicMethod is not implemented yet" ) ;
31+ // Let's say there is a DynamicMethod of Func<int, int> returning its argument,
32+ // at the end I want to reuse the created DynamicMethod for another Func<int, int> returning arg + 42
33+
34+ var dynMethod = new DynamicMethod ( string . Empty ,
35+ typeof ( int ) ,
36+ [ typeof ( ExpressionCompiler . ArrayClosure ) , typeof ( int ) ] ,
37+ typeof ( ExpressionCompiler . ArrayClosure ) ,
38+ true ) ;
39+
40+ var il = dynMethod . GetILGenerator ( ) ;
41+
42+ il . Emit ( OpCodes . Ldarg_1 ) ;
43+ il . Emit ( OpCodes . Ret ) ;
44+
45+ var func = ( Func < int , int > ) dynMethod . CreateDelegate ( typeof ( Func < int , int > ) , ExpressionCompiler . EmptyArrayClosure ) ;
46+ t . AreEqual ( 41 , func ( 41 ) ) ;
47+
48+ // Reset the DynamicMethod internals that we need to reuse:
49+ // _ilGenerator = null;
50+ // _initLocals = true;
51+ // _methodHandle = null;
52+ var dynMethodType = dynMethod . GetType ( ) ;
53+ var ilGeneratorField = dynMethodType . GetField ( "_ilGenerator" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
54+ var initLocalsField = dynMethodType . GetField ( "_initLocals" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
55+ var methodHandleField = dynMethodType . GetField ( "_methodHandle" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
56+
57+ Console . WriteLine ( $ "{{_ilGenerator: { ilGeneratorField ? . GetValue ( dynMethod ) ?? "null" } , _initLocals: { initLocalsField . GetValue ( dynMethod ) } , _methodHandle: { methodHandleField ? . GetValue ( dynMethod ) ?? "null" } }}") ;
58+ ilGeneratorField . SetValue ( dynMethod , null ) ;
59+ initLocalsField . SetValue ( dynMethod , true ) ;
60+ // methodHandleField.SetValue(dynMethod, null); // breaks the CLR
61+
62+ var il2 = dynMethod . GetILGenerator ( ) ;
63+
64+ il2 . Emit ( OpCodes . Ldarg_1 ) ;
65+ il2 . Emit ( OpCodes . Ldc_I4 , 42 ) ;
66+ il2 . Emit ( OpCodes . Add ) ;
67+ il2 . Emit ( OpCodes . Ret ) ;
68+ t . AreEqual ( 41 , func ( 41 ) ) ;
69+
70+ var func2 = ( Func < int , int > ) dynMethod . CreateDelegate ( typeof ( Func < int , int > ) , ExpressionCompiler . EmptyArrayClosure ) ;
71+ t . AreEqual ( 83 , func2 ( 41 ) ) ;
3272 }
3373
3474 public void DynamicMethod_Emit_Hack ( )
0 commit comments