Author: spouliot
Date: 2008-02-15 14:27:50 -0500 (Fri, 15 Feb 2008)
New Revision: 95797

Removed:
   trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignature.cs
   trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignatures.cs
   trunk/mono-tools/gendarme/framework/Gendarme.Framework/StackEntryAnalysis.cs
Modified:
   trunk/mono-tools/gendarme/framework/Gendarme.Framework/ChangeLog
Log:
        * MethodSignature.cs
        * MethodSignatures.cs
        * StackEntryAnalysis.cs:
                Moved into Gendarme.Framework.Helpers

2008-02-15  Sebastien Pouliot  <[EMAIL PROTECTED]>



Modified: trunk/mono-tools/gendarme/framework/Gendarme.Framework/ChangeLog
===================================================================
--- trunk/mono-tools/gendarme/framework/Gendarme.Framework/ChangeLog    
2008-02-15 19:27:00 UTC (rev 95796)
+++ trunk/mono-tools/gendarme/framework/Gendarme.Framework/ChangeLog    
2008-02-15 19:27:50 UTC (rev 95797)
@@ -1,5 +1,12 @@
 2008-02-15  Sebastien Pouliot  <[EMAIL PROTECTED]>
 
+       * MethodSignature.cs
+       * MethodSignatures.cs
+       * StackEntryAnalysis.cs:
+               Moved into Gendarme.Framework.Helpers
+
+2008-02-15  Sebastien Pouliot  <[EMAIL PROTECTED]>
+
        * Runner.cs: Use Rocks to iterate all methods in a type.
 
 2008-02-14  Sebastien Pouliot  <[EMAIL PROTECTED]>

Deleted: 
trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignature.cs
===================================================================
--- trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignature.cs   
2008-02-15 19:27:00 UTC (rev 95796)
+++ trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignature.cs   
2008-02-15 19:27:50 UTC (rev 95797)
@@ -1,171 +0,0 @@
-//
-// Gendarme.Framework.MethodSignature
-//
-// Authors:
-//     Andreas Noever <[EMAIL PROTECTED]>
-//     Sebastien Pouliot  <[EMAIL PROTECTED]>
-//
-//  (C) 2008 Andreas Noever
-// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections.ObjectModel;
-using System.Collections.Generic;
-using System.Text;
-
-using Mono.Cecil;
-
-namespace Gendarme.Framework {
-
-       /// <summary>
-       /// Used to match methods. Properties that are set to null are ignored
-       /// </summary>
-       /// <example>
-       /// <code>
-       /// MethodDefinition method = ...
-       /// MethodSignature sig = new MethodSignature ("Dispose");
-       /// if (sig.Match (method)) { 
-       ///     //matches any method named "Dispose" with any (or no) return 
value and any number of parameters
-       /// }
-       /// </code>
-       /// </example>
-       /// <seealso cref="Gendarme.Framework.MethodSignatures"/>
-       public class MethodSignature {
-
-               /// <summary>
-               /// The name of the method to match. Ignored if null.
-               /// </summary>
-               public string Name { get; private set; }
-
-               /// <summary>
-               /// The FullName (Namespace.Type) of the return type. Ignored 
if null.
-               /// </summary>
-               public string ReturnType { get; private set; }
-
-               /// <summary>
-               /// An array of FullNames (Namespace.Type) of parameter types. 
Ignored if null. Null entries act as wildcards.
-               /// </summary>
-               public ReadOnlyCollection<string> Parameters { get; private 
set; }
-
-               /// <summary>
-               /// An attribute mask matched against the attributes of the 
method.
-               /// </summary>
-               public MethodAttributes Attributes { get; private set; }
-
-
-               public MethodSignature ()
-               {
-               }
-
-               public MethodSignature (string name)
-                       : this (name, null, null)
-               {
-               }
-
-               public MethodSignature (string name, string returnType)
-                       : this (name, returnType, null)
-               {
-               }
-
-               public MethodSignature (string name, string returnType, 
string[] parameters)
-               {
-                       Name = name;
-                       ReturnType = returnType;
-                       if (parameters != null)
-                               Parameters = new ReadOnlyCollection<string> 
(new List<string> (parameters));
-               }
-
-               public MethodSignature (string name, string returnType, string 
[] parameters, MethodAttributes attributes)
-                       : this (name, returnType, parameters)
-               {
-                       Attributes = attributes;
-               }
-
-               /// <summary>
-               /// Checks if a MethodReference match the signature.
-               /// </summary>
-               /// <param name="method">The method to check.</param>
-               /// <returns>True if the MethodReference matches all aspects of 
the MethodSignature.</returns>
-               public bool Matches (MethodReference method)
-               {
-                       if (method == null)
-                               throw new ArgumentNullException ("method");
-
-                       if (Name != null && method.Name != Name)
-                               return false;
-
-                       if (ReturnType != null && 
method.ReturnType.ReturnType.FullName != ReturnType)
-                               return false;
-
-                       if (Parameters != null) {
-                               if (Parameters.Count != method.Parameters.Count)
-                                       return false;
-                               for (int i = 0; i < Parameters.Count; i++) {
-                                       if (Parameters [i] == null)
-                                               continue;//ignore parameter
-                                       if (Parameters [i] != method.Parameters 
[i].ParameterType.FullName) {
-                                               return false;
-                                       }
-                               }
-                       }
-
-                       // skip last check if no attributes are part of the 
signature
-                       if (((int) Attributes) == 0)
-                               return true;
-
-                       // put this at last step so we avoid the cast as much 
as possible
-                       MethodDefinition md = (method as MethodDefinition);
-                       return ((md == null) || ((md.Attributes & Attributes) 
== Attributes));
-               }
-
-               /// <summary>
-               /// 
-               /// </summary>
-               /// <returns></returns>
-               public override string ToString ()
-               {
-                       // if we do not have enough useful information return 
an empty string
-                       if (Name == null)
-                               return String.Empty;
-
-                       StringBuilder sb = new StringBuilder ();
-                       if (ReturnType != null) {
-                               sb.Append (ReturnType);
-                               sb.Append (' ');
-                       }
-
-                       sb.Append (Name);
-                       sb.Append ('(');
-                       if (Parameters != null) {
-                               for (int i = 0; i < Parameters.Count; i++) {
-                                       sb.Append (Parameters [i]);
-                                       if (i < Parameters.Count - 1)
-                                               sb.Append (',');
-                               }
-                       }
-                       sb.Append (')');
-
-                       return sb.ToString ();
-               }
-       }
-}

Deleted: 
trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignatures.cs
===================================================================
--- trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignatures.cs  
2008-02-15 19:27:00 UTC (rev 95796)
+++ trunk/mono-tools/gendarme/framework/Gendarme.Framework/MethodSignatures.cs  
2008-02-15 19:27:50 UTC (rev 95797)
@@ -1,92 +0,0 @@
-//
-// Gendarme.Framework.MethodSignatures
-//
-// Authors:
-//     Andreas Noever <[EMAIL PROTECTED]>
-//     Sebastien Pouliot  <[EMAIL PROTECTED]>
-//
-//  (C) 2008 Andreas Noever
-// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-
-using Mono.Cecil;
-
-namespace Gendarme.Framework {
-
-       /// <summary>
-       /// Defines commonly used MethodSignatures
-       /// </summary>
-       /// <see cref="Gendarme.Framework.MethodSignature"/>
-       public static class MethodSignatures {
-               private static readonly string [] NoParameter = new string [0];
-               private static readonly string [] OneParameter = new string [1];
-               private static readonly string [] TwoParameters = new string 
[2];
-
-               // System.Object
-               public static readonly new MethodSignature Equals = new 
MethodSignature ("Equals", "System.Boolean", new string [] { "System.Object" }, 
 MethodAttributes.Public);
-               public static readonly MethodSignature Finalize = new 
MethodSignature ("Finalize", "System.Void", NoParameter, 
MethodAttributes.Family);
-               public static readonly new MethodSignature GetHashCode = new 
MethodSignature ("GetHashCode", "System.Int32", NoParameter, 
MethodAttributes.Public | MethodAttributes.Virtual);
-               public static readonly new MethodSignature ToString = new 
MethodSignature ("ToString", "System.String", NoParameter, 
MethodAttributes.Public | MethodAttributes.Virtual);
-
-               // IDisposable
-               public static readonly MethodSignature Dispose = new 
MethodSignature ("Dispose", "System.Void", NoParameter);
-               public static readonly MethodSignature DisposeExplicit = new 
MethodSignature ("System.IDisposable.Dispose", "System.Void", NoParameter);
-
-               // operators
-               private static readonly MethodAttributes OperatorAttributes = 
MethodAttributes.Static | MethodAttributes.SpecialName;
-               
-               // unary
-               public static readonly MethodSignature op_UnaryPlus = new 
MethodSignature ("op_UnaryPlus", null, OneParameter, OperatorAttributes);       
      // +5
-               public static readonly MethodSignature op_UnaryNegation = new 
MethodSignature ("op_UnaryNegation", null, OneParameter, OperatorAttributes);   
  // -5
-               public static readonly MethodSignature op_LogicalNot = new 
MethodSignature ("op_LogicalNot", null, OneParameter, OperatorAttributes);      
     // !true
-               public static readonly MethodSignature op_OnesComplement = new 
MethodSignature ("op_OnesComplement", null, OneParameter, OperatorAttributes);  
 // ~5
-
-               public static readonly MethodSignature op_Increment = new 
MethodSignature ("op_Increment", null, OneParameter, OperatorAttributes);       
      // 5++
-               public static readonly MethodSignature op_Decrement = new 
MethodSignature ("op_Decrement", null, OneParameter, OperatorAttributes);       
      // 5--
-               public static readonly MethodSignature op_True = new 
MethodSignature ("op_True", "System.Boolean", OneParameter, 
OperatorAttributes);           // if (object)          
-               public static readonly MethodSignature op_False = new 
MethodSignature ("op_False", "System.Boolean", OneParameter, 
OperatorAttributes);         // if (object)
-
-               // binary
-               public static readonly MethodSignature op_Addition = new 
MethodSignature ("op_Addition", null, TwoParameters, OperatorAttributes);       
       // 5 + 5
-               public static readonly MethodSignature op_Subtraction = new 
MethodSignature ("op_Subtraction", null, TwoParameters, OperatorAttributes);    
    // 5 - 5 
-               public static readonly MethodSignature op_Multiply = new 
MethodSignature ("op_Multiply", null, TwoParameters, OperatorAttributes);       
       // 5 * 5
-               public static readonly MethodSignature op_Division = new 
MethodSignature ("op_Division", null, TwoParameters, OperatorAttributes);       
       // 5 / 5
-               public static readonly MethodSignature op_Modulus = new 
MethodSignature ("op_Modulus", null, TwoParameters, OperatorAttributes);        
        // 5 % 5
-
-               public static readonly MethodSignature op_BitwiseAnd = new 
MethodSignature ("op_BitwiseAnd", null, TwoParameters, OperatorAttributes);     
     // 5 & 5
-               public static readonly MethodSignature op_BitwiseOr = new 
MethodSignature ("op_BitwiseOr", null, TwoParameters, OperatorAttributes);      
      // 5 | 5
-               public static readonly MethodSignature op_ExclusiveOr = new 
MethodSignature ("op_ExclusiveOr", null, TwoParameters, OperatorAttributes);    
    // 5 ^ 5
-
-               public static readonly MethodSignature op_LeftShift = new 
MethodSignature ("op_LeftShift", null, TwoParameters, OperatorAttributes);      
      // 5 << 5
-               public static readonly MethodSignature op_RightShift = new 
MethodSignature ("op_RightShift", null, TwoParameters, OperatorAttributes);     
     // 5 >> 5
-
-               // comparison
-               public static readonly MethodSignature op_Equality = new 
MethodSignature ("op_Equality", null, TwoParameters, OperatorAttributes);       
               // 5 == 5
-               public static readonly MethodSignature op_Inequality = new 
MethodSignature ("op_Inequality", null, TwoParameters, OperatorAttributes);     
             // 5 != 5
-               public static readonly MethodSignature op_GreaterThan = new 
MethodSignature ("op_GreaterThan", null, TwoParameters, OperatorAttributes);    
            // 5 > 5
-               public static readonly MethodSignature op_LessThan = new 
MethodSignature ("op_LessThan", null, TwoParameters, OperatorAttributes);       
               // 5 < 5
-               public static readonly MethodSignature op_GreaterThanOrEqual = 
new MethodSignature ("op_GreaterThanOrEqual", null, TwoParameters, 
OperatorAttributes);  // 5 >= 5
-               public static readonly MethodSignature op_LessThanOrEqual = new 
MethodSignature ("op_LessThanOrEqual", null, TwoParameters, 
OperatorAttributes);        // 5 <= 5
-       }
-}

Deleted: 
trunk/mono-tools/gendarme/framework/Gendarme.Framework/StackEntryAnalysis.cs
===================================================================
--- 
trunk/mono-tools/gendarme/framework/Gendarme.Framework/StackEntryAnalysis.cs    
    2008-02-15 19:27:00 UTC (rev 95796)
+++ 
trunk/mono-tools/gendarme/framework/Gendarme.Framework/StackEntryAnalysis.cs    
    2008-02-15 19:27:50 UTC (rev 95797)
@@ -1,656 +0,0 @@
-//
-// Gendarme.Framework.StackEntryAnalysis
-//
-// Authors:
-//     Andreas Noever <[EMAIL PROTECTED]>
-//
-//  (C) 2008 Andreas Noever
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections.Generic;
-
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-
-using Gendarme.Framework.Rocks;
-
-namespace Gendarme.Framework {
-
-       /// <summary>
-       /// This class can be used to find all usages of a reference on the 
stack.
-       /// Currently used for:
-       /// Gendarme.Rules.BadPractice.CheckNewExceptionWithoutThrowRule
-       /// Gendarme.Rules.BadPractice.CheckNewThreadWithoutStartRule
-       /// 
Gendarme.Rules.Interoperability.GetLastErrorMustBeCalledRightAfterPInvokeRule
-       /// </summary>
-       public class StackEntryAnalysis {
-
-               /// <summary>
-               /// Represents a usage of a StackEntry
-               /// </summary>
-               public struct UsageResult {
-                       /// <summary>
-                       /// The instruction that uses the StackEntry
-                       /// </summary>
-                       public readonly Instruction Instruction;
-                       /// <summary>
-                       /// The positive offset of the StackEntry before the 
instruction executes. 0 means right on top.
-                       /// </summary>
-                       public readonly int StackOffset;
-                       public UsageResult (Instruction ins, int offset)
-                       {
-                               this.Instruction = ins;
-                               this.StackOffset = offset;
-                       }
-               }
-
-               enum StoreType {
-                       None,
-                       Local,
-                       Argument,
-                       Field,
-                       StaticField,
-                       Out,
-               }
-
-               /// <summary>
-               /// Saves information about a local variable slot (argument or 
local variable).
-               /// Used to keep track of assignments.
-               /// </summary>
-               struct StoreSlot {
-                       public readonly StoreType Type;
-                       public readonly int Slot;
-                       public StoreSlot (StoreType type, int slot)
-                       {
-                               this.Type = type;
-                               this.Slot = slot;
-                       }
-
-                       /// <summary>
-                       /// Use this to check if an instruction accesses a 
StoreSlot. True if this is not a StoreSlot.
-                       /// </summary>
-                       public bool IsNone
-                       {
-                               get
-                               {
-                                       return this.Type == StoreType.None;
-                               }
-                       }
-
-                       public static bool operator == (StoreSlot a, StoreSlot 
b)
-                       {
-                               return a.Slot == b.Slot && a.Type == b.Type;
-                       }
-
-                       public static bool operator != (StoreSlot a, StoreSlot 
b)
-                       {
-                               return a.Slot != b.Slot || a.Type != b.Type;
-                       }
-
-                       public override bool Equals (object obj)
-                       {
-                               if (obj == null)
-                                       return false;
-                               if (!(obj is StoreSlot))
-                                       return false;
-                               StoreSlot other = (StoreSlot) obj;
-                               return this == other;
-                       }
-
-                       public override int GetHashCode ()
-                       {
-                               return Slot.GetHashCode () ^ Type.GetHashCode 
();
-                       }
-               }
-
-               /// <summary>
-               /// Wraps an instruction and a stack of leave statements used 
to get to this instruction.
-               /// Needed to do correct analysis in finally blocks.
-               /// </summary>
-               struct InstructionWithLeave {
-                       public static readonly InstructionWithLeave Empty = new 
InstructionWithLeave ();
-
-                       public readonly Instruction Instruction;
-                       public readonly Instruction [] LeaveStack;
-
-                       public InstructionWithLeave (Instruction instruction)
-                       {
-                               this.Instruction = instruction;
-                               this.LeaveStack = null;
-                       }
-
-                       private InstructionWithLeave (Instruction instruction, 
Instruction [] leaveStack)
-                       {
-                               this.Instruction = instruction;
-                               this.LeaveStack = leaveStack;
-                       }
-
-                       /// <summary>
-                       /// Returns a new InstructionWithLeave with leave 
pushed onto the stack.
-                       /// </summary>
-                       /// <param name="instruction">The new 
instruction.</param>
-                       /// <param name="leave">The leave instruction to push 
onto the stack.</param>
-                       /// <returns>A new InstructionWithLeave</returns>
-                       public InstructionWithLeave Push (Instruction 
instruction, Instruction leave)
-                       {
-                               Instruction [] newStack;
-                               if (this.LeaveStack != null) {
-                                       newStack = new Instruction 
[LeaveStack.Length + 1];
-                                       Array.Copy (LeaveStack, newStack, 
LeaveStack.Length);
-                                       newStack [LeaveStack.Length] = leave;
-                               } else {
-                                       newStack = new Instruction [] { leave };
-                               }
-                               return new InstructionWithLeave (instruction, 
newStack);
-                       }
-
-                       /// <summary>
-                       /// Returns a new InstructionWithLeave with the same 
LeaveStack and another instruction.
-                       /// </summary>
-                       /// <param name="instruction">The new 
instruction.</param>
-                       /// <returns>a new InstructionWithLeave</returns>
-                       public InstructionWithLeave Copy (Instruction 
instruction)
-                       {
-                               return new InstructionWithLeave (instruction, 
this.LeaveStack);
-                       }
-
-                       /// <summary>
-                       /// Returns a new InstructionWithLeave with the one 
leave statement popped and instruction set to the operand of the popped leave 
statement.
-                       /// </summary>
-                       /// <returns>a new InstructionWithLeave</returns>
-                       public InstructionWithLeave Pop ()
-                       {
-                               Instruction [] newStack = null;
-                               if (LeaveStack.Length != 1) {
-                                       newStack = new Instruction 
[LeaveStack.Length - 1];
-                                       Array.Copy (LeaveStack, newStack, 
newStack.Length);
-                               }
-                               return new InstructionWithLeave ((Instruction) 
this.LeaveStack [this.LeaveStack.Length - 1].Operand, newStack);
-                       }
-
-               }
-
-               public MethodDefinition Method {
-                       get; private set;
-               }
-
-               private MethodBody Body {
-                       get { return Method.Body; }
-               }
-
-               public StackEntryAnalysis (MethodDefinition method)
-               {
-                       this.Method = method;
-               }
-
-               //static lists to save allocations.
-               private static List<KeyValuePair<InstructionWithLeave, int>> 
UsedBy = new List<KeyValuePair<InstructionWithLeave, int>> ();
-               private static List<KeyValuePair<InstructionWithLeave, int>> 
AlternativePaths = new List<KeyValuePair<InstructionWithLeave, int>> ();
-
-               /// <summary>
-               /// Searches a method for usage of the value pushed onto the 
stack by the specified instruction.
-               /// </summary>
-               /// <param name="ins">The instruction.</param>
-               /// <returns>An array of UsageResults containing the 
instructions that use the value and the stack offset of the entry at that 
instruction. A StackOffset of 0 means right on top of the stack.</returns>
-               public UsageResult [] GetStackEntryUsage (Instruction ins)
-               {
-                       /* In the main loop we search for all usages of a 
StackEntry.
-                        * Then we check each usage for a store (to a local 
variable or an argument), search for corrosponding loads and search for usages 
of the new Stackentry.
-                        * This continues until no stores are found. */
-
-                       UsedBy.Clear ();
-                       AlternativePaths.Clear ();
-
-                       AlternativePaths.Add (new 
KeyValuePair<InstructionWithLeave, int> (new InstructionWithLeave (ins.Next), 
0));
-
-                       int lastAlternativesCount = 0;
-                       int lastUsedByCount = 0;
-
-                       while (lastAlternativesCount != AlternativePaths.Count) 
{ //continue until no more alternatives have been found (by CheckUsedBy)
-
-                               for (int i = lastAlternativesCount; i < 
AlternativePaths.Count; i++) { //find the instruction that pops the value and 
follow all branches
-                                       var result = FollowStackEntry 
(AlternativePaths [i].Key, AlternativePaths [i].Value);
-                                       if (result.Key.Instruction != null)
-                                               UsedBy.AddIfNew (result); //add 
to usedby list
-                               }
-                               lastAlternativesCount = AlternativePaths.Count; 
//check each path only once.
-
-                               CheckUsedBy (lastUsedByCount);
-                               lastUsedByCount = UsedBy.Count;
-                       }
-
-                       //build return value
-                       UsageResult [] results = new UsageResult [UsedBy.Count];
-                       for (int i = 0; i < results.Length; i++)
-                               results [i] = new UsageResult (UsedBy 
[i].Key.Instruction, UsedBy [i].Value);
-                       return results;
-               }
-
-               /// <summary>
-               /// Iterates over all Instructions inside UsedBy and spawns a 
new alternative if necessary.
-               /// </summary>
-               /// <param name="start">The first index to progress.</param>
-               private void CheckUsedBy (int start)
-               {
-                       for (int ii = start; ii < UsedBy.Count; ii++) {
-                               InstructionWithLeave use = UsedBy [ii].Key;
-
-                               StoreSlot slot = GetStoreSlot 
(use.Instruction); //check if this is a store instruction
-
-                               bool removeFromUseBy = false; //ignore the use
-
-                               if (use.Instruction.OpCode.Code == 
Code.Castclass) {
-                                       removeFromUseBy = true;
-                                       AlternativePaths.AddIfNew (new 
KeyValuePair<InstructionWithLeave, int> (use.Copy (use.Instruction.Next), 0));
-                               } else if (use.Instruction.OpCode.Code == 
Code.Pop) {//pop is not a valid usage
-                                       removeFromUseBy = true;
-                               } else if (!slot.IsNone) {
-                                       if (slot.Type == StoreType.Argument || 
slot.Type == StoreType.Local)
-                                               removeFromUseBy = true; 
//temporary save
-                                       foreach (var ld in this.FindLoad 
(use.Copy (use.Instruction.Next), slot)) { //start searching at the next 
instruction
-                                               AlternativePaths.AddIfNew (new 
KeyValuePair<InstructionWithLeave, int> (ld.Copy (ld.Instruction.Next), 0));
-                                       }
-                               }
-                               if (removeFromUseBy) {
-                                       UsedBy.RemoveAt (ii);
-                                       ii--;
-                               }
-                       }
-               }
-
-               /// <summary>
-               /// Follows the instructions until the specified stack entry is 
accessed.
-               /// </summary>
-               /// <param name="ins">The first instruction.</param>
-               /// <param name="stackEntry">The distance of the stack entry 
from the top of the stack. 0 means right on top.</param>
-               /// <returns>The instruction that pops the stackEntry and the 
distance of the entry to the top of the stack. If no valid instruction if found 
the method returns InstructionWithLeave.Empty.</returns>
-               private KeyValuePair<InstructionWithLeave, int> 
FollowStackEntry (InstructionWithLeave startInstruction, int stackEntryDistance)
-               {
-                       Instruction ins = startInstruction.Instruction;
-
-                       while (true) {
-                               int pop = this.GetPopCount (ins);
-                               int push = this.GetPushCount (ins);
-
-                               if (pop > stackEntryDistance)  //does this 
instruction pop the stack entry 
-                                       return new 
KeyValuePair<InstructionWithLeave, int> (startInstruction.Copy (ins), 
stackEntryDistance);
-
-                               stackEntryDistance -= pop;
-                               stackEntryDistance += push;
-
-                               //fetch ne next instruction
-                               object alternativeNext;
-                               Instruction nextInstruction = 
GetNextInstruction (ins, out alternativeNext);
-
-                               if (nextInstruction == null)
-                                       return new 
KeyValuePair<InstructionWithLeave, int> (); //return / throw / endfinally
-
-                               if (nextInstruction.OpCode.Code == Code.Leave 
|| nextInstruction.OpCode.Code == Code.Leave_S)
-                                       return new 
KeyValuePair<InstructionWithLeave, int> (); //leave clears the stack, the entry 
is gone.
-
-                               if (alternativeNext != null) { //branch / 
switch                                        
-                                       Instruction oneTarget = alternativeNext 
as Instruction;
-                                       if (oneTarget != null) { //branch
-                                               AlternativePaths.AddIfNew (new 
KeyValuePair<InstructionWithLeave, int> (startInstruction.Copy (oneTarget), 
stackEntryDistance));
-                                       } else { //switch
-                                               foreach (Instruction 
switchTarget in (Instruction []) alternativeNext)
-                                                       
AlternativePaths.AddIfNew (new KeyValuePair<InstructionWithLeave, int> 
(startInstruction.Copy (switchTarget), stackEntryDistance));
-                                       }
-                               }
-
-                               if (nextInstruction.OpCode.FlowControl == 
FlowControl.Branch || nextInstruction.OpCode.FlowControl == 
FlowControl.Cond_Branch) {
-                                       AlternativePaths.AddIfNew (new 
KeyValuePair<InstructionWithLeave, int> (startInstruction.Copy 
(nextInstruction), stackEntryDistance));
-                                       return new 
KeyValuePair<InstructionWithLeave, int> (); //end of block
-                               }
-                               ins = nextInstruction;
-                       }
-               }
-
-
-               //static lists to save allocations.
-               private static List<InstructionWithLeave> LoadAlternatives = 
new List<InstructionWithLeave> ();
-               private static List<InstructionWithLeave> LoadResults = new 
List<InstructionWithLeave> ();
-
-               /// <summary>
-               /// Follows the codeflow starting at a given instruction and 
finds all loads for a given slot.
-               /// Continues and follows all branches until the slot is 
overwritten or the method returns / throws.
-               /// </summary>
-               /// <param name="insWithLeave">The first instruction to start 
the search at.</param>
-               /// <param name="slot">The slot to search.</param>
-               /// <returns>An array of instructions that load from the 
slot.</returns>
-               private InstructionWithLeave [] FindLoad (InstructionWithLeave 
insWithLeave, StoreSlot slot)
-               {
-                       LoadAlternatives.Clear ();
-                       LoadResults.Clear ();
-
-                       LoadAlternatives.Add (insWithLeave);
-
-
-                       for (int i = 0; i < LoadAlternatives.Count; i++) { 
//loop over all branches, more will get added inside the loop
-                               insWithLeave = LoadAlternatives [i]; //the 
first instruction of the block (contains the leave stack)
-
-                               Instruction ins = insWithLeave.Instruction; 
//the current instruction
-                               while (true) {
-
-                                       if (GetStoreSlot (ins) == slot) //check 
if the slot gets overwritten
-                                               break;
-
-                                       if (slot == GetLoadSlot (ins))
-                                               LoadResults.AddIfNew 
(insWithLeave.Copy (ins)); //continue, might be loaded again
-
-                                       //we simply branch to every possible 
catch block.
-                                       foreach (ExceptionHandler handler in 
Body.ExceptionHandlers) {
-                                               if (handler.Type != 
ExceptionHandlerType.Catch)
-                                                       continue;
-                                               if (ins.Offset < 
handler.TryStart.Offset || ins.Offset >= handler.TryEnd.Offset)
-                                                       continue;
-                                               LoadAlternatives.AddIfNew 
(insWithLeave.Copy (handler.HandlerStart));
-                                       }
-
-                                       //Code.Leave leaves a try/catch block. 
Search for the finally block.
-                                       if (ins.OpCode.Code == Code.Leave || 
ins.OpCode.Code == Code.Leave_S) {
-                                               bool handlerFound = false;
-                                               foreach (ExceptionHandler 
handler in Body.ExceptionHandlers) {
-                                                       if (handler.Type != 
ExceptionHandlerType.Finally)
-                                                               continue;
-                                                       if 
(handler.TryStart.Offset > ins.Offset || handler.TryEnd.Offset <= ins.Offset)
-                                                               continue;
-                                                       
LoadAlternatives.AddIfNew (insWithLeave.Push (handler.HandlerStart, ins)); 
//push the leave instruction onto the leave stack
-                                                       handlerFound = true;
-                                                       break;
-                                               }
-                                               if (!handlerFound) //no finally 
found (try/catch without finally)
-                                                       
LoadAlternatives.AddIfNew (insWithLeave.Copy ((Instruction) ins.Operand));
-                                               break;
-
-                                       }
-
-                                       if (ins.OpCode.Code == Code.Endfinally) 
{ //pop the last leave instruction and branch to it
-                                               LoadAlternatives.AddIfNew 
(insWithLeave.Pop ());
-                                               break;
-                                       }
-
-                                       //fetch the next instruction (s)
-                                       object alternativeNext;
-                                       ins = GetNextInstruction (ins, out 
alternativeNext);
-                                       if (ins == null)
-                                               break;
-
-                                       if (alternativeNext != null) {
-                                               Instruction oneTarget = 
alternativeNext as Instruction;
-                                               if (oneTarget != null) { 
//normal branch
-                                                       
LoadAlternatives.AddIfNew (insWithLeave.Copy (oneTarget));
-                                               } else { //switch statement
-                                                       foreach (Instruction 
switchTarget in (Instruction []) alternativeNext)
-                                                               
LoadAlternatives.AddIfNew (insWithLeave.Copy (switchTarget));
-                                               }
-                                       }
-
-                                       if (ins.OpCode.FlowControl == 
FlowControl.Branch || ins.OpCode.FlowControl == FlowControl.Cond_Branch) {
-                                               if (ins.OpCode.Code != 
Code.Leave && ins.OpCode.Code != Code.Leave_S) {
-                                                       
LoadAlternatives.AddIfNew (insWithLeave.Copy (ins)); //add if new, avoid 
infinity loop
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-                       return LoadResults.ToArray ();
-               }
-
-               /// <summary>
-               /// Helper method that returns the next Instruction.
-               /// </summary>
-               /// <param name="ins">The instruction</param>
-               /// <param name="alternative">If the instruction is a branch, 
the branch target is returned. For a switch statemant an array of targets is 
returned.</param>
-               /// <returns>The next instruction that would be executed by the 
runtime.</returns>
-               public static Instruction GetNextInstruction (Instruction ins, 
out object alternative)
-               {
-                       alternative = null;
-                       switch (ins.OpCode.FlowControl) {
-                       case FlowControl.Branch:
-                               return (Instruction) ins.Operand;
-                       case FlowControl.Cond_Branch:
-                               alternative = ins.Operand;
-                               return ins.Next;
-                       case FlowControl.Call:
-                       case FlowControl.Next:
-                       case FlowControl.Meta:
-                       case FlowControl.Break: //debugging breakpoint
-                               return ins.Next;
-                       case FlowControl.Return:
-                       case FlowControl.Throw:
-                               return null;
-                       default:
-                               throw new NotImplementedException 
("FlowControl: " + ins.OpCode.FlowControl + " is not supported.");
-
-                       }
-               }
-
-               /// <summary>
-               /// Checks if an instruction is a load and returns the slot it 
loads from.
-               /// </summary>
-               /// <param name="ins">The instruction</param>
-               /// <returns>If the instruction is a load returns the slot to 
load. Check slot.IsNone() to see if this instruction is a load.</returns>
-               private StoreSlot GetLoadSlot (Instruction ins)
-               {
-                       switch (ins.OpCode.Code) {
-                       case Code.Ldloc_0:
-                               return new StoreSlot (StoreType.Local, 0);
-                       case Code.Ldloc_1:
-                               return new StoreSlot (StoreType.Local, 1);
-                       case Code.Ldloc_2:
-                               return new StoreSlot (StoreType.Local, 2);
-                       case Code.Ldloc_3:
-                               return new StoreSlot (StoreType.Local, 3);
-                       case Code.Ldloc_S:
-                       case Code.Ldloc:
-                               return new StoreSlot (StoreType.Local, 
((VariableDefinition) ins.Operand).Index);
-
-                       case Code.Ldfld:
-                               //TODO: we do not check what instance is on the 
stack
-                               return new StoreSlot (StoreType.Field, (int) 
((FieldReference) ins.Operand).MetadataToken.ToUInt ());
-                       case Code.Ldsfld:
-                               return new StoreSlot (StoreType.StaticField, 
(int) ((FieldReference) ins.Operand).MetadataToken.ToUInt ());
-
-                       case Code.Ldarg_0:
-                               return new StoreSlot (StoreType.Argument, 0);
-                       case Code.Ldarg_1:
-                               return new StoreSlot (StoreType.Argument, 1);
-                       case Code.Ldarg_2:
-                               return new StoreSlot (StoreType.Argument, 2);
-                       case Code.Ldarg_3:
-                               return new StoreSlot (StoreType.Argument, 3);
-                       case Code.Ldarg_S:
-                       case Code.Ldarg: {
-                                       int sequence = ((ParameterDefinition) 
ins.Operand).Sequence;
-                                       if (!this.Method.HasThis)
-                                               sequence--;
-                                       return new StoreSlot 
(StoreType.Argument, sequence);
-                               }
-
-                       case Code.Ldind_I:
-                       case Code.Ldind_I1:
-                       case Code.Ldind_I2:
-                       case Code.Ldind_I4:
-                       case Code.Ldind_I8:
-                       case Code.Ldind_R4:
-                       case Code.Ldind_R8:
-                       case Code.Ldind_Ref:
-                       case Code.Ldind_U1:
-                       case Code.Ldind_U2:
-                       case Code.Ldind_U4:
-                               //TODO: improve stack check
-                               while (ins.Previous != null) { //quick fix for 
out parameters.
-                                       ins = ins.Previous;
-                                       StoreSlot last = GetLoadSlot (ins);
-                                       if (last.Type == StoreType.Argument)
-                                               return new StoreSlot 
(StoreType.Out, last.Slot);
-                               }
-                               goto default;
-                       default:
-                               return new StoreSlot (StoreType.None, -1);
-                       }
-               }
-               /// <summary>
-               /// Checks if an instruction is a store and returns the slot.
-               /// </summary>
-               /// <param name="ins">The instruction</param>
-               /// <returns>If the instruction is a store returns the slot to 
store. Check slot.IsNone() to see if this instruction is a store.</returns>
-               private StoreSlot GetStoreSlot (Instruction ins)
-               {
-                       switch (ins.OpCode.Code) {
-                       case Code.Stloc_0:
-                               return new StoreSlot (StoreType.Local, 0);
-                       case Code.Stloc_1:
-                               return new StoreSlot (StoreType.Local, 1);
-                       case Code.Stloc_2:
-                               return new StoreSlot (StoreType.Local, 2);
-                       case Code.Stloc_3:
-                               return new StoreSlot (StoreType.Local, 3);
-                       case Code.Stloc_S:
-                       case Code.Stloc:
-                               return new StoreSlot (StoreType.Local, 
((VariableDefinition) ins.Operand).Index);
-
-                       case Code.Stfld:
-                               //TODO: we do not check what instance is on the 
stack
-                               return new StoreSlot (StoreType.Field, (int) 
((FieldReference) ins.Operand).MetadataToken.ToUInt ());
-                       case Code.Stsfld:
-                               return new StoreSlot (StoreType.StaticField, 
(int) ((FieldReference) ins.Operand).MetadataToken.ToUInt ());
-
-                       case Code.Starg_S: //store arg (not ref / out etc)
-                       case Code.Starg: {
-                                       int sequence = ((ParameterDefinition) 
ins.Operand).Sequence;
-                                       if (!this.Method.HasThis)
-                                               sequence--;
-                                       return new StoreSlot 
(StoreType.Argument, sequence);
-                               }
-
-                       case Code.Stind_I:
-                       case Code.Stind_I1:
-                       case Code.Stind_I2:
-                       case Code.Stind_I4:
-                       case Code.Stind_I8:
-                       case Code.Stind_R4:
-                       case Code.Stind_R8:
-                       case Code.Stind_Ref:
-                               //TODO: improve stack check
-                               while (ins.Previous != null) { //quick fix for 
out parameters.
-                                       ins = ins.Previous;
-                                       StoreSlot last = GetLoadSlot (ins);
-                                       if (last.Type == StoreType.Argument)
-                                               return new StoreSlot 
(StoreType.Out, last.Slot);
-                               }
-                               goto default;
-
-
-
-                       default:
-                               return new StoreSlot (StoreType.None, -1);
-                       }
-               }
-
-               private int GetPopCount (Instruction ins)
-               {
-                       switch (ins.OpCode.StackBehaviourPop) {
-                       case StackBehaviour.Pop0:
-                               return 0;
-
-                       case StackBehaviour.Pop1:
-                       case StackBehaviour.Popi:
-                       case StackBehaviour.Popref:
-                               return 1;
-
-                       case StackBehaviour.Pop1_pop1:
-                       case StackBehaviour.Popi_pop1:
-                       case StackBehaviour.Popi_popi8:
-                       case StackBehaviour.Popi_popr4:
-                       case StackBehaviour.Popi_popr8:
-                       case StackBehaviour.Popref_pop1:
-                       case StackBehaviour.Popref_popi:
-                       case StackBehaviour.Popi_popi:
-                               return 2;
-
-                       case StackBehaviour.Popi_popi_popi:
-                       case StackBehaviour.Popref_popi_popi:
-                       case StackBehaviour.Popref_popi_popi8:
-                       case StackBehaviour.Popref_popi_popr4:
-                       case StackBehaviour.Popref_popi_popr8:
-                       case StackBehaviour.Popref_popi_popref:
-                               return 3;
-
-                       case StackBehaviour.PopAll:
-                               goto default;
-
-                       case StackBehaviour.Varpop:
-                               switch (ins.OpCode.FlowControl) {
-                               case FlowControl.Return:
-                                       return 
this.Method.ReturnType.ReturnType.FullName == "System.Void" ? 0 : 1;
-
-                               case FlowControl.Call:
-                                       IMethodSignature calledMethod = 
(IMethodSignature) ins.Operand;
-                                       if (ins.OpCode.Code != Code.Newobj)
-                                               if (calledMethod.HasThis)
-                                                       return 1 + 
calledMethod.Parameters.Count;
-                                       return calledMethod.Parameters.Count;
-
-                               default:
-                                       throw new NotImplementedException 
("Varpop not supported for this Instruction.");
-                               }
-
-                       default:
-                               throw new NotImplementedException 
(ins.OpCode.StackBehaviourPop + " not supported.");
-                       }
-               }
-
-               private int GetPushCount (Instruction ins)
-               {
-                       switch (ins.OpCode.StackBehaviourPush) {
-                       case StackBehaviour.Push0:
-                               return 0;
-
-                       case StackBehaviour.Push1:
-                       case StackBehaviour.Pushi:
-                       case StackBehaviour.Pushi8:
-                       case StackBehaviour.Pushr4:
-                       case StackBehaviour.Pushr8:
-                       case StackBehaviour.Pushref:
-                               return 1;
-
-                       case StackBehaviour.Push1_push1:
-                               return 2;
-
-                       case StackBehaviour.Varpush:
-                               if (ins.OpCode.Code == Code.Call || 
ins.OpCode.Code == Code.Calli || ins.OpCode.Code == Code.Callvirt) {
-                                       IMethodSignature calledMethod = 
(IMethodSignature) ins.Operand;
-                                       if 
(calledMethod.ReturnType.ReturnType.FullName == "System.Void")
-                                               return 0;
-                                       return 1;
-                               } else {
-                                       throw new NotImplementedException 
("Varpush not supported for this Instruction.");
-                               }
-                       default:
-                               throw new NotImplementedException 
(ins.OpCode.StackBehaviourPush + " not supported.");
-                       }
-               }
-       }
-}

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to