Example #1
0
        void IILCode.Generate(ILExpressed il)
        {
            var variableType = il.TypeCache.Extend(_enumerable.ParameterType);
            var collectionContainer = variableType.Container.AsCollection();

            if (collectionContainer == null)
                throw new InvalidOperationException("Could not enumerate the type " + variableType.Ref.FullName);

            var elementType = collectionContainer.ElementType;
            il.Var.Load(_enumerable);

            var enumerableType = typeof(IEnumerable<>).MakeGenericType(elementType);
            var getEnumeratorMethod = enumerableType.GetMethod("GetEnumerator");
            il.CallVirt(getEnumeratorMethod);

            var enumeratorType = typeof(IEnumerator<>).MakeGenericType(elementType);
            var itLocal = il.DeclareLocal("it", enumeratorType);
            il.Var.Set(itLocal);

            il.Try();

            var itHeadLabel = il.DefineLabel();
            var itBodyLabel = il.DefineLabel();
            il.TransferLong(itHeadLabel);
            var itVarLocal = il.DeclareLocal("cv", elementType);
            var getCurrentMethod = enumeratorType.GetProperty("Current").GetGetMethod();
            il.MarkLabel(itBodyLabel);
            il.Var.Load(itLocal);
            il.Call(getCurrentMethod);
            il.Var.Set(itVarLocal);

            _iterateBody.Invoke(il, itVarLocal);

            il.MarkLabel(itHeadLabel);
            il.Var.Load(itLocal);
            il.CallVirt(EnumeratorMoveNext);

            il.TransferLongIfTrue(itBodyLabel);

            il.Finally();
            il.Var.Load(itLocal);
            il.LoadNull();
            il.CompareEquals();

            var endLabel = il.DefineLabel();
            il.TransferLongIfTrue(endLabel);

            il.Var.Load(itLocal);
            il.CallVirt(DisposableDispose);

            il.MarkLabel(endLabel);
            il.EndTry();
        }
Example #2
0
        void IILCode.Generate(ILExpressed il)
        {
            var value = il.DeclareLocal("index", _initialValue.ParameterType);
            il.Snippets.SetVariable(value, _initialValue);

            var labelCondition = il.DefineLabel();
            il.TransferLong(labelCondition);

            var labelBody = il.DefineAndMarkLabel();
            _bodyHandler.Invoke(il, value);
            il.Snippets.Increment(value, _increment);

            il.MarkLabel(labelCondition);
            _conditionHandler.Invoke(il, value);

            il.TransferLongIfTrue(labelBody);
        }