示例#1
0
        // Depth-first order
        void search(BaseBlock bb)
        {
            if (hasVisited(bb))
                return;

            visited[bb] = true;
            var block = bb as Block;	// Block or ScopeBlock
            if (block != null) {
                // Since the sorted array will be in reverse order, and we want the
                // conditional branches to fall through to their fall-through target, make
                // sure the FallThrough target is added last! Some conditional instructions
                // aren't reversible (eg. beq and bne.un) since they don't take the same
                // types of arguments. This will also make sure .NET Reflector doesn't
                // crash (sometimes).
                var targets = new List<Block>(block.getTargets());
                targets.Reverse();

                foreach (var target in targets) {
                    var child = scopeBlock.toChild(target);
                    if (child != null)
                        search(child);
                }
            }
            sorted.Add(bb);
        }
示例#2
0
        void ScanBaseBlock(BaseBlock bb, int stackStart)
        {
            scanBaseBlockStack.Push(new ScanBaseBlockState(bb, stackStart));
            while (scanBaseBlockStack.Count > 0)
            {
                var state = scanBaseBlockStack.Pop();
                if (blockInfos.ContainsKey(state.bb) || !scopeBlock.IsOurBaseBlock(state.bb))
                {
                    continue;
                }

                var blockInfo = new BlockInfo(state.bb, state.stackStart);
                blockInfos[state.bb] = blockInfo;

                var block = state.bb as Block;
                if (block == null)                      // i.e., if try, filter, or handler block
                // It's not important to know the exact values, so we set them both to 0.
                // Compilers must make sure the stack is empty when entering a try block.
                {
                    blockInfo.stackStart = blockInfo.stackEnd = 0;
                    continue;
                }

                blockInfo.CalculateStackUsage();

                foreach (var target in block.GetTargets())
                {
                    scanBaseBlockStack.Push(new ScanBaseBlockState(target, blockInfo.stackEnd));
                }
            }
        }
示例#3
0
 // Add a block to be processed later, including all its enclosing ScopeBlocks.
 void addBaseBlock(BaseBlock baseBlock)
 {
     for (BaseBlock bb = baseBlock; bb != null; bb = bb.Parent)
     {
         baseBlocksToCheck.Push(bb);
     }
 }
        void addToNewList(BaseBlock bb)
        {
            if (inNewList.ContainsKey(bb) || !scopeBlock.isOurBaseBlock(bb))
                return;
            inNewList[bb] = false;

            var blockInfo = blockInfos[bb];
            var block = bb as Block;
            if (blockInfo.stackStart == 0 || ReferenceEquals(bb, sorted[0]) ||
                block == null || block.Sources == null || isInNewList(block.Sources)) {
            }
            else {
                foreach (var source in block.Sources) {
                    if (!scopeBlock.isOurBaseBlock(source))
                        continue;
                    int oldCount = newList.Count;
                    addToNewList(source);	// Make sure it's before this block
                    if (oldCount != newList.Count)
                        break;
                }
            }

            inNewList[bb] = true;
            newList.Add(bb);
        }
        void doBaseBlock(BaseBlock bb)
        {
            BlockState current = stateStack.Peek();
            ScopeBlock newOne = getScopeBlock(bb);
            if (newOne == null)
                return;		// Not a BaseBlock somewhere inside this ScopeBlock
            if (newOne != current.scopeBlock)
                bb = newOne;

            bool hasVisited;
            if (!visited.TryGetValue(bb, out hasVisited))
                visited[bb] = hasVisited = false;
            if (hasVisited)
                return;
            visited[bb] = true;

            if (bb is Block)
                doBlock(bb as Block);
            else if (bb is TryBlock)
                doTryBlock(bb as TryBlock);
            else if (bb is FilterHandlerBlock)
                doFilterHandlerBlock(bb as FilterHandlerBlock);
            else if (bb is HandlerBlock)
                doHandlerBlock(bb as HandlerBlock);
            else if (bb is TryHandlerBlock) {
                // The try handler block is usually after the try block, but sometimes it isn't...
                // Handle that case here.
                visited.Remove(bb);
                notProcessedYet.Add(bb);
            }
            else
                throw new ApplicationException("Invalid block found");
        }
示例#6
0
        void AddToNewList(BaseBlock bb)
        {
            if (inNewList.ContainsKey(bb) || !scopeBlock.IsOurBaseBlock(bb))
            {
                return;
            }
            inNewList[bb] = false;

            var blockInfo = blockInfos[bb];
            var block     = bb as Block;

            if (blockInfo.stackStart == 0 || ReferenceEquals(bb, sorted[0]) ||
                block == null || block.Sources == null || IsInNewList(block.Sources))
            {
            }
            else
            {
                foreach (var source in block.Sources)
                {
                    if (!scopeBlock.IsOurBaseBlock(source))
                    {
                        continue;
                    }
                    int oldCount = newList.Count;
                    AddToNewList(source);                       // Make sure it's before this block
                    if (oldCount != newList.Count)
                    {
                        break;
                    }
                }
            }

            inNewList[bb] = true;
            newList.Add(bb);
        }
示例#7
0
        void processBaseBlock(BaseBlock baseBlock)
        {
            if (baseBlock == null || checkedBaseBlocks.ContainsKey(baseBlock))
            {
                return;
            }
            checkedBaseBlocks[baseBlock] = true;

            if (baseBlock is Block)
            {
                var block = (Block)baseBlock;
                foreach (var block2 in block.getTargets())
                {
                    addBaseBlock(block2);
                }
            }
            else if (baseBlock is ScopeBlock)
            {
                var scopeBlock = (ScopeBlock)baseBlock;
                addScopeBlock(scopeBlock);
                if (scopeBlock.BaseBlocks != null && scopeBlock.BaseBlocks.Count > 0)
                {
                    addBaseBlock(scopeBlock.BaseBlocks[0]);
                }
            }
            else
            {
                throw new ApplicationException(string.Format("Unknown BaseBlock type {0}", baseBlock.GetType()));
            }
        }
示例#8
0
 bool hasVisited(BaseBlock bb)
 {
     bool hasVisited;
     if (visited.TryGetValue(bb, out hasVisited))
         return hasVisited;
     visited[bb] = false;
     return false;
 }
示例#9
0
            public List <BaseBlock> Sort()
            {
                if (validBlocks.Count == 0)
                {
                    return(new List <BaseBlock>());
                }
                if (skipFirstBlock)
                {
                    firstBlock = validBlocks[0];
                }

                foreach (var block in validBlocks)
                {
                    if (block != firstBlock)
                    {
                        blockToInfo[block] = new BlockInfo(block);
                    }
                }

                sorted = new List <BaseBlock>(validBlocks.Count);
                var finalList = new List <BaseBlock>(validBlocks.Count);

                if (firstBlock is Block)
                {
                    foreach (var target in GetTargets(firstBlock))
                    {
                        Visit(target);
                        finalList.AddRange(sorted);
                        sorted.Clear();
                    }
                }
                foreach (var bb in validBlocks)
                {
                    Visit(bb);
                    finalList.AddRange(sorted);
                    sorted.Clear();
                }

                if (stack.Count > 0)
                {
                    throw new ApplicationException("Stack isn't empty");
                }

                if (firstBlock != null)
                {
                    finalList.Insert(0, firstBlock);
                }
                else if (validBlocks[0] != finalList[0])
                {
                    // Make sure the original first block is first
                    int index = finalList.IndexOf(validBlocks[0]);
                    finalList.RemoveAt(index);
                    finalList.Insert(0, validBlocks[0]);
                }
                return(finalList);
            }
        // Returns the BaseBlock's ScopeBlock. The return value is either current ScopeBlock,
        // the ScopeBlock one step below current (current one's child), or null.
        ScopeBlock getScopeBlock(BaseBlock bb)
        {
            BlockState current = stateStack.Peek();

            if (current.scopeBlock.isOurBaseBlock(bb))
            {
                return(current.scopeBlock);
            }
            return((ScopeBlock)current.scopeBlock.toChild(bb));
        }
示例#11
0
 BlockInfo GetInfo(BaseBlock baseBlock)
 {
     baseBlock = scopeBlock.ToChild(baseBlock);
     if (baseBlock == null)
     {
         return(null);
     }
     blockToInfo.TryGetValue(baseBlock, out var info);
     return(info);
 }
        void doBaseBlock(BaseBlock bb)
        {
            BlockState current = stateStack.Peek();
            ScopeBlock newOne  = getScopeBlock(bb);

            if (newOne == null)
            {
                return;                         // Not a BaseBlock somewhere inside this ScopeBlock
            }
            if (newOne != current.scopeBlock)
            {
                bb = newOne;
            }

            bool hasVisited;

            if (!visited.TryGetValue(bb, out hasVisited))
            {
                visited[bb] = hasVisited = false;
            }
            if (hasVisited)
            {
                return;
            }
            visited[bb] = true;

            if (bb is Block)
            {
                doBlock(bb as Block);
            }
            else if (bb is TryBlock)
            {
                doTryBlock(bb as TryBlock);
            }
            else if (bb is FilterHandlerBlock)
            {
                doFilterHandlerBlock(bb as FilterHandlerBlock);
            }
            else if (bb is HandlerBlock)
            {
                doHandlerBlock(bb as HandlerBlock);
            }
            else if (bb is TryHandlerBlock)
            {
                // The try handler block is usually after the try block, but sometimes it isn't...
                // Handle that case here.
                visited.Remove(bb);
                notProcessedYet.Add(bb);
            }
            else
            {
                throw new ApplicationException("Invalid block found");
            }
        }
            BlockInfo getInfo(BaseBlock baseBlock)
            {
                baseBlock = scopeBlock.toChild(baseBlock);
                if (baseBlock == null)
                {
                    return(null);
                }
                BlockInfo info;

                blockToInfo.TryGetValue(baseBlock, out info);
                return(info);
            }
示例#14
0
 public void add(BaseBlock bb, int start, int end)
 {
     if (start < 0 || end < 0 || end < start)
     {
         throw new ApplicationException("Invalid start and/or end index");
     }
     if (blocksLeft.Count != 0)
     {
         var bbi = blocksLeft[blocksLeft.Count - 1];
         if (bbi.endInstr + 1 != start)
         {
             throw new ApplicationException("Previous BaseBlock does not end where this new one starts");
         }
     }
     blocksLeft.Add(new BaseBlockInfo(start, end, bb));
 }
示例#15
0
        // If bb is in baseBlocks (a direct child), return bb. If bb is a BaseBlock in a
        // ScopeBlock that is a direct child, then return that ScopeBlock. Else return null.
        public BaseBlock toChild(BaseBlock bb)
        {
            if (isOurBaseBlock(bb))
            {
                return(bb);
            }

            for (var sb = bb.Parent; sb != null; sb = sb.Parent)
            {
                if (isOurBaseBlock(sb))
                {
                    return(sb);
                }
            }

            return(null);
        }
示例#16
0
            void Visit(BaseBlock bb)
            {
                var info = GetInfo(bb);

                if (info == null)
                {
                    return;
                }
                if (info.baseBlock == firstBlock)
                {
                    return;
                }
                if (info.Visited())
                {
                    return;
                }
                Visit(info);
            }
示例#17
0
			public List<BaseBlock> Sort() {
				if (validBlocks.Count == 0)
					return new List<BaseBlock>();
				if (skipFirstBlock)
					firstBlock = validBlocks[0];

				foreach (var block in validBlocks) {
					if (block != firstBlock)
						blockToInfo[block] = new BlockInfo(block);
				}

				sorted = new List<BaseBlock>(validBlocks.Count);
				var finalList = new List<BaseBlock>(validBlocks.Count);

				if (firstBlock is Block) {
					foreach (var target in GetTargets(firstBlock)) {
						Visit(target);
						finalList.AddRange(sorted);
						sorted.Clear();
					}
				}
				foreach (var bb in validBlocks) {
					Visit(bb);
					finalList.AddRange(sorted);
					sorted.Clear();
				}

				if (stack.Count > 0)
					throw new ApplicationException("Stack isn't empty");

				if (firstBlock != null)
					finalList.Insert(0, firstBlock);
				else if (validBlocks[0] != finalList[0]) {
					// Make sure the original first block is first
					int index = finalList.IndexOf(validBlocks[0]);
					finalList.RemoveAt(index);
					finalList.Insert(0, validBlocks[0]);
				}
				return finalList;
			}
示例#18
0
            List <BaseBlock> GetTargets(BaseBlock baseBlock)
            {
                var list = new List <BaseBlock>();

                if (baseBlock is Block block)
                {
                    AddTargets(list, block.GetTargets());
                }
                else if (baseBlock is TryBlock)
                {
                    AddTargets(list, (TryBlock)baseBlock);
                }
                else if (baseBlock is TryHandlerBlock)
                {
                    AddTargets(list, (TryHandlerBlock)baseBlock);
                }
                else
                {
                    AddTargets(list, (ScopeBlock)baseBlock);
                }

                return(list);
            }
 // Add a block to be processed later, including all its enclosing ScopeBlocks.
 void addBaseBlock(BaseBlock baseBlock)
 {
     for (BaseBlock bb = baseBlock; bb != null; bb = bb.Parent)
         baseBlocksToCheck.Push(bb);
 }
示例#20
0
        void doBaseBlock(BaseBlock bb)
        {
            BlockState current = stateStack.Peek();
            ScopeBlock newOne = getScopeBlock(bb);
            if (newOne == null)
                return;		// Not a BaseBlock somewhere inside this ScopeBlock
            if (newOne != current.scopeBlock)
                bb = newOne;

            bool hasVisited;
            if (!visited.TryGetValue(bb, out hasVisited))
                visited[bb] = hasVisited = false;
            if (hasVisited)
                return;
            visited[bb] = true;

            if (bb is Block)
                doBlock(bb as Block);
            else if (bb is TryBlock)
                doTryBlock(bb as TryBlock);
            else if (bb is FilterHandlerBlock)
                doFilterHandlerBlock(bb as FilterHandlerBlock);
            else if (bb is HandlerBlock)
                doHandlerBlock(bb as HandlerBlock);
            else
                throw new ApplicationException("Invalid block found");
        }
示例#21
0
			void Visit(BaseBlock bb) {
				var info = GetInfo(bb);
				if (info == null)
					return;
				if (info.baseBlock == firstBlock)
					return;
				if (info.Visited())
					return;
				Visit(info);
			}
示例#22
0
			List<BaseBlock> GetTargets(BaseBlock baseBlock) {
				var list = new List<BaseBlock>();

				if (baseBlock is Block) {
					var block = (Block)baseBlock;
					AddTargets(list, block.GetTargets());
				}
				else if (baseBlock is TryBlock)
					AddTargets(list, (TryBlock)baseBlock);
				else if (baseBlock is TryHandlerBlock)
					AddTargets(list, (TryHandlerBlock)baseBlock);
				else
					AddTargets(list, (ScopeBlock)baseBlock);

				return list;
			}
示例#23
0
			BlockInfo GetInfo(BaseBlock baseBlock) {
				baseBlock = scopeBlock.ToChild(baseBlock);
				if (baseBlock == null)
					return null;
				BlockInfo info;
				blockToInfo.TryGetValue(baseBlock, out info);
				return info;
			}
示例#24
0
 public bool isOurBaseBlock(BaseBlock bb)
 {
     return(bb != null && bb.Parent == this);
 }
示例#25
0
        // Returns the BaseBlock's ScopeBlock. The return value is either current ScopeBlock,
        // the ScopeBlock one step below current (current one's child), or null.
        ScopeBlock getScopeBlock(BaseBlock bb)
        {
            BlockState current = stateStack.Peek();

            if (current.scopeBlock.isOurBlockBase(bb))
                return current.scopeBlock;
            return (ScopeBlock)current.scopeBlock.toChild(bb);
        }
示例#26
0
 public ScanBaseBlockState(BaseBlock bb, int stackStart)
 {
     this.bb         = bb;
     this.stackStart = stackStart;
 }
				public BaseBlockInfo(int start, int end, BaseBlock bb) {
					startInstr = start;
					endInstr = end;
					baseBlock = bb;
				}
 public BlockInfo(BaseBlock baseBlock, int stackStart)
 {
     this.baseBlock = baseBlock;
     this.stackStart = stackStart;
 }
示例#29
0
 public BlockInfo(BaseBlock baseBlock) => this.baseBlock = baseBlock;
        void scanBaseBlock(BaseBlock bb, int stackStart)
        {
            if (blockInfos.ContainsKey(bb) || !scopeBlock.isOurBaseBlock(bb))
                return;

            var blockInfo = new BlockInfo(bb, stackStart);
            blockInfos[bb] = blockInfo;

            var block = bb as Block;
            if (block == null) {	// i.e., if try, filter, or handler block
                // It's not important to know the exact values, so we set them both to 0.
                // Compilers must make sure the stack is empty when entering a try block.
                blockInfo.stackStart = blockInfo.stackEnd = 0;
                return;
            }

            blockInfo.calculateStackUsage();

            foreach (var target in block.getTargets())
                scanBaseBlock(target, blockInfo.stackEnd);
        }
		// Returns the BaseBlock's ScopeBlock. The return value is either current ScopeBlock,
		// the ScopeBlock one step below current (current one's child), or null.
		ScopeBlock GetScopeBlock(BaseBlock bb) {
			BlockState current = stateStack.Peek();

			if (current.scopeBlock.IsOurBaseBlock(bb))
				return current.scopeBlock;
			return (ScopeBlock)current.scopeBlock.ToChild(bb);
		}
示例#32
0
			public ScanBaseBlockState(BaseBlock bb, int stackStart) {
				this.bb = bb;
				this.stackStart = stackStart;
			}
示例#33
0
 public List<BaseBlock> getBlocks(BaseBlock parent)
 {
     if (blocksLeft.Count == 0)
         return new List<BaseBlock>();
     int startIndex, endIndex;
     var lb = getBlocks(0, blocksLeft[blocksLeft.Count - 1].endInstr, out startIndex, out endIndex);
     return updateParent(lb, parent);
 }
示例#34
0
            // Replace the BaseBlocks with a new BaseBlock, returning the old ones.
            public List<BaseBlock> replace(int startInstr, int endInstr, BaseBlock bb)
            {
                int startIndex, endIndex;
                var rv = getBlocks(startInstr, endInstr, out startIndex, out endIndex);
                updateParent(rv, bb);

                var bbi = new BaseBlockInfo(blocksLeft[startIndex].startInstr, blocksLeft[endIndex].endInstr, bb);
                blocksLeft.RemoveRange(startIndex, endIndex - startIndex + 1);
                blocksLeft.Insert(startIndex, bbi);

                return rv;
            }
示例#35
0
 void visit(BaseBlock bb)
 {
     var info = getInfo(bb);
     if (info == null)
         return;
     if (info.baseBlock == firstBlock)
         return;
     if (info.visited())
         return;
     visit(info);
 }
        void processBaseBlock(BaseBlock baseBlock)
        {
            if (baseBlock == null || checkedBaseBlocks.ContainsKey(baseBlock))
                return;
            checkedBaseBlocks[baseBlock] = true;

            if (baseBlock is Block) {
                var block = (Block)baseBlock;
                foreach (var block2 in block.getTargets())
                    addBaseBlock(block2);
            }
            else if (baseBlock is ScopeBlock) {
                var scopeBlock = (ScopeBlock)baseBlock;
                addScopeBlock(scopeBlock);
                if (scopeBlock.BaseBlocks != null && scopeBlock.BaseBlocks.Count > 0)
                    addBaseBlock(scopeBlock.BaseBlocks[0]);
            }
            else
                throw new ApplicationException(string.Format("Unknown BaseBlock type {0}", baseBlock.GetType()));
        }
示例#37
0
 public BlockInfo(BaseBlock baseBlock, int stackStart)
 {
     this.baseBlock  = baseBlock;
     this.stackStart = stackStart;
 }
示例#38
0
 public BaseBlockInfo(int start, int end, BaseBlock bb)
 {
     startInstr = start;
     endInstr   = end;
     baseBlock  = bb;
 }
			public void Add(BaseBlock bb, int start, int end) {
				if (start < 0 || end < 0 || end < start)
					throw new ApplicationException("Invalid start and/or end index");
				if (blocksLeft.Count != 0) {
					var bbi = blocksLeft[blocksLeft.Count - 1];
					if (bbi.endInstr + 1 != start)
						throw new ApplicationException("Previous BaseBlock does not end where this new one starts");
				}
				blocksLeft.Add(new BaseBlockInfo(start, end, bb));
			}
示例#40
0
			public BlockInfo(BaseBlock baseBlock) {
				this.baseBlock = baseBlock;
			}
示例#41
0
		void ScanBaseBlock(BaseBlock bb, int stackStart) {
			scanBaseBlockStack.Push(new ScanBaseBlockState(bb, stackStart));
			while (scanBaseBlockStack.Count > 0) {
				var state = scanBaseBlockStack.Pop();
				if (blockInfos.ContainsKey(state.bb) || !scopeBlock.IsOurBaseBlock(state.bb))
					continue;

				var blockInfo = new BlockInfo(state.bb, state.stackStart);
				blockInfos[state.bb] = blockInfo;

				var block = state.bb as Block;
				if (block == null) {	// i.e., if try, filter, or handler block
					// It's not important to know the exact values, so we set them both to 0.
					// Compilers must make sure the stack is empty when entering a try block.
					blockInfo.stackStart = blockInfo.stackEnd = 0;
					continue;
				}

				blockInfo.CalculateStackUsage();

				foreach (var target in block.GetTargets())
					scanBaseBlockStack.Push(new ScanBaseBlockState(target, blockInfo.stackEnd));
			}
		}
示例#42
0
 List<BaseBlock> updateParent(List<BaseBlock> lb, BaseBlock parent)
 {
     foreach (var bb in lb)
         bb.Parent = parent;
     return lb;
 }