-
Notifications
You must be signed in to change notification settings - Fork 2
CIL
There are many utilities to aid in composing IL edits.
An ILCursor extension which allows you to conditionally substitute a value with another one given a predicate condition.
Refer to this DAYBREAK example:
private static void DrawSingleTile_SkipDrawingForLilyPads(ILContext il)
{
var c = new ILCursor(il);
c.GotoNext(MoveType.Before, x => x.MatchLdcI4(TileID.LilyPad));
c.Substitute(TileID.LilyPad, type => TileLoader.GetTile(type) is ILilyPad { VanillaDrawTileInWater: true });
}The above code matches to before TileID.LilyPad is pushed to the stack and conditionally replaces the value right before it with TileID.LilyPad if the tile is of the ILilyPad type. This is used to override a condition (type == TileID.LilyPad) to be type == TileID.LilyPad (true) for all TileLoader.GetTile(type) is ILilyPad { VanillaDrawTileInWater: true } (while preserving any checks that don't fulfill this condition). While it's used here to intercept a conditional branch, it can be used in any context where you want to replace a value given a condition.
An extension to ILCursor and related types which allows you to easily define a new local variable within a MethodBody. It returns the VaribleDefinition which may be directly used in APIs like ILCursor::EmitLdloc(VariableDefinition). It should be preferred to use the generic overload when possible, but you can pass a Type object directly as well.