Exemplo n.º 1
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].ILRange);
                     block.Instructions[i] = copiedExpr;
                 }
             }
             else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr))
             {
                 DoPropagate(v, copiedExpr, block, ref i, context);
             }
         }
     }
 }
Exemplo n.º 2
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 (copiedExpr.Flags == InstructionFlags.None)
                 {
                     // no-op -> delete
                     block.Instructions.RemoveAt(i--);
                 }
                 else
                 {
                     // evaluate the value for its side-effects
                     block.Instructions[i] = copiedExpr;
                 }
             }
             else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr))
             {
                 DoPropagate(v, copiedExpr, block, ref i, context);
             }
         }
     }
 }
Exemplo n.º 3
0
 void IBlockTransform.Run(Block block, BlockTransformContext context)
 {
     this.context = context;
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         if (TransformPostIncDecOperatorOnAddress(block, i) || TransformPostIncDecOnStaticField(block, i) || TransformCSharp4PostIncDecOperatorOnAddress(block, i))
         {
             block.Instructions.RemoveAt(i);
             continue;
         }
         if (TransformPostIncDecOperator(block, i))
         {
             block.Instructions.RemoveAt(i);
             continue;
         }
         if (TransformInlineAssignmentStObj(block, i))
         {
             continue;
         }
         if (TransformInlineCompoundAssignmentCall(block, i))
         {
             continue;
         }
         if (TransformRoslynCompoundAssignmentCall(block, i))
         {
             continue;
         }
     }
 }
Exemplo n.º 4
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;
         }
     }
 }
Exemplo n.º 5
0
 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;
             }
         }
     }
 }
Exemplo n.º 6
0
 void IBlockTransform.Run(Block block, BlockTransformContext context)
 {
     this.context = context;
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         DoTransform(block, i);
     }
 }
Exemplo n.º 7
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--;
                }
            }
            // This invariant can be surprisingly expensive to check if the block has thousands
            // of instructions and is frequently modified by transforms (invalidating the flags each time)
            // so we'll check this only once at the end of the block.
            Debug.Assert(block.HasFlag(InstructionFlags.EndPointUnreachable));
        }
Exemplo n.º 8
0
 void IBlockTransform.Run(Block block, BlockTransformContext context)
 {
     this.context = context;
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         if (TransformNullCoalescing(block, i))
         {
             block.Instructions.RemoveAt(i);
             continue;
         }
     }
 }
Exemplo n.º 9
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)
                {
                    Debug.Assert(block.HasFlag(InstructionFlags.EndPointUnreachable));
                    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--;
                }
            }
        }
Exemplo n.º 10
0
        public void Run(ILFunction function, ILTransformContext context)
        {
            var blockContext = new BlockTransformContext(context);

            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?
            }
        }
 void IBlockTransform.Run(Block block, BlockTransformContext context)
 {
     this.context = context;
     for (int i = block.Instructions.Count - 1; i >= 0; i--)
     {
         DoTransform(block, i);
         // This happens in some cases:
         // Use correct index after transformation.
         if (i >= block.Instructions.Count)
         {
             i = block.Instructions.Count;
         }
     }
 }
Exemplo n.º 12
0
		public void Run(ILFunction function, ILTransformContext context)
		{
			if (running)
				throw new InvalidOperationException("Reentrancy detected. Transforms (and the CSharpDecompiler) are neither 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;
			}
		}
Exemplo n.º 13
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;
         }
     }
 }
Exemplo n.º 14
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();
		}
Exemplo n.º 15
0
 public void Run(Block block, BlockTransformContext context)
 {
     if (running)
     {
         throw new InvalidOperationException("LoopingBlockTransform already running. Transforms (and the CSharpDecompiler) are neither 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;
     }
 }
Exemplo n.º 16
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))
         {
             continue;
         }
         if (TransformUsingVB(block, i))
         {
             continue;
         }
         if (TransformAsyncUsing(block, i))
         {
             continue;
         }
     }
 }
Exemplo n.º 17
0
 public void Run(Block block, BlockTransformContext context)
 {
     InlineAllInBlock(context.Function, block, context);
 }
Exemplo n.º 18
0
        internal static bool IsPotentialClosure(BlockTransformContext context, NewObj inst)
        {
            var decompilationContext = new SimpleTypeResolveContext(context.TypeSystem.Resolve(context.Function.Method));

            return(IsPotentialClosure(decompilationContext.CurrentTypeDefinition, inst.Method.DeclaringTypeDefinition));
        }
Exemplo n.º 19
0
 public void Run(Block block, BlockTransformContext context)
 {
     new NullableLiftingTransform(context).RunBlock(block);
 }
Exemplo n.º 20
0
 public void Run(Block block, BlockTransformContext context)
 {
     InlineAllInBlock(block, context);
 }
Exemplo n.º 21
0
 public void Run(Block block, BlockTransformContext context)
 {
     RunOnBlock(block, context);
 }
Exemplo n.º 22
0
 public void Run(Block block, BlockTransformContext context)
 {
     this.context = context;
     Default(block);
 }
Exemplo n.º 23
0
 public StatementTransformContext(BlockTransformContext blockContext) : base(blockContext)
 {
     this.BlockContext = blockContext ?? throw new ArgumentNullException(nameof(blockContext));
 }