protected override void OnGenerate(ILGenerator il) { if (!_enumerable.Type.TryGetInterface(typeof(IEnumerable <>), out var enumerableType)) { throw new InvalidOperationException("Could not enumerate the type " + _enumerable.Type.FullName); } var getEnumerator = ILSnippet.Call(_enumerable, enumerableType.GetRuntimeMethod("GetEnumerator", Type.EmptyTypes)); var elementType = enumerableType.GetTypeInfo().GetGenericArguments()[0]; var itLocal = il.NewLocal(getEnumerator.ReturnType); il.Set(itLocal, getEnumerator); il.Try(() => { var itHeadLabel = il.NewLabel(); var itBodyLabel = il.NewLabel(); itHeadLabel.TransferLong(); var itVarLocal = il.NewLocal(elementType); itBodyLabel.Mark(); il.Set(itVarLocal, ILPointer.Property(itLocal, "Current")); _iterateBody.Invoke(il, itVarLocal); itHeadLabel.Mark(); il.InvokeMethod(itLocal, EnumeratorMoveNext); itBodyLabel.TransferLongIfTrue(); }) .Finally(() => { var endLabel = il.NewLabel(); endLabel.TransferIfNull(itLocal); il.InvokeMethod(itLocal, DisposableDispose); endLabel.Mark(); }) .End(); }
public static void Set(this ILGenerator il, ILPointer instance, PropertyInfo property, ILPointer value) { var p = ILPointer.Property(instance, property); il.Set(p, value); }