private static void AppendBinaryOperation(ModuleDefinition moduleDefinition, TypeDefinition definition, InstructionData instructionData, string baseName, Instruction operation) { var method = FieldOperationMethod.Create(moduleDefinition, definition, $"{baseName}{instructionData.type.Name}", instructionData.GetTypeReference(moduleDefinition), instructionData.GetBinaryConfigTypeDefinition(moduleDefinition), $"core_field_operation_{baseName.ToLower()}", baseName, instructionData.type.Name.ToLower()); method.definition.Body.InitLocals = true; method.definition.Body.SimplifyMacros(); var data = new VariableDefinition(instructionData.GetBinaryConfigTypeDefinition(moduleDefinition)); method.definition.Body.Variables.Add(data); var processor = method.definition.Body.GetILProcessor(); processor.Emit(OpCodes.Nop); processor.Emit(OpCodes.Ldarga_S, method.configParameter); processor.Emit(OpCodes.Call, moduleDefinition.ImportReference(typeof(IntPtr).GetMethod(nameof(IntPtr.ToPointer)))); var call = new GenericInstanceMethod(moduleDefinition.ImportReference(typeof(UnsafeUtility).GetMethod(nameof(UnsafeUtility.AsRef)))); call.GenericArguments.Add(instructionData.GetBinaryConfigTypeDefinition(moduleDefinition)); processor.Emit(OpCodes.Call, call); processor.Emit(OpCodes.Ldobj, instructionData.GetBinaryConfigTypeDefinition(moduleDefinition)); processor.Emit(OpCodes.Stloc, data); processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Call, moduleDefinition.ImportReference(typeof(IntPtr).GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance).First(m => m.Name == "op_Explicit" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(IntPtr) && m.ReturnType == typeof(void *)))); processor.Emit(OpCodes.Ldloc_0); processor.Emit(OpCodes.Ldfld, instructionData.GetBinaryConfigTypeDefinition(moduleDefinition).Fields[0]); processor.Emit(OpCodes.Ldloc_0); processor.Emit(OpCodes.Ldfld, instructionData.GetBinaryConfigTypeDefinition(moduleDefinition).Fields[1]); processor.Append(operation); processor.Append(instructionData.GetStoreInstruction(moduleDefinition)); processor.Emit(OpCodes.Ret); method.definition.Body.OptimizeMacros(); }
private static void AppendMathOperation(ModuleDefinition moduleDefinition, TypeDefinition container, TypeDefinition config, MethodInfo methodInfo) { var method = FieldOperationMethod.Create(moduleDefinition, container, $"MathOperation_{methodInfo.Name}_{config.Name}", moduleDefinition.ImportReference(methodInfo.ReturnType), config, $"core_field_operation_math_{methodInfo.Name}", CultureInfo.InvariantCulture.TextInfo.ToTitleCase(methodInfo.Name), GetSubIdentifier(methodInfo)); method.definition.Body.InitLocals = true; method.definition.Body.SimplifyMacros(); var data = new VariableDefinition(config); method.definition.Body.Variables.Add(data); var processor = method.definition.Body.GetILProcessor(); processor.Emit(OpCodes.Nop); processor.Emit(OpCodes.Ldarga_S, method.configParameter); processor.Emit(OpCodes.Call, moduleDefinition.ImportReference(typeof(IntPtr).GetMethod(nameof(IntPtr.ToPointer)))); var call = new GenericInstanceMethod(moduleDefinition.ImportReference(typeof(UnsafeUtility).GetMethod(nameof(UnsafeUtility.AsRef)))); call.GenericArguments.Add(config); processor.Emit(OpCodes.Call, call); processor.Emit(OpCodes.Ldobj, config); processor.Emit(OpCodes.Stloc, data); processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Call, moduleDefinition.ImportReference(typeof(IntPtr).GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance).First(m => m.Name == "op_Explicit" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(IntPtr) && m.ReturnType == typeof(void *)))); foreach (var field in config.Fields) { processor.Emit(OpCodes.Ldloc_0); processor.Emit(OpCodes.Ldfld, field); } processor.Emit(OpCodes.Call, moduleDefinition.ImportReference(methodInfo)); processor.Emit(OpCodes.Stobj, moduleDefinition.ImportReference(methodInfo.ReturnType)); processor.Emit(OpCodes.Ret); method.definition.Body.OptimizeMacros(); }