|
4 | 4 | using AsmResolver.DotNet.Collections;
|
5 | 5 | using AsmResolver.DotNet.Signatures;
|
6 | 6 | using AsmResolver.PE.DotNet.Cil;
|
| 7 | +using AsmResolver.PE.DotNet.Metadata.Tables; |
7 | 8 | using Il2CppInterop.Generator.Contexts;
|
8 | 9 | using Il2CppInterop.Generator.Extensions;
|
9 | 10 | using Il2CppInterop.Generator.Passes;
|
@@ -341,13 +342,91 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t
|
341 | 342 | newLabel.Instruction = instructionMap[oldLabel.Instruction!];
|
342 | 343 | }
|
343 | 344 |
|
| 345 | + // Copy exception handlers |
| 346 | + foreach (var exceptionHandler in original.CilMethodBody.ExceptionHandlers) |
| 347 | + { |
| 348 | + var newExceptionHandler = new CilExceptionHandler |
| 349 | + { |
| 350 | + HandlerType = exceptionHandler.HandlerType |
| 351 | + }; |
| 352 | + |
| 353 | + switch (exceptionHandler.TryStart) |
| 354 | + { |
| 355 | + case null: |
| 356 | + break; |
| 357 | + case CilInstructionLabel { Instruction: not null } tryStart: |
| 358 | + newExceptionHandler.TryStart = new CilInstructionLabel(instructionMap[tryStart.Instruction]); |
| 359 | + break; |
| 360 | + default: |
| 361 | + return false; |
| 362 | + } |
| 363 | + |
| 364 | + switch (exceptionHandler.TryEnd) |
| 365 | + { |
| 366 | + case null: |
| 367 | + break; |
| 368 | + case CilInstructionLabel { Instruction: not null } tryEnd: |
| 369 | + newExceptionHandler.TryEnd = new CilInstructionLabel(instructionMap[tryEnd.Instruction]); |
| 370 | + break; |
| 371 | + default: |
| 372 | + return false; |
| 373 | + } |
| 374 | + |
| 375 | + switch (exceptionHandler.HandlerStart) |
| 376 | + { |
| 377 | + case null: |
| 378 | + break; |
| 379 | + case CilInstructionLabel { Instruction: not null } handlerStart: |
| 380 | + newExceptionHandler.HandlerStart = new CilInstructionLabel(instructionMap[handlerStart.Instruction]); |
| 381 | + break; |
| 382 | + default: |
| 383 | + return false; |
| 384 | + } |
| 385 | + |
| 386 | + switch (exceptionHandler.HandlerEnd) |
| 387 | + { |
| 388 | + case null: |
| 389 | + break; |
| 390 | + case CilInstructionLabel { Instruction: not null } handlerEnd: |
| 391 | + newExceptionHandler.HandlerEnd = new CilInstructionLabel(instructionMap[handlerEnd.Instruction]); |
| 392 | + break; |
| 393 | + default: |
| 394 | + return false; |
| 395 | + } |
| 396 | + |
| 397 | + switch (exceptionHandler.FilterStart) |
| 398 | + { |
| 399 | + case null: |
| 400 | + break; |
| 401 | + case CilInstructionLabel { Instruction: not null } filterStart: |
| 402 | + newExceptionHandler.FilterStart = new CilInstructionLabel(instructionMap[filterStart.Instruction]); |
| 403 | + break; |
| 404 | + default: |
| 405 | + return false; |
| 406 | + } |
| 407 | + |
| 408 | + switch (exceptionHandler.ExceptionType?.ToTypeSignature()) |
| 409 | + { |
| 410 | + case null: |
| 411 | + break; |
| 412 | + case CorLibTypeSignature { ElementType: ElementType.Object }: |
| 413 | + newExceptionHandler.ExceptionType = imports.Module.CorLibTypeFactory.Object.ToTypeDefOrRef(); |
| 414 | + break; |
| 415 | + default: |
| 416 | + // In the future, we will throw exact exceptions, but we don't right now, |
| 417 | + // so attempting to catch a specific exception type will always fail. |
| 418 | + return false; |
| 419 | + } |
| 420 | + |
| 421 | + target.CilMethodBody.ExceptionHandlers.Add(newExceptionHandler); |
| 422 | + } |
| 423 | + |
344 | 424 | return true;
|
345 | 425 | }
|
346 | 426 |
|
347 | 427 | public static void ReplaceBodyWithException(MethodDefinition newMethod, RuntimeAssemblyReferences imports)
|
348 | 428 | {
|
349 |
| - newMethod.CilMethodBody!.LocalVariables.Clear(); |
350 |
| - newMethod.CilMethodBody.Instructions.Clear(); |
| 429 | + newMethod.CilMethodBody = new(newMethod); |
351 | 430 | var processor = newMethod.CilMethodBody.Instructions;
|
352 | 431 |
|
353 | 432 | processor.Add(OpCodes.Ldstr, "Method unstripping failed");
|
|
0 commit comments