Last active
July 16, 2020 11:39
-
-
Save pardeike/52a518c452d4b7b9db63fef698454a4a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il, MethodBase original) | |
{ | |
// create new local variables | |
var local = il.DeclareLocal(typeof(TheType)); | |
// create new labels for jumping | |
var label = il.DefineLabel(); | |
// inspect original methods properties | |
var args = original.GetParameters(); | |
// alternative 1 - looping and emitting | |
// | |
yield return ...; // add new codes before | |
foreach (CodeInstruction instruction in instructions) | |
{ | |
// skip instructions | |
if (...) | |
continue; | |
// add new instructions | |
if (...) | |
yield return new CodeInstruction(...); | |
// edit instructions | |
if (...) | |
{ | |
instruction.opcode = OpCodes.Brtrue; | |
instruction.operand = label; | |
// or | |
instruction.labels.Add(label); // add label | |
// or | |
instruction.blocks.Add(new ExceptionBlock(ExceptionBlockType.BeginCatchBlock)); // add try/catch boundaries | |
} | |
yield return instruction; | |
} | |
yield return ...; // add new codes after | |
// alternative 2 - convert to list | |
// | |
var list = instructions.ToList(); | |
// search in list (to find existing local variable for example) | |
var index = list.FindIndex(instr => instr.opcode == OpCodes.Ldloc); | |
var someLocal = list[index].operand; // LocalBuilder object representing variable | |
// reuse someLocal here | |
// move existing labels | |
int idx = ...; | |
var someLabels = list[idx].labels; | |
list[idx].labels.Clear(); | |
list.Insert(idx, new CodeInstruction(OpCodes.Nop) { labels = someLabels }); | |
list[idx].labels.AddRange(someLabels); | |
return list.AsEnumerable(); | |
// alternative 3 - abort and dont modify | |
// | |
if (...) | |
return null; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment