protected override void EmitEnumerateCollection(ILGenerator il, Action <ILGenerator> emitLoad, EnumerateLoopBody emitLoopBody) { var loopStartLabel = il.DefineLabel(); var loopConditionLabel = il.DefineLabel(); var enumeratorVar = il.DeclareLocal( // IEnumerator<T> enumerator typeof(IEnumerator <>).MakeGenericType(ElementType)); emitLoad(il); // enumerator = value.GetEnumerator() il.Emit(OpCodes.Callvirt, getEnumeratorMethod); il.Emit(OpCodes.Stloc, enumeratorVar); il.Emit(OpCodes.Br, loopConditionLabel); // goto loopConditionLabel il.MarkLabel(loopStartLabel); // label loopStartLabel emitLoopBody(() => { il.Emit(OpCodes.Ldloc, enumeratorVar); il.Emit(OpCodes.Callvirt, getCurrentMethod); }); il.MarkLabel(loopConditionLabel); // label loopConditionLabel il.Emit(OpCodes.Ldloc, enumeratorVar); // if (i < (int)value.Length) il.Emit(OpCodes.Callvirt, moveNextMethod); // goto loopStartLabel il.Emit(OpCodes.Brtrue, loopStartLabel); }
protected abstract void EmitEnumerateCollection(ILGenerator il, Action <ILGenerator> emitLoad, EnumerateLoopBody loopBody);
protected override void EmitEnumerateCollection(ILGenerator il, Action <ILGenerator> emitLoad, EnumerateLoopBody loopBody) { var lengthVar = il.DeclareLocal(typeof(int)); emitLoad(il); il.Emit(OpCodes.Ldlen); il.Emit(OpCodes.Conv_I4); il.Emit(OpCodes.Stloc, lengthVar); il.EmitForLoop(lengthVar, (lil, iVar) => loopBody(() => { emitLoad(lil); lil.Emit(OpCodes.Ldloc, iVar); EmitLoadElement(lil); })); }