summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks/MethodBodyExtensions.cs
blob: f5bdc85985e82a6fb0b9816d551b95e03eb6e95e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using System;

namespace Xamarin.Forms.Build.Tasks
{
	static class MethodBodyExtensions
	{
		public static void Optimize(this MethodBody self)
		{
			if (self == null)
				throw new ArgumentNullException(nameof(self));

			self.OptimizeLongs();
			self.OptimizeMacros();
		}

		static void ExpandMacro(Instruction instruction, OpCode opcode, object operand)
		{
			instruction.OpCode = opcode;
			instruction.Operand = operand;
		}

		//this can be removed if/when https://github.com/jbevain/cecil/pull/307 is released in a nuget we consume
		static void OptimizeLongs(this MethodBody self)
		{
			var method = self.Method;
			for (var i = 0; i < self.Instructions.Count; i++) {
				var instruction = self.Instructions[i];
				if (instruction.OpCode.Code != Code.Ldc_I8)
					continue;
				var l = (long)instruction.Operand;
				if (l < int.MinValue || l > int.MaxValue)
					continue;
				ExpandMacro(instruction, OpCodes.Ldc_I4, unchecked((int)l));
				self.Instructions.Insert(++i, Instruction.Create(OpCodes.Conv_I8));
			}
		}
	}
}