Dispatch Macros
Each of these computes the address to call from the licence result rather
than branching on it. With the check returning 1 or 0, the target is
fallback + (real - fallback) * valid: the real function when
licensed, the fallback when not. No cbz, no b.eq,
and no static reference from the call site to the guarded function.
TIL_DISPATCH
TIL_DISPATCH(pkg, fn)
Calls fn() when licensed. When not, calls an inert stub that
does nothing. fn takes no arguments and returns nothing.
TIL_DISPATCH("com.example.mytweak", install_my_hooks);
TIL_DISPATCH_OR
TIL_DISPATCH_OR(pkg, fn, fallback)
As above, but you choose what runs when unlicensed. Useful when a tweak has a free tier: the fallback can be the reduced behaviour instead of nothing.
TIL_DISPATCH_OR("com.example.mytweak", full_feature, basic_feature);
TIL_DISPATCH_CALL
TIL_DISPATCH_CALL(pkg, fn, fallback, ...)
For functions that take arguments and return a value. The arguments are forwarded to whichever of the two is selected, so both must have the same signature.
int width = TIL_DISPATCH_CALL("com.example.mytweak",
premium_width, default_width, view);
TIL_DISPATCH_FN
TIL_DISPATCH_FN(pkg, fn, fallback)
Resolves to the function pointer without calling it, for storing in a struct or passing as a callback. The selection happens where the macro is written, so the pointer handed on is already the right one.
What this does and does not achieve
It removes the single conditional that would otherwise decide everything, and it keeps your guarded function out of the cross-reference list for the check. Someone reading the disassembly still sees arithmetic on two addresses, and can still work out what it means.
Use it in several places rather than one. The value is in there being no single edit, which only holds if there is genuinely more than one.