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