private (LocalBuilder xDone, LocalBuilder yDone) EmitMoveNext(LocalBuilder xEnumerator, LocalBuilder yEnumerator, ILEmitter il)
        {
            // todo: 3. it's possible to use "not done" flag. it will simplify emitted code in _emitCheckIfLoopsAreDone.
            il.Ceq(CallMethod(_moveNextMethod, LoadCaller(xEnumerator)),
                   Ldc_I4(0),
                   out var xDone)
            .Ceq(CallMethod(_moveNextMethod, LoadCaller(yEnumerator)),
                 Ldc_I4(0),
                 out var yDone);

            return(xDone, yDone);
        }
Exemplo n.º 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));
            }
        }
Exemplo n.º 3
0
 private static void EmitCycleDetection(ILEmitter il, Type objectType) =>
     il.Ceq(Ldc_I4(0), Or(TryAdd(Arg.SetX, Arg.X, objectType), TryAdd(Arg.SetY, Arg.Y, objectType)))
       .Brfalse_S(out var next)
Exemplo n.º 4
0
 public ILEmitter Emit(ILEmitter il, Label _) => il.Ceq(_variable.Load(Arg.X), _variable.Load(Arg.Y));