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)); } }
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)); } }
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)); }