コード例 #1
0
        private void Loop(ILEmitter il, LocalBuilder xEnumerator, LocalBuilder yEnumerator, Label exitLoop)
        {
            il.DefineLabel(out var loopStart);

            using (il.LocalsScope()) {
                il.MarkLabel(loopStart);
                var(xDone, yDone) = EmitMoveNext(xEnumerator, yEnumerator, il);

                _emitCheckIfLoopsAreDone(il, xDone, yDone, exitLoop);
            }

            using (il.LocalsScope()) {
                var enumerators = new Dictionary <ushort, LocalBuilder>(2)
                {
                    [Arg.X] = xEnumerator,
                    [Arg.Y] = yEnumerator
                };

                var itemVariable   = new EnumerableItemVariable(_enumeratorType, _elementType, _getCurrentMethod, enumerators);
                var itemComparison = _resolver.GetComparisonEmitter(itemVariable);

                il.Emit(itemComparison.Emit(loopStart))
                .Emit(itemComparison.EmitCheckForResult(loopStart));
            }
        }
コード例 #2
0
        public ILEmitter EmitCompareArrays(
            ILEmitter il,
            Type arrayType,
            Type ownerType,
            LocalBuilder xArray,
            LocalBuilder yArray,
            Label afterLoop)
        {
            // todo: 2. compare array lengths at the beginning
            il.EmitArrayLength(arrayType, xArray, out var countX)
            .EmitArrayLength(arrayType, yArray, out var countY)
            .Ldc_I4(0)
            .Stloc(typeof(int), out var index)
            .DefineLabel(out var loopStart)
            .DefineLabel(out var continueLoop)
            .MarkLabel(loopStart);

            using (il.LocalsScope()) {
                il.Ceq(Ldloc(index), Ldloc(countX), out var isDoneX)
                .Ceq(Ldloc(index), Ldloc(countY), out var isDoneY);
                _emitCheckIfLoopsAreDone(il, isDoneX, isDoneY, afterLoop);
            }

            using (il.LocalsScope()) {
                var arrays = new Dictionary <ushort, LocalBuilder>(2)
                {
                    [Arg.X] = xArray,
                    [Arg.Y] = yArray
                };
                var itemVariable   = new ArrayItemVariable(arrayType, ownerType, arrays, index);
                var itemComparison = _resolver.GetComparisonEmitter(itemVariable);

                return(il.Emit(
                           itemComparison.Emit(continueLoop),
                           itemComparison.EmitCheckForResult(continueLoop))
                       .MarkLabel(continueLoop)
                       .Add(Ldloc(index), Ldc_I4(1))
                       .Stloc(index)
                       .Br(loopStart));
            }
        }
コード例 #3
0
        public ILEmitter Emit(ILEmitter il, Label gotoNext)
        {
            var variableType = _variable.VariableType;

            _variable.Load(il, Arg.X).Stloc(variableType, out var nullableX);
            _variable.Load(il, Arg.Y).Stloc(variableType, out var nullableY);

            var isMember = !(_variable is ArgumentVariable);

            if (isMember)
            {
                _emitCheckNullablesForValue(il, LoadLocalAddress(nullableX), LoadLocalAddress(nullableY), variableType, gotoNext);
            }

            var nullableVariables = new NullableVariables(variableType, _variable.OwnerType, new Dictionary <int, LocalBuilder>(2)
            {
                [Arg.X] = nullableX,
                [Arg.Y] = nullableY
            });

            return(_resolver
                   .GetComparisonEmitter(nullableVariables)
                   .Emit(il, gotoNext));
        }