public static void GenerateLoop(GenerationContextBase context, LocalBuilder countLocal, LocalBuilder loopControlLocal, Action loopAction, bool reversed = false) { var loopLabel = context.Generator.DefineLabel(); var loopFinishLabel = context.Generator.DefineLabel(); if (reversed) { context.Generator.PushLocalValueOntoStack(countLocal); context.Generator.PushIntegerOntoStack(1); context.Generator.Emit(OpCodes.Sub); // put <<countLocal>> - 1 on stack } else { context.Generator.PushIntegerOntoStack(0); // put <<0> on stack } context.Generator.StoreLocalValueFromStack(loopControlLocal); // initialize <<loopControl>> variable using value from stack context.Generator.MarkLabel(loopLabel); context.Generator.PushLocalValueOntoStack(loopControlLocal); if (reversed) { context.Generator.PushIntegerOntoStack(-1); } else { context.Generator.PushLocalValueOntoStack(countLocal); } context.Generator.Emit(OpCodes.Beq, loopFinishLabel); loopAction(); context.Generator.PushLocalValueOntoStack(loopControlLocal); context.Generator.PushIntegerOntoStack(reversed ? -1 : 1); context.Generator.Emit(OpCodes.Add); context.Generator.StoreLocalValueFromStack(loopControlLocal); // change <<loopControl>> variable by one context.Generator.Emit(OpCodes.Br, loopLabel); // jump to the next loop iteration context.Generator.MarkLabel(loopFinishLabel); }
public static void GenerateLoop(GenerationContextBase context, LocalBuilder countLocal, Action <LocalBuilder> loopAction, bool reversed = false) { var loopControlLocal = context.Generator.DeclareLocal(typeof(int)); GenerateLoop(context, countLocal, loopControlLocal, () => loopAction(loopControlLocal), reversed); }