private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, TypeReference comparer, TypeReference func)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("comparer", ParameterAttributes.None, func));
            method.DefineAllocatorParam();

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));
            body.Variables.Add(new VariableDefinition(comparer));

            body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldloca_S, body.Variables[0]))
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LoadFuncArgumentAndStoreToLocalVariableField(1, 1)

            .LdLocA(0)
            .LdLocA(1)
            .LdArg(2)
            .NewObj(method.ReturnType.FindMethod(".ctor", 3))
            .Ret();
        }
        private static void GenerateSpecial(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, TypeReference func, TypeReference TKeySelector)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("keySelector", ParameterAttributes.None, func));
            var allocator = new ParameterDefinition("allocator", ParameterAttributes.HasDefault | ParameterAttributes.Optional, Helper.Allocator)
            {
                Constant = 2,
            };
            method.Parameters.Add(allocator);

            var body = method.Body;
            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));
            body.Variables.Add(new VariableDefinition(TKeySelector));

            body.GetILProcessor()
                .LdLocA(0)
                .LdArg(0)
                .Call(enumerable.FindMethod(".ctor", 1))

                .LoadFuncArgumentAndStoreToLocalVariableField(1, 1)

                .LdLocA(0)
                .LdLocA(1)
                .LdArg(2)
                .NewObj(method.ReturnType.FindMethod(".ctor", 3))
                .Ret();
        }
        private static void GenerateNativeArray(MethodDefinition method, TypeReference enumerable, GenericParameter T, TypeReference TOperator, GenericInstanceType equatable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(enumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.In, new ByReferenceType(T))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.In, new ByReferenceType(TOperator))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Int32));
            body.Variables.Add(new VariableDefinition(T));

            var loopStart = Instruction.Create(OpCodes.Ldarg_2);
            var @return   = InstructionUtility.LoadConstant(true);

            var getLength = enumerable.FindMethod("get_Length");

            body.GetILProcessor()
            .LdArg(0)
            .Call(getLength)
            .BrTrueS(loopStart)

            .LdC(false)
            .Ret()

            .Add(loopStart)
            .LdArg(1)
            .LdArg(0)
            .LdLoc(0)
            .Call(enumerable.FindMethod("get_Item"))
            .StLoc(1)
            .LdLocA(1)
            .Constrained(TOperator)
            .CallVirtual(equatable.FindMethod("Calc"))
            .BrTrueS(@return)

            .LdLoc(0)
            .LdC(1)
            .Add()
            .Dup()
            .StLoc(0)
            .LdArg(0)
            .Call(getLength)
            .BltS(loopStart)

            .LdC(false)
            .Ret()

            .Add(@return)
            .Ret();
        }
Exemple #4
0
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericInstanceType KeyFunc, TypeReference TKeyFunc, TypeReference ElementFunc, TypeReference TElementFunc, TypeReference Comparer, TypeReference TComparer)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("keySelector", ParameterAttributes.None, KeyFunc));
            method.Parameters.Add(new ParameterDefinition("elementSelector", ParameterAttributes.None, ElementFunc));
            method.Parameters.Add(new ParameterDefinition("equalityComparer", ParameterAttributes.None, Comparer));
            method.DefineAllocatorParam();
            method.DefineGroupByDisposeOptions();

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));
            body.Variables.Add(new VariableDefinition(TKeyFunc));
            body.Variables.Add(new VariableDefinition(TElementFunc));
            body.Variables.Add(new VariableDefinition(TComparer));

            body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldloca_S, body.Variables[0]))
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LoadFuncArgumentAndStoreToLocalVariableField(1, 1)
            .LoadFuncArgumentAndStoreToLocalVariableField(2, 2)
            .LoadFuncArgumentAndStoreToLocalVariableField(3, 3)

            .LdLocA(0)
            .LdLocA(1)
            .LdLocA(2)
            .LdLocA(3)
            .LdArg(4)
            .LdArg(5)
            .NewObj(method.ReturnType.FindMethod(".ctor", 6))
            .Ret();
        }
Exemple #5
0
        private static void GenerateNativeArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericInstanceType KeyFunc, TypeReference TKeyFunc)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("keySelector", ParameterAttributes.None, KeyFunc));
            method.DefineAllocatorParam();
            method.DefineGroupByDisposeOptions();

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));
            body.Variables.Add(new VariableDefinition(TKeyFunc));

            body.GetILProcessor()
            .LdLocA(0)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LoadFuncArgumentAndStoreToLocalVariableField(1, 1)

            .LdLocA(0)
            .LdLocA(1)
            .LdArg(2)
            .LdArg(3)
            .NewObj(method.ReturnType.FindMethod(".ctor", 4))
            .Ret();
        }
        private static void GenerateSpecial(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericParameter T, TypeReference equalityComparer)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("comparer", ParameterAttributes.In, new ByReferenceType(equalityComparer))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.DefineAllocatorParam();

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));

            body.GetILProcessor()
            .LdLocA(0)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LdLocA(0)
            .LdArg(1)
            .LdArg(2)
            .NewObj(method.ReturnType.FindMethod(".ctor", 3))
            .Ret();
        }
        private static void GenerateSpecial(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericParameter T, TypeReference equalityComparer, TypeReference comparerParamType)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("comparer", ParameterAttributes.None, comparerParamType));
            method.DefineAllocatorParam();

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));
            body.Variables.Add(new VariableDefinition(equalityComparer));

            body.GetILProcessor()
            .LdLocA(0)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LoadFuncArgumentAndStoreToLocalVariableField(1, 1)

            .LdLocA(0)
            .LdLocA(1)
            .LdArg(2)
            .NewObj(method.ReturnType.FindMethod(".ctor", 3))
            .Ret();
        }
Exemple #8
0
        private static void GenerateSpecial(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, TypeReference T)
        {
            var constructor = method.ReturnType.FindMethod(".ctor");

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("count", ParameterAttributes.None, method.Module.TypeSystem.Int64));
            if (constructor.Parameters.Count == 3)
            {
                method.DefineAllocatorParam();
            }

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));

            body.GetILProcessor()
            .LdLocA(0)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LdLocA(0)
            .LdArgs(1, method.Parameters.Count - 1)
            .NewObj(constructor)
            .Ret();
        }
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Void)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var action = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "RefAction`1"))
            {
                GenericArguments = { T }
            };

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("action", ParameterAttributes.None, action));

            var body = method.Body;

            body.InitLocals = true;
            var variables = body.Variables;

            variables.Add(new VariableDefinition(TEnumerator));
            variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));
            variables.Add(new VariableDefinition(new ByReferenceType(T)));

            var closing   = Instruction.Create(OpCodes.Ldloca_S, variables[0]);
            var loopStart = Instruction.Create(OpCodes.Ldloca_S, variables[0]);

            body.GetILProcessor()
            .LdArg(0)
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(1)
            .TryGetNextEnumerator(TEnumerator)
            .StLoc(2)
            .LdLoc(1)
            .BrFalseS(closing)

            .LdArg(1)
            .LdLoc(2)
            .CallVirtual(action.FindMethod("Invoke"))
            .BrS(loopStart)

            .Add(closing)
            .DisposeEnumerator(TEnumerator)
            .Ret();
        }
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule, ModuleDefinition systemModule)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var TFunc = new GenericInstanceType(mainModule.ImportReference(systemModule.GetType("System", "Func`2")))
            {
                GenericArguments = { T, mainModule.TypeSystem.Boolean }
            };

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.IsReadOnlyAttribute }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, TFunc));

            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);

            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var loopStart = Instruction.Create(OpCodes.Ldarg_1);


            body.GetILProcessor()
            .ArgumentNullCheck(1, Instruction.Create(OpCodes.Ldarg_0))
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .BrS(condition)
            .Add(loopStart)
            .LdLocA(0)
            .GetCurrentEnumerator(TEnumerator)
            .LdObj(T)
            .CallVirtual(TFunc.FindMethod("Invoke", 1))
            .BrTrueS(condition)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(false)
            .Ret()
            .Add(condition)
            .MoveNextEnumerator(TEnumerator)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(true)
            .Ret();
        }
Exemple #11
0
        private static void GenerateNativeArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));

            method.Body.GetILProcessor()
            .LdArg(0)
            .NewObj(enumerable.FindMethod(".ctor", 1))
            .Ret();
        }
        private static void GenerateNormal(MethodDefinition method, TypeReference enumerable, TypeReference enumerator, GenericParameter T, GenericInstanceType Func)
        {
            var body = method.Body;

            body.InitLocals = true;
            var enumeratorVariable = new VariableDefinition(enumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));

            var loopStart = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var @return   = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var fail      = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            var Dispose = enumerator.FindMethod("Dispose", 0);

            body.GetILProcessor()
            .ArgumentNullCheck(2, Instruction.Create(OpCodes.Ldarg_0))
            .Call(enumerable.FindMethod("GetEnumerator", 0))
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(3)
            .Call(enumerator.FindMethod("TryGetNext"))
            .StLoc(1)
            .LdLoc(3)
            .BrFalseS(@return)

            .LdArg(2)
            .LdLoc(1)
            .LdObj(T)
            .CallVirtual(Func.FindMethod("Invoke"))
            .BrFalseS(loopStart)

            .LdLoc(2)
            .BrTrueS(fail)

            .LdArg(1)
            .LdLoc(1)
            .CpObj(T)
            .LdC(true)
            .StLoc(2)
            .BrS(loopStart)

            .Add(fail)
            .Call(Dispose)
            .LdC(false)
            .Ret()

            .Add(@return)
            .Call(Dispose)
            .LdLoc(2)
            .Ret();
        }
Exemple #13
0
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));

            var body = method.Body;

            body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldarg_0))
            .NewObj(enumerable.FindMethod(".ctor", 1))
            .Ret();
        }
        private static void GenerateNormal(MethodDefinition method, GenericParameter T, TypeReference enumerable, TypeReference enumerator, TypeReference TOperator, GenericInstanceType equatable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(enumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.In, new ByReferenceType(T))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.In, new ByReferenceType(TOperator))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var body = method.Body;

            body.InitLocals = true;
            var enumeratorVariable = new VariableDefinition(enumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(T));

            var loopStart = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var fail      = InstructionUtility.LoadConstant(false);
            var dispose   = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            body.GetILProcessor()
            .LdArg(0)
            .Call(enumerable.FindMethod("GetEnumerator", 0))
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(1)
            .Call(enumerator.FindMethod("TryMoveNext"))
            .BrFalseS(fail)

            .LdArg(2)
            .LdArg(1)
            .LdLocA(1)
            .Constrained(TOperator)
            .CallVirtual(equatable.FindMethod("Calc"))
            .BrFalseS(loopStart)

            .LdC(true)
            .BrS(dispose)

            .Add(fail)
            .Add(dispose)
            .Call(enumerator.FindMethod("Dispose", 0))
            .Ret();
        }
        private static void GenerateArray(MethodDefinition method, TypeReference enumerable, GenericParameter T, GenericInstanceType equatable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, enumerable));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.In, new ByReferenceType(T))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });


            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.IntPtr));

            var loopStart = Instruction.Create(OpCodes.Ldarg_1);
            var @return   = InstructionUtility.LoadConstant(true);

            body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldarg_0))
            .LdLen()
            .BrTrueS(loopStart)

            .LdC(false)
            .Ret()

            .Add(loopStart)
            .LdArg(0)
            .LdLoc(0)
            .LdElem(T)
            .Constrained(T)
            .CallVirtual(equatable.FindMethod("Equals"))
            .BrTrueS(@return)

            .LdLoc(0)
            .LdC(1)
            .Add()
            .Dup()
            .StLoc(0)
            .LdArg(0)
            .LdLen()
            .BltS(loopStart)

            .LdC(false)
            .Ret()

            .Add(@return)
            .Ret();
        }
        private void GenerateEach(string name, bool isSpecial, TypeDefinition @static, ModuleDefinition mainModule, TypeReference returnTypeReference)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var T = method.DefineUnmanagedGenericParameter();

            method.GenericParameters.Add(T);
            TypeReference IRefFunc = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "IRefFunc`2"))
            {
                GenericArguments = { T, returnTypeReference }
            };
            var TOperator = new GenericParameter("TOperator", method)
            {
                HasNotNullableValueTypeConstraint = true,
                Constraints = { IRefFunc }
            };

            method.GenericParameters.Add(TOperator);
            var Calc = IRefFunc.FindMethod("Calc");

            if (isSpecial)
            {
                var(baseEnumerable, _, _) = T.MakeSpecialTypePair(name);
                switch (name)
                {
                case "T[]":
                    GenerateArray(mainModule, method, returnTypeReference, baseEnumerable, T, TOperator, Calc);
                    break;

                case "NativeArray<T>":
                    GenerateNativeArray(mainModule, method, returnTypeReference, baseEnumerable, T, TOperator, Calc);
                    break;

                default: throw new NotSupportedException(name);
                }
            }
            else
            {
                GenerateNormal(method, Dictionary[name], returnTypeReference, T, TOperator, Calc);
            }
        }
        private static void GenerateSpecial(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, TypeReference selector)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));

            body.GetILProcessor()
            .LdLocA(0)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LdLocA(0)
            .NewObj(method.ReturnType.FindMethod(".ctor", 1))
            .Ret();
        }
        private void GenerateEach(string name, bool isSpecial, TypeDefinition @static, ModuleDefinition mainModule, ModuleDefinition systemModule, TypeReference returnTypeReference)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var T = method.DefineUnmanagedGenericParameter();

            method.GenericParameters.Add(T);
            var Func = new GenericInstanceType(mainModule.ImportReference(systemModule.GetType("System", "Func`2")))
            {
                GenericArguments = { T, returnTypeReference }
            };
            var Invoke = Func.FindMethod("Invoke");

            if (isSpecial)
            {
                var(baseEnumerable, _, _) = T.MakeSpecialTypePair(name);
                switch (name)
                {
                case "T[]":
                    GenerateArray(mainModule, method, returnTypeReference, baseEnumerable, T, Func, Invoke);
                    break;

                case "NativeArray<T>":
                    GenerateNativeArray(mainModule, method, returnTypeReference, baseEnumerable, Func, Invoke);
                    break;

                default: throw new NotSupportedException(name);
                }
            }
            else
            {
                GenerateNormal(method, Dictionary[name], returnTypeReference, T, Func, Invoke);
            }
        }
Exemple #19
0
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericParameter T)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));

            var body = method.Body;

            body.InitLocals = true;
            var variables = body.Variables;

            variables.Add(new VariableDefinition(enumerable));
            variables.Add(new VariableDefinition(T));

            body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldloca_S, body.Variables[0]))
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LdLocA(0)
            .LdLocA(1)
            .NewObj(method.ReturnType.FindMethod(".ctor", 2))
            .Ret();
        }
Exemple #20
0
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericParameter predicate)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("predicate", ParameterAttributes.In, new ByReferenceType(predicate))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));

            body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldloca_S, body.Variables[0]))
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LdLocA(0)
            .LdArg(1)
            .NewObj(method.ReturnType.FindMethod(".ctor", 2))
            .Ret();
        }
Exemple #21
0
        private static void GenerateSpecial(MethodDefinition method, TypeReference baseEnumerable, GenericInstanceType enumerable, GenericInstanceType predicate, GenericInstanceType func)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("predicate", ParameterAttributes.None, func));

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(enumerable));
            body.Variables.Add(new VariableDefinition(predicate));

            body.GetILProcessor()
            .LdLocA(0)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor", 1))

            .LoadFuncArgumentAndStoreToLocalVariableField(1, 1)

            .LdLocA(0)
            .LdLocA(1)
            .NewObj(method.ReturnType.FindMethod(".ctor", 2))
            .Ret();
        }
        private static void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule)
        {
            var method = new MethodDefinition("Aggregate", Helper.StaticMethodAttributes, mainModule.TypeSystem.Void)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var genericParameters = method.GenericParameters;

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var TAccumulate = new GenericParameter("TAccumulate", method);

            genericParameters.Add(TAccumulate);

            var IRefAction = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "IRefAction`2"))
            {
                GenericArguments = { TAccumulate, T }
            };
            var TFunc = new GenericParameter("TFunc", method)
            {
                Constraints =
                {
                    IRefAction
                }
            };

            genericParameters.Add(TFunc);

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("accumulate", ParameterAttributes.None, new ByReferenceType(TAccumulate)));
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.In, new ByReferenceType(TFunc))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });


            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));

            var loopStart = Instruction.Create(OpCodes.Ldarg_2);
            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            body.GetILProcessor()
            .LdArg(0)
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .BrS(condition)
            .Add(loopStart)
            .LdArg(1)
            .LdLoc(2)
            .Constrained(TFunc)
            .CallVirtual(IRefAction.FindMethod("Execute"))
            .Add(condition)
            .LdLocA(1)
            .TryGetNextEnumerator(TEnumerator)
            .StLoc(2)
            .LdLoc(1)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .Ret();
        }
        private static void GenerateNativeArray(MethodDefinition method, TypeReference enumerable, GenericParameter T, GenericInstanceType Func)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(enumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, Func));

            var loopStart = Instruction.Create(OpCodes.Ldarg_0);
            var @return   = Instruction.Create(OpCodes.Ldloc_2);
            var fail      = InstructionUtility.LoadConstant(false);

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Int32));
            body.Variables.Add(new VariableDefinition(T));
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));

            var getLength = enumerable.FindMethod("get_Length");

            body.GetILProcessor()
            .ArgumentNullCheck(2, Instruction.Create(OpCodes.Ldarg_0))
            .Call(getLength)
            .BrTrueS(loopStart)

            .LdC(false)
            .Ret()

            .Add(loopStart)
            .Call(getLength)
            .LdLoc(0)
            .BleS(@return)

            .LdArg(2)
            .LdArg(0)
            .LdLoc(0)
            .Dup()
            .LdC(1)
            .Add()
            .StLoc(0)
            .Call(enumerable.FindMethod("get_Item"))
            .Dup()
            .StLoc(1)
            .CallVirtual(Func.FindMethod("Invoke"))
            .BrFalseS(loopStart)

            .LdLoc(2)
            .BrTrueS(fail)

            .LdArg(1)
            .LdLocA(1)
            .CpObj(T)
            .LdC(true)
            .StLoc(2)
            .BrS(loopStart)

            .Add(fail)
            .Ret()

            .Add(@return)
            .Ret();
        }
Exemple #24
0
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var IRefFunc2 = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "IRefFunc`2"))
            {
                GenericArguments = { T, mainModule.TypeSystem.Boolean }
            };
            var TOperator = method.DefineUnmanagedGenericParameter("TOperator");

            TOperator.Constraints.Add(IRefFunc2);
            method.GenericParameters.Add(TOperator);

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.IsReadOnlyAttribute }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.In, new ByReferenceType(TOperator))
            {
                CustomAttributes = { Helper.IsReadOnlyAttribute }
            });

            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);

            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var loopStart = Instruction.Create(OpCodes.Ldarg_1);


            body.GetILProcessor()
            .LdArg(0)
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .BrS(condition)
            .Add(loopStart)
            .LdLocA(0)
            .GetCurrentEnumerator(TEnumerator)
            .Constrained(TOperator)
            .CallVirtual(IRefFunc2.FindMethod("Calc"))
            .BrTrueS(condition)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(false)
            .Ret()
            .Add(condition)
            .MoveNextEnumerator(TEnumerator)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(true)
            .Ret();
        }
Exemple #25
0
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule, ModuleDefinition systemModule)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var TPredicate = new GenericInstanceType(mainModule.ImportReference(systemModule.GetType("System", "Func`2")))
            {
                GenericArguments = { T, mainModule.TypeSystem.Boolean }
            };

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));
            method.Parameters.Add(new ParameterDefinition("predicate", ParameterAttributes.None, TPredicate));

            var body = method.Body;

            body.InitLocals = true;
            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));

            var loopStart = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var fail      = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);


            body.GetILProcessor()
            .ArgumentNullCheck(2, Instruction.Create(OpCodes.Ldarg_0))
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(1)
            .TryGetNextEnumerator(TEnumerator)
            .StLoc(2)

            .LdLoc(1)
            .BrFalseS(fail)

            .LdArg(2)
            .LdLoc(2)
            .LdObj(T)
            .CallVirtual(TPredicate.FindMethod("Invoke"))
            .BrFalseS(loopStart)

            .LdArg(1)
            .LdLoc(2)
            .CpObj(T)

            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)

            .LdC(true)
            .Ret()

            .Add(fail)
            .DisposeEnumerator(TEnumerator)
            .LdC(false)
            .Ret();
        }
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule, ModuleDefinition systemModule, TypeReference returnTypeReference)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var Func = new GenericInstanceType(mainModule.ImportReference(systemModule.GetType("System", "Func`2")))
            {
                GenericArguments = { T, returnTypeReference }
            };
            var Invoke = Func.FindMethod("Invoke");

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.IsReadOnlyAttribute }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(returnTypeReference)));
            method.Parameters.Add(new ParameterDefinition("operator", ParameterAttributes.None, Func));

            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(returnTypeReference));
            body.Variables.Add(new VariableDefinition(T));
            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var loopStart = Instruction.Create(OpCodes.Ldarg_1);
            var shortJump = Instruction.Create(OpCodes.Ldarg_1);

            body.GetILProcessor()
            .ArgumentNullCheck(2, Instruction.Create(OpCodes.Ldarg_0))
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .LdLocA(0)
            .LdLocA(2)
            .TryMoveNextEnumerator(TEnumerator)
            .BrTrueS(shortJump)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(false)
            .Ret()
            .Add(shortJump)
            .LdArg(2)
            .LdLoc(2)
            .CallVirtual(Invoke)
            .StObj(returnTypeReference)
            .BrS(condition)
            .Add(loopStart)
            .LdArg(2)
            .LdLoc(2)
            .CallVirtual(Invoke)
            .StLoc(1)
            .Add(Instruction.Create(OpCodeLdInd))
            .LdLoc(1)
            .Add(Instruction.Create(isMax ? OpCodeBgeS : OpCodeBleS, condition))
            .LdArg(1)
            .LdLocA(1)
            .CpObj(returnTypeReference)
            .Add(condition)
            .LdLocA(2)
            .TryMoveNextEnumerator(TEnumerator)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(true)
            .Ret();
        }
Exemple #27
0
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var predicate = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "IRefFunc`2"))
            {
                GenericArguments = { T, mainModule.TypeSystem.Boolean }
            };

            var TPredicate = method.DefineUnmanagedGenericParameter("TPredicate");

            TPredicate.Constraints.Add(predicate);
            method.GenericParameters.Add(TPredicate);

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));
            method.Parameters.Add(new ParameterDefinition("TPredicate", ParameterAttributes.In, new ByReferenceType(TPredicate))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var body = method.Body;

            body.InitLocals = true;
            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(T));
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));

            var loopStart = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var @return   = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            body.GetILProcessor()
            .LdArg(0)
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(1)
            .TryMoveNextEnumerator(TEnumerator)
            .BrFalseS(@return)

            .LdArg(2)
            .LdLocA(1)
            .Constrained(TPredicate)
            .CallVirtual(predicate.FindMethod("Calc"))
            .BrFalseS(loopStart)

            .LdC(true)
            .StLoc(2)

            .LdArg(1)
            .LdLocA(1)
            .CpObj(T)
            .BrS(loopStart)

            .Add(@return)
            .DisposeEnumerator(TEnumerator)
            .LdLoc(2)
            .Ret();
        }
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule)
        {
            var method = new MethodDefinition(Api.Name, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var IEquatable = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "IRefFunc`3"))
            {
                GenericArguments = { T, T, mainModule.TypeSystem.Boolean }
            };
            var TOperator = new GenericParameter("TOperator", method)
            {
                HasNotNullableValueTypeConstraint = true,
                Constraints = { IEquatable }
            };

            method.GenericParameters.Add(TOperator);

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.In, new ByReferenceType(T))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.In, new ByReferenceType(TOperator))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var body = method.Body;

            body.InitLocals = true;
            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(T));

            var loopStart = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var fail      = InstructionUtility.LoadConstant(false);
            var dispose   = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            body.GetILProcessor()
            .LdArg(0)
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(1)
            .TryMoveNextEnumerator(TEnumerator)
            .BrFalseS(fail)

            .LdArg(2)
            .LdArg(1)
            .LdLocA(1)
            .Constrained(TOperator)
            .CallVirtual(IEquatable.FindMethod("Calc"))
            .BrFalseS(loopStart)

            .LdC(true)
            .BrS(dispose)

            .Add(fail)
            .Add(dispose)
            .DisposeEnumerator(TEnumerator)
            .Ret();
        }
        private static void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule, ModuleDefinition systemModule)
        {
            var method = new MethodDefinition("Aggregate", Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var genericParameters = method.GenericParameters;

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var TAccumulate = new GenericParameter("TAccumulate", method);

            genericParameters.Add(TAccumulate);

            var TResult = new GenericParameter("TResult", method);

            genericParameters.Add(TResult);
            method.ReturnType = TResult;

            var TFunc = new GenericInstanceType(mainModule.ImportReference(systemModule.GetType("System", "Func`3")))
            {
                GenericArguments = { TAccumulate, T, TAccumulate }
            };

            var TResultFunc = new GenericInstanceType(mainModule.ImportReference(systemModule.GetType("System", "Func`2")))
            {
                GenericArguments = { TAccumulate, TResult }
            };

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            var paramAccumulate = new ParameterDefinition("accumulate", ParameterAttributes.None, TAccumulate);

            method.Parameters.Add(paramAccumulate);
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, TFunc));
            method.Parameters.Add(new ParameterDefinition("resultFunc", ParameterAttributes.None, TResultFunc));

            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(T));

            var loopStart = Instruction.Create(OpCodes.Ldarg_2);
            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            body.GetILProcessor()
            .ArgumentNullCheck(2, 3, Instruction.Create(OpCodes.Ldarg_0))
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .BrS(condition)
            .Add(loopStart)
            .LdArg(1)
            .LdLoc(1)
            .CallVirtual(TFunc.FindMethod("Invoke"))
            .StArgS(paramAccumulate)
            .Add(condition)
            .LdLocA(1)
            .TryMoveNextEnumerator(TEnumerator)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdArg(3)
            .LdArg(1)
            .CallVirtual(TResultFunc.FindMethod("Invoke"))
            .Ret();
        }
        private void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule, TypeReference returnTypeReference)
        {
            var method = new MethodDefinition(Api.Name + processType, Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            TypeReference IRefFunc = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "IRefFunc`2"))
            {
                GenericArguments = { T, returnTypeReference }
            };
            var TOperator = new GenericParameter("TOperator", method)
            {
                HasNotNullableValueTypeConstraint = true,
                Constraints = { IRefFunc }
            };

            method.GenericParameters.Add(TOperator);
            var Calc = IRefFunc.FindMethod("Calc");

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.IsReadOnlyAttribute }
            });
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(returnTypeReference)));
            method.Parameters.Add(new ParameterDefinition("operator", ParameterAttributes.In, new ByReferenceType(TOperator))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(returnTypeReference));
            body.Variables.Add(new VariableDefinition(T));
            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);
            var loopStart = Instruction.Create(OpCodes.Ldarg_1);
            var shortJump = Instruction.Create(OpCodes.Ldarg_1);

            body.GetILProcessor()
            .LdArg(0)
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .LdLocA(0)
            .LdLocA(2)
            .TryMoveNextEnumerator(TEnumerator)
            .BrTrueS(shortJump)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(false)
            .Ret()
            .Add(shortJump)
            .LdArg(2)
            .LdLocA(2)
            .Constrained(TOperator)
            .CallVirtual(Calc)
            .StObj(returnTypeReference)
            .BrS(condition)
            .Add(loopStart)
            .LdArg(2)
            .LdLocA(2)
            .Constrained(TOperator)
            .CallVirtual(Calc)
            .StLoc(1)
            .Add(Instruction.Create(OpCodeLdInd))
            .LdLoc(1)
            .Add(Instruction.Create(isMax ? OpCodeBgeS : OpCodeBleS, condition))
            .LdArg(1)
            .LdLocA(1)
            .CpObj(returnTypeReference)
            .Add(condition)
            .LdLocA(2)
            .TryMoveNextEnumerator(TEnumerator)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdC(true)
            .Ret();
        }