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 InvokeMethod(this ILGenerator il, ILPointer instance, string methodName, params ILPointer[] parameters) { var call = ILSnippet.Call(instance, methodName, parameters); il.Generate(call); }
public static void InvokeMethod(this ILGenerator il, MethodInfo method, params ILPointer[] parameters) { var call = ILSnippet.Call(method, parameters); il.Generate(call); }