Пример #1
0
 void IBlockTransform.Run(Block block, BlockTransformContext context)
 {
     if (!context.Settings.LockStatement)
     {
         return;
     }
     this.context = context;
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         if (!TransformLockRoslyn(block, i))
         {
             if (!TransformLockV4(block, i))
             {
                 if (!TransformLockV2(block, i))
                 {
                     TransformLockMCS(block, i);
                 }
             }
         }
         // This happens in some cases:
         // Use correct index after transformation.
         if (i >= block.Instructions.Count)
         {
             i = block.Instructions.Count;
         }
     }
 }
 public void Run(Block block, BlockTransformContext context)
 {
     this.context = context;
     if (!context.Settings.AnonymousMethods)
     {
         return;
     }
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         if (block.Instructions[i] is IfInstruction inst)
         {
             if (CachedDelegateInitializationWithField(inst))
             {
                 block.Instructions.RemoveAt(i);
                 continue;
             }
             if (CachedDelegateInitializationWithLocal(inst))
             {
                 ILInlining.InlineOneIfPossible(block, i, InliningOptions.Aggressive, context);
                 continue;
             }
             if (CachedDelegateInitializationRoslynInStaticWithLocal(inst) || CachedDelegateInitializationRoslynWithLocal(inst))
             {
                 block.Instructions.RemoveAt(i);
                 continue;
             }
         }
     }
 }
Пример #3
0
 public void Run(Block block, BlockTransformContext context)
 {
     for (int i = 0; i < block.Instructions.Count; i++)
     {
         ILVariable    v;
         ILInstruction copiedExpr;
         if (block.Instructions[i].MatchStLoc(out v, out copiedExpr))
         {
             if (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot)
             {
                 // dead store to stack
                 if (SemanticHelper.IsPure(copiedExpr.Flags))
                 {
                     // no-op -> delete
                     context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i]);
                     block.Instructions.RemoveAt(i--);
                 }
                 else
                 {
                     // evaluate the value for its side-effects
                     context.Step("remove dead store to stack: evaluate the value for its side-effects", block.Instructions[i]);
                     copiedExpr.AddILRange(block.Instructions[i]);
                     block.Instructions[i] = copiedExpr;
                 }
             }
             else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr))
             {
                 DoPropagate(v, copiedExpr, block, ref i, context);
             }
         }
     }
 }
Пример #4
0
        public void Run(Block block, BlockTransformContext context)
        {
            var ctx = new StatementTransformContext(context);
            int pos = 0;

            ctx.rerunPosition = block.Instructions.Count - 1;
            while (pos >= 0)
            {
                if (ctx.rerunPosition != null)
                {
                    Debug.Assert(ctx.rerunPosition >= pos);
#if DEBUG
                    for (; pos < ctx.rerunPosition; ++pos)
                    {
                        block.Instructions[pos].ResetDirty();
                    }
#else
                    pos = ctx.rerunPosition.Value;
#endif
                    Debug.Assert(pos == ctx.rerunPosition);
                    ctx.rerunPosition = null;
                }
                foreach (var transform in children)
                {
                    transform.Run(block, pos, ctx);
#if DEBUG
                    block.Instructions[pos].CheckInvariant(ILPhase.Normal);
                    for (int i = Math.Max(0, pos - 100); i < pos; ++i)
                    {
                        if (block.Instructions[i].IsDirty)
                        {
                            Debug.Fail($"{transform.GetType().Name} modified an instruction before pos");
                        }
                    }
#endif
                    if (ctx.rerunCurrentPosition)
                    {
                        ctx.rerunCurrentPosition = false;
                        ctx.RequestRerun(pos);
                    }
                    if (ctx.rerunPosition != null)
                    {
                        break;
                    }
                }
                if (ctx.rerunPosition == null)
                {
                    pos--;
                }
            }
        }
Пример #5
0
 void IBlockTransform.Run(Block block, BlockTransformContext context)
 {
     if (!context.Settings.UsingStatement)
     {
         return;
     }
     this.context = context;
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         if (!TransformUsing(block, i) && !TransformUsingVB(block, i))
         {
             continue;
         }
         // This happens in some cases:
         // Use correct index after transformation.
         if (i >= block.Instructions.Count)
         {
             i = block.Instructions.Count;
         }
     }
 }
Пример #6
0
 public void Run(ILFunction function, ILTransformContext context)
 {
     if (running)
     {
         throw new InvalidOperationException("Reentrancy detected. Transforms (and the CSharpDecompiler) are neither thread-safe nor re-entrant.");
     }
     try {
         running = true;
         var blockContext = new BlockTransformContext(context);
         Debug.Assert(blockContext.Function == function);
         foreach (var container in function.Descendants.OfType <BlockContainer>().ToList())
         {
             context.CancellationToken.ThrowIfCancellationRequested();
             blockContext.ControlFlowGraph = new ControlFlowGraph(container, context.CancellationToken);
             VisitBlock(blockContext.ControlFlowGraph.GetNode(container.EntryPoint), blockContext);
             // TODO: handle unreachable code?
         }
     } finally {
         running = false;
     }
 }
Пример #7
0
 public void Run(Block block, BlockTransformContext context)
 {
     if (running)
     {
         throw new InvalidOperationException("LoopingBlockTransform already running. Transforms (and the CSharpDecompiler) are neither thread-safe nor re-entrant.");
     }
     running = true;
     try {
         int count = 1;
         do
         {
             block.ResetDirty();
             block.RunTransforms(children, context);
             if (block.IsDirty)
             {
                 context.Step($"Block is dirty; running loop iteration #{++count}.", block);
             }
         } while (block.IsDirty);
     } finally {
         running = false;
     }
 }
Пример #8
0
        void VisitBlock(ControlFlowNode cfgNode, BlockTransformContext context)
        {
            Block block = (Block)cfgNode.UserData;

            context.StepStartGroup(block.Label, block);

            context.ControlFlowNode = cfgNode;
            context.Block           = block;
            block.RunTransforms(PreOrderTransforms, context);

            // First, process the children in the dominator tree.
            // The ConditionDetection transform requires dominated blocks to
            // be already processed.
            foreach (var child in cfgNode.DominatorTreeChildren)
            {
                VisitBlock(child, context);
            }

            context.ControlFlowNode = cfgNode;
            context.Block           = block;
            block.RunTransforms(PostOrderTransforms, context);
            context.StepEndGroup();
        }
Пример #9
0
 public void Run(Block block, BlockTransformContext context)
 {
     InlineAllInBlock(context.Function, block, context);
 }
Пример #10
0
 public StatementTransformContext(BlockTransformContext blockContext) : base(blockContext)
 {
     this.BlockContext = blockContext ?? throw new ArgumentNullException(nameof(blockContext));
 }