private MethodDefinition GenerateGetPair(int bitmask, FieldDefinition tableField, ArrayType pairArray) { var getPair = new MethodDefinition( "GetPair", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static, importer.Import(pairGenerator.Value.FieldType).Reference) { HasThis = false, Parameters = { new ParameterDefinition("type", ParameterAttributes.None, typeHelper.Type), }, Body = { InitLocals = true, Variables = { new VariableDefinition(pairArray), new VariableDefinition(module.TypeSystem.IntPtr), }, }, }; var processor = getPair.Body.GetILProcessor(); processor.Append(Instruction.Create(OpCodes.Ldsfld, tableField)); // { Pair[][] } processor.Append(InstructionUtility.LdcI4(bitmask)); // { Pair[][], int32 } processor.Append(Instruction.Create(OpCodes.Ldarg_0)); // { Pair[][], int32, Type } processor.Append(Instruction.Create(OpCodes.Callvirt, systemObjectHelper.GetHashCode)); // { Pair[][], int32, int32 } processor.Append(Instruction.Create(OpCodes.And)); // { Pair[][], int32 } processor.Append(Instruction.Create(OpCodes.Ldelem_Ref)); // { Pair[] } processor.Append(Instruction.Create(OpCodes.Dup)); // { Pair[], Pair[] } processor.Append(Instruction.Create(OpCodes.Stloc_0)); // { Pair[] } var condition = Instruction.Create(OpCodes.Ldloc_1); processor.Append(Instruction.Create(OpCodes.Brtrue_S, condition)); // { } ReturnDefaultValue(processor); var loopStart = Instruction.Create(OpCodes.Ldloc_0); processor.Append(loopStart); // { Pair[] } processor.Append(Instruction.Create(OpCodes.Ldloc_1)); // { Pair[], native int } processor.Append(Instruction.Create(OpCodes.Ldelema, importer.Import(pairGenerator.Pair).Reference)); // { Pair& } processor.Append(Instruction.Create(OpCodes.Dup)); // { Pair&, Pair& } processor.Append(Instruction.Create(OpCodes.Ldfld, importer.Import(pairGenerator.Key))); // { Pair&, Type } processor.Append(Instruction.Create(OpCodes.Ldarg_0)); // { Pair&, Type, Type } var continuation = Instruction.Create(OpCodes.Pop); processor.Append(Instruction.Create(OpCodes.Bne_Un_S, continuation)); // { Pair& } processor.Append(Instruction.Create(OpCodes.Ldfld, importer.Import(pairGenerator.Value))); // { uint64 } processor.Append(Instruction.Create(OpCodes.Ret)); processor.Append(continuation); // { } processor.Append(Instruction.Create(OpCodes.Ldloc_1)); // { native int } processor.Append(InstructionUtility.LdcI4(1)); // { native int, int32 } processor.Append(Instruction.Create(OpCodes.Conv_I)); // { native int, native int } processor.Append(Instruction.Create(OpCodes.Add)); // { native int } processor.Append(Instruction.Create(OpCodes.Stloc_1)); // { } processor.Append(condition); // { native int } processor.Append(Instruction.Create(OpCodes.Ldloc_0)); // { native int, Pair[] } processor.Append(Instruction.Create(OpCodes.Ldlen)); // { native int, native int } processor.Append(Instruction.Create(OpCodes.Blt_S, loopStart)); // { } ReturnDefaultValue(processor); return(getPair); }
private void LoadAppropriateValueFromFormatterInfo(ILProcessor processor, FormatterTableItemInfo formatterTableItemInfo) { foreach (var constructorArgument in formatterTableItemInfo.FormatterConstructorArguments) { void Load(CustomAttributeArgument argument) { var value = argument.Value; switch (argument.Type.FullName) { case "System.Char": processor.Append(InstructionUtility.LdcI4((char)value)); break; case "System.Boolean": processor.Append(InstructionUtility.LdcBoolean((bool)value)); break; case "System.Type": processor.Append(Instruction.Create(OpCodes.Ldtoken, importer.Import((TypeReference)value).Reference)); processor.Append(Instruction.Create(OpCodes.Call, typeHelper.GetTypeFromHandle)); break; case "System.Object": processor.Append(Instruction.Create(OpCodes.Ldnull)); break; case "System.Byte": processor.Append(InstructionUtility.LdcI4((byte)value)); break; case "System.SByte": processor.Append(InstructionUtility.LdcI4((sbyte)value)); break; case "System.Int16": processor.Append(InstructionUtility.LdcI4((short)value)); break; case "System.Int32": processor.Append(InstructionUtility.LdcI4((int)value)); break; case "System.Int64": { var(instruction0, instruction1) = InstructionUtility.LdcI8((long)value); processor.Append(instruction0); if (!(instruction1 is null)) { processor.Append(instruction1); } } break; case "System.UInt16": processor.Append(InstructionUtility.LdcI4((ushort)value)); break; case "System.UInt32": processor.Append(InstructionUtility.LdcI4((int)(uint)value)); break; case "System.UInt64": { var(instruction0, instruction1) = InstructionUtility.LdcU8((ulong)value); processor.Append(instruction0); if (!(instruction1 is null)) { processor.Append(instruction1); } } break; case "System.Single": processor.Append(InstructionUtility.LdcR4((float)value)); break; case "System.Double": processor.Append(InstructionUtility.LdcR8((double)value)); break; case "System.String": processor.Append(InstructionUtility.LdStr((string)value)); break; default: throw new MessagePackGeneratorResolveFailedException(argument.Type.FullName + " is not supported."); } } Load(constructorArgument); } processor.Append(Instruction.Create(OpCodes.Newobj, customFormatterConstructorImporter.Import(formatterTableItemInfo))); // { Pair&, formatter } }