public DevirtualizeResults Devirtualize(DevirtualizeOptions options, Action<DevirtualizeAttempt> attemptCallback) { var methods = this.Parent.FindMethodStubs(); if (methods.Length == 0) return new DevirtualizeResults(); var attempts = new List<DevirtualizeAttempt>(); foreach (var method in methods) { var reader = new VirtualizedMethodBodyReader(method, this.Logger, this.Parent.Version); Exception exception = null, fixerException = null; try { reader.Read(); // Read method } catch (Exception e) { exception = e; } DevirtualizeAttempt attempt; if (exception == null) { var body = new CilBody( true, reader.Instructions, reader.ExceptionHandlers, reader.Locals ); method.Method.FreeMethodBody(); method.Method.Body = body; // Perform fixes try { PerformFixes(method.Method); } catch (Exception e) { fixerException = e; } if (fixerException == null) { // Inject DevirtualizedAttribute if specified if (options.HasFlag(DevirtualizeOptions.InjectAttributes)) this.Injector.InjectDevirtualized(method.Method); attempt = new DevirtualizeAttempt(method, reader, body); } else attempt = new DevirtualizeAttempt(method, reader, fixerException); } else attempt = new DevirtualizeAttempt(method, reader, exception); // Add attempt to list and fire callback attempts.Add(attempt); if (attemptCallback != null) attemptCallback(attempt); } return new DevirtualizeResults(attempts); }
/// <summary> /// Constructs a failed devirtualize attempt. /// </summary> /// <param name="vmethod">Virtualized method</param> /// <param name="reader">Method body reader</param> /// <param name="exception">Exception that occurred while devirtualizing</param> public DevirtualizeAttempt(MethodStub vmethod, VirtualizedMethodBodyReader reader, Exception exception) { this.VirtualizedMethod = vmethod; this.Reader = reader; this.Exception = exception; }
/// <summary> /// Constructs a successful devirtualize attempt. /// </summary> /// <param name="vmethod">Virtualized method</param> /// <param name="reader">Method body reader</param> /// <param name="body">Devirtualized method body</param> public DevirtualizeAttempt(MethodStub vmethod, VirtualizedMethodBodyReader reader, CilBody body) { this.VirtualizedMethod = vmethod; this.Reader = reader; this.MethodBody = body; }
static void WritePartiallyDevirtualizedMethod(VirtualizedMethodBodyReader reader) { if (!reader.HasInstructions) return; Console.WriteLine(); foreach(var instruction in reader.Instructions) Console.WriteLine("{0}", instruction.ToString()); Console.WriteLine(); }