コード例 #1
0
 public void Run(ILFunction function, ILTransformContext context)
 {
     try {
         if (this.context != null)
         {
             throw new InvalidOperationException("Reentrancy in " + nameof(TransformDisplayClassUsage));
         }
         this.context = context;
         var decompilationContext = new SimpleTypeResolveContext(context.Function.Method);
         // Traverse nested functions in post-order:
         // Inner functions are transformed before outer functions
         foreach (var f in function.Descendants.OfType <ILFunction>())
         {
             foreach (var v in f.Variables.ToArray())
             {
                 if (context.Settings.YieldReturn && HandleMonoStateMachine(function, v, decompilationContext, f))
                 {
                     continue;
                 }
                 if ((context.Settings.AnonymousMethods || context.Settings.ExpressionTrees) && IsClosure(context, v, out ITypeDefinition closureType, out var inst))
                 {
                     if (!CanRemoveAllReferencesTo(context, v))
                     {
                         continue;
                     }
                     instructionsToRemove.Add(inst);
                     AddOrUpdateDisplayClass(f, v, closureType, inst, localFunctionClosureParameter: false);
                     continue;
                 }
                 if (context.Settings.LocalFunctions && f.Kind == ILFunctionKind.LocalFunction && v.Kind == VariableKind.Parameter && v.Index > -1 && f.Method.Parameters[v.Index.Value] is IParameter p && LocalFunctionDecompiler.IsClosureParameter(p, decompilationContext))
                 {
                     AddOrUpdateDisplayClass(f, v, ((ByReferenceType)p.Type).ElementType.GetDefinition(), f.Body, localFunctionClosureParameter: true);
                     continue;
                 }
                 AnalyzeUseSites(v);
             }
         }
         VisitILFunction(function);
         if (instructionsToRemove.Count > 0)
         {
             context.Step($"Remove instructions", function);
             foreach (var store in instructionsToRemove)
             {
                 if (store.Parent is Block containingBlock)
                 {
                     containingBlock.Instructions.Remove(store);
                 }
             }
         }
         RemoveDeadVariableInit.ResetHasInitialValueFlag(function, context);
     } finally {
         instructionsToRemove.Clear();
         displayClasses.Clear();
         fieldAssignmentsWithVariableValue.Clear();
         this.context = null;
     }
 }
コード例 #2
0
 public void Run(ILFunction function, ILTransformContext context)
 {
     try {
         if (this.context != null || this.currentFunction != null)
         {
             throw new InvalidOperationException("Reentrancy in " + nameof(TransformDisplayClassUsage));
         }
         this.context = context;
         var decompilationContext = new SimpleTypeResolveContext(context.Function.Method);
         // Traverse nested functions in post-order:
         // Inner functions are transformed before outer functions
         foreach (var f in function.Descendants.OfType <ILFunction>())
         {
             foreach (var v in f.Variables.ToArray())
             {
                 if (HandleMonoStateMachine(function, v, decompilationContext, f))
                 {
                     continue;
                 }
                 if (IsClosure(v, out ITypeDefinition closureType, out var inst))
                 {
                     AddOrUpdateDisplayClass(f, v, closureType, inst, localFunctionClosureParameter: false);
                 }
                 if (context.Settings.LocalFunctions && f.Kind == ILFunctionKind.LocalFunction && v.Kind == VariableKind.Parameter && v.Index > -1 && f.Method.Parameters[v.Index.Value] is IParameter p && LocalFunctionDecompiler.IsClosureParameter(p, decompilationContext))
                 {
                     AddOrUpdateDisplayClass(f, v, ((ByReferenceType)p.Type).ElementType.GetDefinition(), f.Body, localFunctionClosureParameter: true);
                 }
             }
             foreach (var displayClass in displayClasses.Values.OrderByDescending(d => d.Initializer.StartILOffset).ToArray())
             {
                 context.Step($"Transform references to " + displayClass.Variable, displayClass.Initializer);
                 this.currentFunction = f;
                 VisitILFunction(f);
             }
         }
         if (instructionsToRemove.Count > 0)
         {
             context.Step($"Remove instructions", function);
             foreach (var store in instructionsToRemove)
             {
                 if (store.Parent is Block containingBlock)
                 {
                     containingBlock.Instructions.Remove(store);
                 }
             }
         }
         RemoveDeadVariableInit.ResetHasInitialValueFlag(function, context);
     } finally {
         instructionsToRemove.Clear();
         displayClasses.Clear();
         this.context         = null;
         this.currentFunction = null;
     }
 }