Skip to content

Instantly share code, notes, and snippets.

@pardeike
Last active March 19, 2021 09:00
Show Gist options
  • Save pardeike/d75d609b842d793b0e4e938d86ed8e27 to your computer and use it in GitHub Desktop.
Save pardeike/d75d609b842d793b0e4e938d86ed8e27 to your computer and use it in GitHub Desktop.
using System;
public static class Program {
public static void Main() {
Console.WriteLine(DynamicHarmonyWrapper());
}
public static string DynamicHarmonyWrapper() {
string result = default;
bool finalized = false;
Exception ex = null;
try {
result = Original();
// finalizers get all the arguments a prefix could get too
// plus one new one: "Exception __exception"
// they SHOULD NOT edit the passed exception but instead
// signal to Harmony that they change it by returning it
// here finalizers are called without try-catch so they are
// allowed to throw exceptions. note, that it is perfectly fine
// to get null passed into the exception argument
SimpleFinalizer(ref result);
ex = EditFinalizer(ex, ref result);
finalized = true;
if (ex != null) throw ex;
return result;
} catch (Exception e) {
ex = e;
// finalizers will get another chance here, so they are guaranteed to run
// even if their first invocation threw an exception
if (!finalized)
{
try { SimpleFinalizer(ref result); } catch { }
try { ex = EditFinalizer(ex, ref result); } catch { }
}
// All this code is generated dynamically, which means that Harmony
// can build it depending on
// - if there are any finalizers (if not, skip overall try-catch logic)
// - re-throwing can be dynamic too:
//
// alternative 1: for when all finalizers are returning void:
throw;
// alternative 2: for when at least one finalizer has a non-void return
if (ex != null) throw ex;
// make compiler happy (can probably be skipped in IL)
return result;
}
}
public static String Original() { return "original"; }
public static void SimpleFinalizer(ref string result) { }
public static Exception EditFinalizer(Exception ex, ref string result) { return ex; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment