Example #1
0
        protected override void OnGenerate(ILGenerator il)
        {
            var loopConditionLabel = il.NewLabel();
            var loopBodyLabel      = il.NewLabel();

            loopConditionLabel.TransferLong();
            loopBodyLabel.Mark();
            _bodyHandler.Invoke(il);

            loopConditionLabel.Mark();
            _conditionHandler.Invoke(il);

            loopBodyLabel.TransferLongIfTrue();
        }
Example #2
0
        protected override void OnGenerate(ILGenerator il)
        {
            var value = il.NewLocal(_initialValue.Type);

            il.Set(value, _initialValue);

            var labelCondition = il.NewLabel();

            labelCondition.TransferLong();

            var labelBody = il.NewLabel().Mark();

            _bodyHandler.Invoke(il, value);
            il.Increment(value, _increment);

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

            labelBody.TransferLongIfTrue();
        }
Example #3
0
        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();
        }