Beispiel #1
0
        private static void GenerateArray(ModuleDefinition mainModule, MethodDefinition method, TypeReference TFunc, GenericParameter T, TypeReference baseEnumerable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, TFunc));
            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(mainModule.TypeSystem.Int32));

            var loopStart = Instruction.Create(OpCodes.Ldloc_0);
            var next      = Instruction.Create(OpCodes.Ldloc_0);
            var retVal    = InstructionUtility.LoadConstant(IsAll);

            body.GetILProcessor()
            .ArgumentNullCheck(0, 1, loopStart)
            .LdArg(0)
            .LdLen()
            .ConvI4()
            .BgeS(retVal)
            .LdArg(1)
            .LdArg(0)
            .LdLoc(0)
            .LdElemAny(T)
            .CallVirtual(TFunc.FindMethod("Invoke", 1))
            .BrBoolS(next, IsAll)
            .LdC(!IsAll)
            .Ret()
            .Add(next)
            .LdC(1)
            .Add()
            .StLoc(0)
            .BrS(loopStart)
            .Add(retVal)
            .Ret();
        }
        private static void GenerateNativeArray(MethodDefinition method, TypeReference baseEnumerable, GenericParameter T)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(baseEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("index", ParameterAttributes.None, method.Module.TypeSystem.Int32));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));

            var fail     = InstructionUtility.LoadConstant(false);
            var notMinus = Instruction.Create(OpCodes.Ldarg_0);

            method.Body.GetILProcessor()
            .LdArg(1)
            .LdC(0)
            .BgeS(notMinus)

            .Add(fail)
            .Ret()

            .Add(notMinus)
            .Call(baseEnumerable.FindMethod("get_Length"))
            .LdArg(1)
            .BleS(fail)
            .Add(Instruction.Create(OpCodes.Nop))
            .LdArg(2)
            .LdArg(0)
            .LdArg(1)
            .Call(baseEnumerable.FindMethod("get_Item"))
            .StObj(T)

            .LdC(true)
            .Ret();
        }
        private static void GenerateArray(MethodDefinition method, TypeReference enumerable, TypeReference T, TypeReference Func)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, enumerable));
            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.IntPtr));
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));

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

            .LdC(false)
            .Ret()

            .Add(loopStart)
            .LdLen()
            .LdLoc(0)
            .BleS(@return)

            .LdArg(2)
            .LdArg(0)
            .LdLoc(0)
            .Dup()
            .LdC(1)
            .Add()
            .StLoc(0)
            .LdElemA(T)
            .Dup()
            .StLoc(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)
            .Ret()

            .Add(@return)
            .Ret();
        }
Beispiel #4
0
        private static void GenerateArray(MethodDefinition method, TypeReference enumerable, TypeReference T)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, enumerable));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));

            var fail = InstructionUtility.LoadConstant(false);

            method.Body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldarg_0))
            .LdLen()
            .LdC(1)
            .BneS(fail)

            .LdArg(1)
            .LdArg(0)
            .LdC(0)
            .LdElemA(T)
            .CpObj(T)

            .LdC(true)
            .Ret()

            .Add(fail)
            .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();
        }
Beispiel #6
0
        private static void GenerateNativeArray(MethodDefinition method, TypeReference enumerable, GenericParameter T)
        {
            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)));

            var fail = InstructionUtility.LoadConstant(false);

            method.Body.GetILProcessor()
            .LdArg(0)
            .Call(enumerable.FindMethod("get_Length"))
            .LdC(1)
            .BneS(fail)

            .LdArg(1)
            .LdArg(0)
            .LdC(0)
            .Call(enumerable.FindMethod("get_Item"))
            .StObj(T)

            .LdC(true)
            .Ret()

            .Add(fail)
            .Ret();
        }
Beispiel #7
0
        public static void GenerateSum_Array(this TypeReference returnType, MethodDefinition method, TypeReference baseEnumerable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            var body = method.Body;

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

            var condition = Instruction.Create(OpCodes.Ldloc_1);
            var loopStart = Instruction.Create(OpCodes.Ldloc_0);

            body.GetILProcessor()
            .ArgumentNullCheck(0, InstructionUtility.LoadConstant(0))
            .StLoc(1)
            .BrS(condition)
            .Add(loopStart)
            .LdArg(0)
            .LdLoc(1)
            .LdElem(returnType)
            .Add()
            .StLoc(0)
            .LdLoc(1)
            .LdC(1)
            .Add()
            .StLoc(1)
            .Add(condition)
            .LdArg(0)
            .LdLen()
            .ConvI4()
            .BltS(loopStart)
            .LdLoc(0)
            .Ret();
        }
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericParameter T)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("index", ParameterAttributes.None, method.Module.TypeSystem.Int64));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));

            var fail = InstructionUtility.LoadConstant(false);

            method.Body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldarg_1))
            .LdC(0L)
            .BltS(fail)

            .LdArg(0)
            .LdLen()
            .ConvI8()
            .LdArg(1)
            .BleS(fail)

            .LdArg(2)
            .LdArg(0)
            .LdArg(1)
            .LdElemA(T)
            .CpObj(T)

            .LdC(true)
            .Ret()

            .Add(fail)
            .Ret();
        }
Beispiel #9
0
        private static void GenerateNativeArray(MethodDefinition method, TypeReference baseEnumerable, TypeReference enumerable, GenericParameter T, TypeReference IEquatable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(method.Module.TypeSystem.Int32)));
            method.Parameters.Add(new ParameterDefinition("comparer", ParameterAttributes.None, T));

            var body = method.Body;

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

            var loopStart = Instruction.Create(OpCodes.Ldloca_S, body.Variables[2]);
            var success   = Instruction.Create(OpCodes.Ldarg_1);
            var fail      = InstructionUtility.LoadConstant(false);

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

            method.Body.GetILProcessor()
            .LdArgA(0)
            .Call(getLength)
            .BrFalseS(fail)

            .LdLocA(2)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor"))

            .Add(loopStart)
            .LdLoc(0)
            .Call(enumerable.FindMethod("get_Item"))
            .Dup()
            .StLoc(1)
            .LdArg(2)
            .Constrained(T)
            .CallVirtual(IEquatable.FindMethod("Equals"))
            .BrTrueS(success)

            .LdLoc(0)
            .LdC(1)
            .Add()
            .Dup()
            .StLoc(0)

            .LdArgA(0)
            .Call(getLength)
            .ConvI8()

            .BltS(loopStart)

            .Add(fail)
            .Ret()

            .Add(success)
            .LdLoc(0)
            .StObj(method.Module.TypeSystem.Int32)

            .LdC(true)
            .Ret();
        }
        private static void GenerateNativeArray(MethodDefinition method, TypeReference baseEnumerable, TypeReference enumerable, GenericParameter T, TypeReference TPredicate)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            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;
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Int64));
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));
            body.Variables.Add(new VariableDefinition(enumerable));

            var loopStart = Instruction.Create(OpCodes.Ldarg_2);
            var success   = Instruction.Create(OpCodes.Ldarg_1);
            var fail      = InstructionUtility.LoadConstant(false);

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

            method.Body.GetILProcessor()
            .ArgumentNullCheck(2, Instruction.Create(OpCodes.Ldarg_0))
            .Call(getLength)
            .BrFalseS(fail)

            .LdLocA(2)
            .LdArg(0)
            .Call(enumerable.FindMethod(".ctor"))

            .LdArgA(0)
            .Call(getLength)
            .ConvI8()
            .StLoc(0)

            .Add(loopStart)
            .LdLocA(2)
            .LdLoc(0)
            .LdC(1)
            .Sub()
            .Dup()
            .StLoc(0)
            .Call(enumerable.FindMethod("get_Item"))
            .Dup()
            .StLoc(1)
            .CallVirtual(TPredicate.FindMethod("Invoke"))
            .BrTrueS(success)

            .LdLoc(0)
            .BrTrueS(loopStart)

            .Add(fail)
            .Ret()

            .Add(success)
            .LdLoc(1)
            .CpObj(T)

            .LdC(true)
            .Ret();
        }
Beispiel #11
0
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericParameter T, TypeReference TPredicate, TypeReference predicate)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            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 loopStart = Instruction.Create(OpCodes.Ldarg_0);
            var success   = Instruction.Create(OpCodes.Ldarg_1);
            var fail      = InstructionUtility.LoadConstant(false);

            var body = method.Body;

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

            method.Body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldarg_0))
            .LdLen()
            .BrFalseS(fail)

            .LdArg(0)
            .LdLen()
            .StLoc(0)

            .Add(loopStart)
            .LdLoc(0)
            .LdC(1)
            .Sub()
            .Dup()
            .StLoc(0)
            .LdElemA(T)
            .StLoc(1)

            .LdArg(2)
            .LdLoc(1)
            .Constrained(TPredicate)
            .CallVirtual(predicate.FindMethod("Calc"))
            .BrTrueS(success)

            .LdLoc(0)

            .BrTrueS(loopStart)

            .Add(fail)
            .Ret()

            .Add(success)
            .LdLoc(1)
            .CpObj(T)

            .LdC(true)
            .Ret();
        }
        private static void GenerateNormalCanFastCount(MethodDefinition method, GenericParameter T, TypeReference enumerable, TypeReference enumerator, ParameterDefinition paramIndex)
        {
            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(enumerator);

            body.Variables.Add(enumeratorVariable);

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

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

            body.GetILProcessor()
            .LdArg(1)
            .LdC(0L)
            .BltS(fail)

            .LdArg(1)
            .LdArg(0)
            .Call(enumerable.FindMethod("LongCount"))
            .BgeS(fail)

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

            .Add(loopStart)
            .Call(enumerator.FindMethod("MoveNext"))
            .Pop()

            .LdArg(1)
            .LdC(0L)
            .BeqS(@return)

            .LdArg(1)
            .LdC(1L)
            .Sub()
            .StArgS(paramIndex)
            .BrS(loopStart)

            .Add(Instruction.Create(OpCodes.Nop))
            .Add(@return)
            .LdLocA(0)
            .Call(enumerator.FindMethod("get_Current"))
            .LdObj(T)
            .StObj(T)
            .LdLocA(0)
            .Call(dispose)
            .LdC(true)
            .Ret()

            .Add(fail)
            .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();
        }
Beispiel #14
0
        public static void SerializeFixedSizeBuffer(ILProcessor processor, ParameterDefinition valueParam, FieldReference fixedFieldImportedReference, ModuleDefinition module, MessagePackWriterHelper writer, FixedSizeBufferElementType elementType, int count, ref VariableDefinition notPinnedVariable)
#endif
        {
            var writingElement = writer.WriteMessagePackPrimitive(GetType(module, elementType));
            var ldInd          = LdInd(elementType);
            var stride         = SizeOf(elementType);

            processor.Append(Instruction.Create(OpCodes.Ldarg_1));                             // { writer }
            processor.Append(InstructionUtility.LdcI4(count));                                 // { writer, int32 }
            processor.Append(Instruction.Create(OpCodes.Call, writer.WriteArrayHeaderInt));    // { }

            processor.Append(Instruction.Create(OpCodes.Ldarg_1));                             // { writer }
            processor.Append(Instruction.Create(OpCodes.Ldarga_S, valueParam));                // { writer, value& }
            processor.Append(Instruction.Create(OpCodes.Ldflda, fixedFieldImportedReference)); // { writer, field& }
            processor.Append(Instruction.Create(OpCodes.Conv_U));                              // { writer, native uint }

            if (count == 1)
            {
                processor.Append(Instruction.Create(ldInd));                        // { writer, binary }
                processor.Append(Instruction.Create(OpCodes.Call, writingElement)); // { }
            }
            else
            {
                if (notPinnedVariable is null)
                {
                    notPinnedVariable = new VariableDefinition(module.TypeSystem.IntPtr);
                    processor.Body.Variables.Add(notPinnedVariable);
                }

                processor.Append(Instruction.Create(OpCodes.Dup));                  // { writer, native uint, native uint }
                processor.Append(InstructionUtility.Store(notPinnedVariable));      // { writer, native uint }
                processor.Append(Instruction.Create(ldInd));                        // { writer, binary }
                processor.Append(Instruction.Create(OpCodes.Call, writingElement)); // { }

                for (var i = 1; i < count; i++)
                {
                    processor.Append(Instruction.Create(OpCodes.Ldarg_1));        // { writer }
                    processor.Append(InstructionUtility.Load(notPinnedVariable)); // { writer, native uint }
                    processor.Append(InstructionUtility.LdcI4(stride));           // { writer, native uint, int32 }
                    processor.Append(Instruction.Create(OpCodes.Add));            // { writer, native uint }
                    if (i != count - 1)
                    {
                        processor.Append(Instruction.Create(OpCodes.Dup));             // { writer, native int, native int }
                        processor.Append(InstructionUtility.Store(notPinnedVariable)); // { writer, native int }
                    }

                    processor.Append(Instruction.Create(ldInd));                        // { writer, binary }
                    processor.Append(Instruction.Create(OpCodes.Call, writingElement)); // { }
                }
            }
        }
Beispiel #15
0
        private static void GenerateArray(MethodDefinition method, TypeReference enumerable, GenericParameter T, TypeReference TRefFunc)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, enumerable));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.In, new ByReferenceType(T))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, TRefFunc));

            var body = method.Body;

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

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

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

            .LdC(false)
            .Ret()

            .Add(loopStart)
            .LdArg(1)
            .LdArg(0)
            .LdLoc(0)
            .LdElemA(T)
            .CallVirtual(TRefFunc.FindMethod("Invoke"))
            .BrTrueS(@return)

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

            .LdC(false)
            .Ret()

            .Add(@return)
            .Ret();
        }
Beispiel #16
0
        private static void GenerateCanIndexAccess(MethodDefinition method, TypeReference enumerable, TypeReference TPredicate, TypeReference T)
        {
            var body = method.Body;

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

            var fail      = InstructionUtility.LoadConstant(false);
            var success   = Instruction.Create(OpCodes.Ldarg_1);
            var loopStart = Instruction.Create(OpCodes.Ldarg_2);

            body.GetILProcessor()
            .ArgumentNullCheck(2, Instruction.Create(OpCodes.Ldarg_0))
            .Call(enumerable.FindMethod("LongCount", 0))
            .Dup()
            .StLoc(0)
            .BrFalseS(fail)

            .Add(loopStart)
            .LdArg(0)
            .LdLoc(0)
            .LdC(1)
            .Sub()
            .Dup()
            .StLoc(0)
            .Call(enumerable.FindMethod("get_Item"))
            .LdObj(T)
            .CallVirtual(TPredicate.FindMethod("Invoke"))
            .BrTrueS(success)

            .LdLoc(0)
            .BrTrueS(loopStart)

            .Add(fail)
            .Ret()

            .Add(success)
            .LdArg(0)
            .LdLoc(0)
            .Call(enumerable.FindMethod("get_Item"))
            .CpObj(T)
            .LdC(true)
            .Ret();
        }
Beispiel #17
0
        private static void GenerateNativeArray(MethodDefinition method, TypeReference TFunc, TypeReference baseEnumerable)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(baseEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, TFunc));
            var body = method.Body;

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

            var loopStart = Instruction.Create(OpCodes.Ldloc_0);
            var next      = Instruction.Create(OpCodes.Ldloc_0);
            var retVal    = InstructionUtility.LoadConstant(IsAll);

            body.GetILProcessor()
            .ArgumentNullCheck(1, loopStart)
            .LdArg(0)
            .Call(baseEnumerable.FindMethod("get_Length"))
            .BgeS(retVal)
            .LdArg(1)
            .LdArg(0)
            .LdLoc(0)
            .Call(baseEnumerable.FindMethod("get_Item", 1))
            .CallVirtual(TFunc.FindMethod("Invoke", 1))
            .BrBoolS(next, IsAll)
            .LdC(!IsAll)
            .Ret()
            .Add(next)
            .LdC(1)
            .Add()
            .StLoc(0)
            .BrS(loopStart)
            .Add(retVal)
            .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 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();
        }
Beispiel #20
0
        public static Instruction[] DeserializeFixedSizeBuffer(VariableDefinition targetVariable, FieldDefinition fixedField, ModuleDefinition module, MessagePackReaderHelper reader, ModuleImporter importer, SystemInvalidOperationExceptionHelper invalidOperationExceptionHelper, FixedSizeBufferElementType elementType, int count)
        {
            var same   = Instruction.Create(OpCodes.Ldloca_S, targetVariable);
            var read   = reader.ReadMessagePackPrimitive(GetType(module, elementType));
            var stride = SizeOf(elementType);

            switch (count)
            {
            case 1:
                return(new[]
                {
                    Instruction.Create(OpCodes.Ldarg_1),
                    Instruction.Create(OpCodes.Call, reader.ReadArrayHeader),
                    InstructionUtility.LdcI4(count),
                    Instruction.Create(OpCodes.Beq_S, same),
                    Instruction.Create(OpCodes.Ldstr, "Fixed size buffer field should have " + count.ToString(CultureInfo.InvariantCulture) + " element(s)."),
                    Instruction.Create(OpCodes.Newobj, invalidOperationExceptionHelper.Ctor),
                    Instruction.Create(OpCodes.Throw),
                    same,
                    Instruction.Create(OpCodes.Ldflda, importer.Import(fixedField)),
                    Instruction.Create(OpCodes.Ldarg_1),
                    Instruction.Create(OpCodes.Call, read),
                    Instruction.Create(StInd(elementType)),
                });

            case 2:
                return(new[]
                {
                    Instruction.Create(OpCodes.Ldarg_1),
                    Instruction.Create(OpCodes.Call, reader.ReadArrayHeader),
                    InstructionUtility.LdcI4(count),
                    Instruction.Create(OpCodes.Beq_S, same),
                    Instruction.Create(OpCodes.Ldstr, "Fixed size buffer field should have " + count.ToString(CultureInfo.InvariantCulture) + " element(s)."),
                    Instruction.Create(OpCodes.Newobj, invalidOperationExceptionHelper.Ctor),
                    Instruction.Create(OpCodes.Throw),
                    same,
                    Instruction.Create(OpCodes.Ldflda, importer.Import(fixedField)),
                    Instruction.Create(OpCodes.Dup),
                    Instruction.Create(OpCodes.Ldarg_1),
                    Instruction.Create(OpCodes.Call, read),
                    Instruction.Create(StInd(elementType)),
                    InstructionUtility.LdcI4(stride),
                    Instruction.Create(OpCodes.Add),
                    Instruction.Create(OpCodes.Ldarg_1),
                    Instruction.Create(OpCodes.Call, read),
                    Instruction.Create(StInd(elementType)),
                });

            default:
            {
                var answer = new Instruction[6 + (6 * count)];
                answer[0] = Instruction.Create(OpCodes.Ldarg_1);
                answer[1] = Instruction.Create(OpCodes.Call, reader.ReadArrayHeader);
                answer[2] = InstructionUtility.LdcI4(count);
                answer[3] = Instruction.Create(OpCodes.Beq_S, same);
                answer[4] = Instruction.Create(OpCodes.Ldstr, "Fixed size buffer field should have " + count.ToString(CultureInfo.InvariantCulture) + " element(s). field : " + fixedField.FullName);
                answer[5] = Instruction.Create(OpCodes.Newobj, invalidOperationExceptionHelper.Ctor);
                answer[6] = Instruction.Create(OpCodes.Throw);
                answer[7] = same;
                answer[8] = Instruction.Create(OpCodes.Ldflda, importer.Import(fixedField));

                answer[9]  = Instruction.Create(OpCodes.Dup);
                answer[10] = Instruction.Create(OpCodes.Ldarg_1);
                answer[11] = Instruction.Create(OpCodes.Call, read);
                answer[12] = Instruction.Create(StInd(elementType));

                for (var i = 1; i < count - 1; i++)
                {
                    var start = 7 + (i * 6);
                    answer[start++] = Instruction.Create(OpCodes.Dup);
                    answer[start++] = InstructionUtility.LdcI4(stride);
                    answer[start++] = Instruction.Create(OpCodes.Add);
                    answer[start++] = Instruction.Create(OpCodes.Ldarg_1);
                    answer[start++] = Instruction.Create(OpCodes.Call, read);
                    answer[start]   = Instruction.Create(StInd(elementType));
                }

                answer[1 + (6 * count)] = InstructionUtility.LdcI4(stride);
                answer[2 + (6 * count)] = Instruction.Create(OpCodes.Add);
                answer[3 + (6 * count)] = Instruction.Create(OpCodes.Ldarg_1);
                answer[4 + (6 * count)] = Instruction.Create(OpCodes.Call, read);
                answer[5 + (6 * count)] = Instruction.Create(StInd(elementType));

                return(answer);
            }
            }
        }