コード例 #1
0
        public ILEmitter Emit(ILEmitter il, LocalBuilder hash)
        {
            il.Emit(_variable.Load(Arg.Input))
            .Stloc(_variable.VariableType, out var enumerable)
            .DefineLabel(out var end);

            if (!_variable.VariableType.IsValueType)
            {
                il.Brtrue_S(Ldloc(enumerable), out var begin)
                .Ldc_I4(0)
                .Br(end)
                .MarkLabel(begin);
            }

            if (_configuration.Get(_variable.OwnerType).IgnoreCollectionOrder)
            {
                return(EmitHashAsSortedArray(il, enumerable, hash).MarkLabel(end));
            }

            il.CallMethod(_getEnumeratorMethod, LoadCaller(enumerable))
            .Stloc(_enumeratorType, out var enumerator)
            .DefineLabel(out var loopStart);

            if (!_enumeratorType.IsValueType)
            {
                il.Brtrue_S(Ldloc(enumerator), loopStart)
                .Ldc_I4(0)
                .Br(end);
            }

            // todo: 1. think how to use try/finally block
            // the problem now with the inner `return` statements, it has to be `leave` instruction
            //il.BeginExceptionBlock();

            Loop(il, enumerator, loopStart, hash);

            //il.BeginFinallyBlock();
            EmitDisposeEnumerator(il, enumerator);

            //il.EndExceptionBlock();

            return(il.Ldloc(hash).MarkLabel(end));
        }
コード例 #2
0
 private static void EmitCycleDetection(ILEmitter il, Type objectType) =>
 il.Brtrue_S(TryAdd(Arg.CycleSet, Arg.Input, objectType), out var next)
 .Emit(GetCount(Arg.CycleSet))
 .Stloc(typeof(int), out var count)
 .Ret(CallMethod(_getHashCodeMethod, LoadCaller(count)))
 .MarkLabel(next);