Ejemplo n.º 1
0
        void IILTransform.Run(ILFunction function, ILTransformContext context)
        {
            if (!context.Settings.AnonymousMethods)
            {
                return;
            }
            this.context = context;
            this.decompilationContext = new SimpleTypeResolveContext(function.Method);
            var orphanedVariableInits    = new List <ILInstruction>();
            var targetsToReplace         = new List <IInstructionWithVariableOperand>();
            var translatedDisplayClasses = new HashSet <ITypeDefinition>();

            foreach (var block in function.Descendants.OfType <Block>())
            {
                for (int i = block.Instructions.Count - 1; i >= 0; i--)
                {
                    context.CancellationToken.ThrowIfCancellationRequested();
                    foreach (var call in block.Instructions[i].Descendants.OfType <NewObj>())
                    {
                        ILFunction f = TransformDelegateConstruction(call, out ILInstruction target);
                        if (f != null)
                        {
                            f.AddILRange(call.Arguments[0].ILRange);
                            f.AddILRange(call.Arguments[1].ILRange);
                            call.Arguments[0].ReplaceWith(new LdNull());
                            call.Arguments[1].ReplaceWith(f);
                            if (target is IInstructionWithVariableOperand && !target.MatchLdThis())
                            {
                                targetsToReplace.Add((IInstructionWithVariableOperand)target);
                            }
                        }
                    }
                    if (block.Instructions[i].MatchStLoc(out ILVariable targetVariable, out ILInstruction value))
                    {
                        var newObj = value as NewObj;
                        // TODO : it is probably not a good idea to remove *all* display-classes
                        // is there a way to minimize the false-positives?
                        if (newObj != null && IsInSimpleDisplayClass(newObj.Method))
                        {
                            targetVariable.CaptureScope = FindBlockContainer(block);
                            targetsToReplace.Add((IInstructionWithVariableOperand)block.Instructions[i]);
                            translatedDisplayClasses.Add(newObj.Method.DeclaringTypeDefinition);
                        }
                    }
                }
            }
            foreach (var target in targetsToReplace.OrderByDescending(t => ((ILInstruction)t).ILRange.Start))
            {
                function.AcceptVisitor(new TransformDisplayClassUsages(function, target, target.Variable.CaptureScope, orphanedVariableInits, translatedDisplayClasses));
            }
            foreach (var store in orphanedVariableInits)
            {
                if (store.Parent is Block containingBlock)
                {
                    containingBlock.Instructions.Remove(store);
                }
            }
        }
Ejemplo n.º 2
0
        void IILTransform.Run(ILFunction function, ILTransformContext context)
        {
            if (!context.Settings.AnonymousMethods)
            {
                return;
            }
            this.context = context;
            this.decompilationContext = new SimpleTypeResolveContext(function.Method);
            var orphanedVariableInits    = new List <ILInstruction>();
            var targetsToReplace         = new List <IInstructionWithVariableOperand>();
            var translatedDisplayClasses = new HashSet <ITypeDefinition>();
            var cancellationToken        = context.CancellationToken;

            foreach (var inst in function.Descendants)
            {
                cancellationToken.ThrowIfCancellationRequested();
                if (inst is NewObj call)
                {
                    context.StepStartGroup($"TransformDelegateConstruction {call.StartILOffset}", call);
                    ILFunction f = TransformDelegateConstruction(call, out ILInstruction target);
                    if (f != null && target is IInstructionWithVariableOperand instWithVar)
                    {
                        if (instWithVar.Variable.Kind == VariableKind.Local)
                        {
                            instWithVar.Variable.Kind = VariableKind.DisplayClassLocal;
                        }
                        targetsToReplace.Add(instWithVar);
                    }
                    context.StepEndGroup();
                }
                if (inst.MatchStLoc(out ILVariable targetVariable, out ILInstruction value))
                {
                    var newObj = value as NewObj;
                    // TODO : it is probably not a good idea to remove *all* display-classes
                    // is there a way to minimize the false-positives?
                    if (newObj != null && IsInSimpleDisplayClass(newObj.Method))
                    {
                        targetVariable.CaptureScope = BlockContainer.FindClosestContainer(inst);
                        targetsToReplace.Add((IInstructionWithVariableOperand)inst);
                        translatedDisplayClasses.Add(newObj.Method.DeclaringTypeDefinition);
                    }
                }
            }
            foreach (var target in targetsToReplace.OrderByDescending(t => ((ILInstruction)t).StartILOffset))
            {
                context.Step($"TransformDisplayClassUsages {target.Variable}", (ILInstruction)target);
                function.AcceptVisitor(new TransformDisplayClassUsages(function, target, target.Variable.CaptureScope, orphanedVariableInits, translatedDisplayClasses));
            }
            context.Step($"Remove orphanedVariableInits", function);
            foreach (var store in orphanedVariableInits)
            {
                if (store.Parent is Block containingBlock)
                {
                    containingBlock.Instructions.Remove(store);
                }
            }
        }
Ejemplo n.º 3
0
        internal static void ResetHasInitialValueFlag(ILFunction function, ILTransformContext context)
        {
            var visitor = new DefiniteAssignmentVisitor(function, context.CancellationToken);

            function.AcceptVisitor(visitor);
            foreach (var v in function.Variables)
            {
                if (v.Kind != VariableKind.Parameter && !visitor.IsPotentiallyUsedUninitialized(v))
                {
                    v.HasInitialValue = false;
                }
            }
        }
Ejemplo n.º 4
0
 static void CollectNamespacesFromMethodBody(IMethod method, ILFunction body, HashSet <string> namespaces)
 {
     body.AcceptVisitor(new ILCollectionVisitor(namespaces));
     foreach (var v in body.Variables)
     {
         CollectNamespacesForTypeReference(v.Type, namespaces);
     }
     foreach (var node in body.Descendants)
     {
         if (node is LdsFlda staticField)
         {
             CollectNamespacesForMemberReference(staticField.Field, namespaces);
         }
         else if (node is CallInstruction call && call.Method.IsStatic)
         {
             CollectNamespacesForMemberReference(call.Method, namespaces);
         }
Ejemplo n.º 5
0
 public void Run(ILFunction function, ILTransformContext context)
 {
     cancellationToken = context.CancellationToken;
     currentExit       = NoExit;
     blocksPotentiallyMadeUnreachable.Clear();
     function.AcceptVisitor(this);
     // It's possible that there are unreachable code blocks which we only
     // detect as such during exit point detection.
     // Clean them up.
     foreach (var block in blocksPotentiallyMadeUnreachable)
     {
         if (block.IncomingEdgeCount == 0 || block.IncomingEdgeCount == 1 && IsInfiniteLoop(block))
         {
             block.Remove();
         }
     }
     blocksPotentiallyMadeUnreachable.Clear();
 }
Ejemplo n.º 6
0
 public void Run(ILFunction function, ILTransformContext context)
 {
     cancellationToken = context.CancellationToken;
     currentExit       = NoExit;
     function.AcceptVisitor(this);
 }