@@ -1076,6 +1076,157 @@ public void SimpleTryCatchBlock()
10761076 }
10771077 }
10781078
1079+ [ Fact ]
1080+ public void TryCatchWithTypeBuilderException ( )
1081+ {
1082+ using ( TempFile file = TempFile . Create ( ) )
1083+ {
1084+ PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder ( new AssemblyName ( "MyAssembly" ) , typeof ( object ) . Assembly ) ;
1085+ ModuleBuilder mb = ab . DefineDynamicModule ( "MyModule" ) ;
1086+ TypeBuilder tb = mb . DefineType ( "MyType" , TypeAttributes . Public ) ;
1087+ TypeBuilder exceptionType = mb . DefineType ( "MyException" , TypeAttributes . Public , typeof ( Exception ) ) ;
1088+ MethodBuilder method = tb . DefineMethod ( "Method" , MethodAttributes . Public | MethodAttributes . Static , typeof ( int ) , [ typeof ( int ) , typeof ( int ) ] ) ;
1089+ ILGenerator ilGenerator = method . GetILGenerator ( ) ;
1090+ ilGenerator . BeginExceptionBlock ( ) ;
1091+ ilGenerator . Emit ( OpCodes . Ldarg_0 ) ;
1092+ ilGenerator . Emit ( OpCodes . Ldarg_1 ) ;
1093+ ilGenerator . Emit ( OpCodes . Add ) ;
1094+ ilGenerator . BeginCatchBlock ( exceptionType ) ;
1095+ ilGenerator . Emit ( OpCodes . Ldc_I4_0 ) ;
1096+ ilGenerator . EndExceptionBlock ( ) ;
1097+ ilGenerator . Emit ( OpCodes . Ret ) ;
1098+ tb . CreateType ( ) ;
1099+ exceptionType . CreateType ( ) ;
1100+ ab . Save ( file . Path ) ;
1101+
1102+ using ( MetadataLoadContext mlc = new MetadataLoadContext ( new CoreMetadataAssemblyResolver ( ) ) )
1103+ {
1104+ Assembly assemblyFromDisk = mlc . LoadFromAssemblyPath ( file . Path ) ;
1105+ Type typeFromDisk = assemblyFromDisk . Modules . First ( ) . GetType ( "MyType" ) ;
1106+ MethodBody body = typeFromDisk . GetMethod ( "Method" ) . GetMethodBody ( ) ;
1107+ Assert . Equal ( 1 , body . ExceptionHandlingClauses . Count ) ;
1108+ Assert . Equal ( "MyException" , body . ExceptionHandlingClauses [ 0 ] . CatchType . FullName ) ;
1109+ Assert . Equal ( ExceptionHandlingClauseOptions . Clause , body . ExceptionHandlingClauses [ 0 ] . Flags ) ;
1110+ }
1111+ }
1112+ }
1113+
1114+ [ Fact ]
1115+ public void TryMultipleCatchFinallyBlocks ( )
1116+ {
1117+ using ( TempFile file = TempFile . Create ( ) )
1118+ {
1119+ PersistedAssemblyBuilder ab = AssemblySaveTools . PopulateAssemblyBuilderAndTypeBuilder ( out TypeBuilder tb ) ;
1120+ MethodBuilder method = tb . DefineMethod ( "Method" , MethodAttributes . Public | MethodAttributes . Static , typeof ( int ) , [ typeof ( int ) , typeof ( int ) ] ) ;
1121+ FieldBuilder fb = tb . DefineField ( "Field" , typeof ( int ) , FieldAttributes . Public | FieldAttributes . Static ) ;
1122+ Type dBZException = typeof ( DivideByZeroException ) ;
1123+ TypeBuilder myExceptionType = ab . GetDynamicModule ( "MyModule" ) . DefineType ( "MyException" , TypeAttributes . Public , typeof ( Exception ) ) ;
1124+ myExceptionType . CreateType ( ) ;
1125+ Type exception = typeof ( Exception ) ;
1126+ Type overflowException = typeof ( OverflowException ) ;
1127+ ILGenerator ilGenerator = method . GetILGenerator ( ) ;
1128+ LocalBuilder local = ilGenerator . DeclareLocal ( typeof ( int ) ) ;
1129+ Label exBlock = ilGenerator . BeginExceptionBlock ( ) ;
1130+ Label check100 = ilGenerator . DefineLabel ( ) ;
1131+ Label leave = ilGenerator . DefineLabel ( ) ;
1132+ ilGenerator . Emit ( OpCodes . Ldarg_0 ) ;
1133+ ilGenerator . Emit ( OpCodes . Ldarg_1 ) ;
1134+ ilGenerator . Emit ( OpCodes . Div ) ;
1135+ ilGenerator . Emit ( OpCodes . Stloc_0 ) ;
1136+ ilGenerator . Emit ( OpCodes . Ldloc_0 ) ;
1137+ ilGenerator . Emit ( OpCodes . Brtrue , check100 ) ;
1138+ ilGenerator . ThrowException ( myExceptionType ) ;
1139+ ilGenerator . MarkLabel ( check100 ) ;
1140+ ilGenerator . Emit ( OpCodes . Ldarg_1 ) ;
1141+ ilGenerator . Emit ( OpCodes . Ldc_I4 , 100 ) ;
1142+ ilGenerator . Emit ( OpCodes . Bne_Un , leave ) ;
1143+ ilGenerator . ThrowException ( overflowException ) ;
1144+ ilGenerator . MarkLabel ( leave ) ;
1145+ ilGenerator . BeginCatchBlock ( dBZException ) ;
1146+ ilGenerator . EmitWriteLine ( "Error: division by zero" ) ;
1147+ ilGenerator . Emit ( OpCodes . Ldc_I4_M1 ) ;
1148+ ilGenerator . Emit ( OpCodes . Stloc_0 ) ;
1149+ ilGenerator . BeginCatchBlock ( myExceptionType ) ;
1150+ ilGenerator . EmitWriteLine ( "Error: MyException" ) ;
1151+ ilGenerator . Emit ( OpCodes . Ldc_I4_S , 2 ) ;
1152+ ilGenerator . Emit ( OpCodes . Stloc_0 ) ;
1153+ ilGenerator . BeginCatchBlock ( exception ) ;
1154+ ilGenerator . EmitWriteLine ( "Error: generic Exception" ) ;
1155+ ilGenerator . Emit ( OpCodes . Ldc_I4_S , 3 ) ;
1156+ ilGenerator . Emit ( OpCodes . Stloc_0 ) ;
1157+ ilGenerator . BeginFinallyBlock ( ) ;
1158+ ilGenerator . EmitWriteLine ( "Finally block" ) ;
1159+ ilGenerator . Emit ( OpCodes . Ldc_I4_S , 30 ) ;
1160+ ilGenerator . Emit ( OpCodes . Stsfld , fb ) ;
1161+ ilGenerator . EndExceptionBlock ( ) ;
1162+ ilGenerator . Emit ( OpCodes . Ldloc_0 ) ;
1163+ ilGenerator . Emit ( OpCodes . Ret ) ;
1164+ tb . CreateType ( ) ;
1165+ ab . Save ( file . Path ) ;
1166+
1167+ TestAssemblyLoadContext tlc = new TestAssemblyLoadContext ( ) ;
1168+ Assembly assemblyFromDisk = tlc . LoadFromAssemblyPath ( file . Path ) ;
1169+ Type typeFromDisk = assemblyFromDisk . GetType ( "MyType" ) ;
1170+ MethodInfo methodFromDisk = typeFromDisk . GetMethod ( "Method" ) ;
1171+ MethodBody body = methodFromDisk . GetMethodBody ( ) ;
1172+ Assert . Equal ( 4 , body . ExceptionHandlingClauses . Count ) ;
1173+ Assert . Equal ( ExceptionHandlingClauseOptions . Clause , body . ExceptionHandlingClauses [ 0 ] . Flags ) ;
1174+ Assert . Equal ( ExceptionHandlingClauseOptions . Clause , body . ExceptionHandlingClauses [ 1 ] . Flags ) ;
1175+ Assert . Equal ( ExceptionHandlingClauseOptions . Clause , body . ExceptionHandlingClauses [ 2 ] . Flags ) ;
1176+ Assert . Equal ( ExceptionHandlingClauseOptions . Finally , body . ExceptionHandlingClauses [ 3 ] . Flags ) ;
1177+ Assert . Equal ( dBZException . FullName , body . ExceptionHandlingClauses [ 0 ] . CatchType . FullName ) ;
1178+ Assert . Equal ( "MyException" , body . ExceptionHandlingClauses [ 1 ] . CatchType . FullName ) ;
1179+ Assert . Equal ( exception . FullName , body . ExceptionHandlingClauses [ 2 ] . CatchType . FullName ) ;
1180+ /*
1181+ public class MyException : Exception { }
1182+
1183+ public class MyType
1184+ {
1185+ public static int Field;
1186+ public static int Method(int a, int b)
1187+ {
1188+ int res;
1189+ try{
1190+ res = a/b;
1191+ if (res == 0)
1192+ throw new MyException();
1193+ if (b == 100)
1194+ throw new OverflowException();
1195+ }
1196+ catch(DivideByZeroException)
1197+ {
1198+ Console.WriteLine("Divide by zero caught");
1199+ res = -1;
1200+ }
1201+ catch(MyException)
1202+ {
1203+ Console.WriteLine("MyException caught");
1204+ res = 2;
1205+ }
1206+ catch(Exception)
1207+ {
1208+ Console.WriteLine("Divide by zero!");
1209+ res = 3;
1210+ }
1211+ finally
1212+ {
1213+ Console.WriteLine("Finally block");
1214+ Field = 30;
1215+ }
1216+ return res;
1217+ }
1218+ }*/
1219+ FieldInfo field = typeFromDisk . GetField ( "Field" ) ;
1220+ Assert . Equal ( 0 , field . GetValue ( null ) ) ;
1221+ Assert . Equal ( 5 , methodFromDisk . Invoke ( null , new object [ ] { 50 , 10 } ) ) ;
1222+ Assert . Equal ( 30 , field . GetValue ( null ) ) ;
1223+ Assert . Equal ( - 1 , methodFromDisk . Invoke ( null , new object [ ] { 1 , 0 } ) ) ;
1224+ Assert . Equal ( 2 , methodFromDisk . Invoke ( null , new object [ ] { 0 , 1 } ) ) ;
1225+ Assert . Equal ( 3 , methodFromDisk . Invoke ( null , new object [ ] { 1000 , 100 } ) ) ;
1226+ tlc . Unload ( ) ;
1227+ }
1228+ }
1229+
10791230 [ Fact ]
10801231 public void TryMultipleCatchBlocks ( )
10811232 {
0 commit comments