Пример #1
0
 private static void ProcessNameOfCallInstruction(Instruction instruction, ILProcessor ilProcessor)
 {
     var instructions = instruction.AsReverseEnumerable().Take(patterns.Value.First().Length).ToArray(); // Take an instruction set with a maximum size of the longest pattern.
     Boolean possibleMatch = false;
     PatternInstruction[] patternMatched = null;
     Func<String> terminal = null;
     foreach (var pattern in patterns.Value) {
         possibleMatch = true;
         terminal = null;
         for (Int32 i = 0, j = 0; i < pattern.Length && j < instructions.Length; ++i, ++j) {
             while (pattern[i] is OptionalPatternInstruction && !pattern[i].EligibleOpCodes.Contains(instructions[j].OpCode))
                 ++i;
             var patternInstruction = pattern[i];
             var currentInstruction = instructions[j];
             if (patternInstruction.EligibleOpCodes.Contains(currentInstruction.OpCode) && patternInstruction.IsPredicated(currentInstruction, ilProcessor)) {
                 if (patternInstruction.Terminal != null && terminal == null)
                     terminal = () => patternInstruction.Terminal(currentInstruction, ilProcessor);
                 if (patternInstruction.Action != null)
                     patternInstruction.Action(currentInstruction);
             }
             else {
                 possibleMatch = false;
                 break;
             }
         }
         if (possibleMatch && pattern.Count(x => !(x is OptionalPatternInstruction)) <= instructions.Length) {
             patternMatched = pattern;
             break;
         }
     }
     if (!possibleMatch)
         throw GetNotSupportedException(instruction); // The usage of Name.Of is not supported
     if (terminal == null)
         throw new NotImplementedException("There is no terminal expression implemented for the matched pattern.");
     String name;
     try {
         name = terminal();
         if (IsNullOrWhiteSpace(name))
             throw new Exception("Name not found.");
     }
     catch {
         throw GetNotSupportedException(instruction);
     }
     // TODO: Remove the anonymous methods generated by lamdba expressions in some uses of Name.Of...
     ilProcessor.InsertAfter(instruction, Instruction.Create(OpCodes.Ldstr, name));
     for (Int32 i = 0, j = 0; i < patternMatched.Length && j < instructions.Length; ++i, ++j) {
         while (patternMatched[i] is OptionalPatternInstruction && !patternMatched[i].EligibleOpCodes.Contains(instructions[j].OpCode))
             ++i;
         ilProcessor.Remove(instructions[j]);
     }
 }