예제 #1
0
		/// <summary>
		///     Computes a key sequence of the given CFG.
		/// </summary>
		/// <param name="graph">The CFG.</param>
		/// <param name="random">The random source, or <c>null</c> if key id is needed.</param>
		/// <returns>The generated key sequence of the CFG.</returns>
		public static BlockKey[] ComputeKeys(ControlFlowGraph graph, RandomGenerator random) {
			var keys = new BlockKey[graph.Count];

			foreach (ControlFlowBlock block in graph) {
				var key = new BlockKey();
				if ((block.Type & ControlFlowBlockType.Entry) != 0)
					key.Type = BlockKeyType.Explicit;
				else
					key.Type = BlockKeyType.Incremental;
				keys[block.Id] = key;
			}
			ProcessBlocks(keys, graph, random);
			return keys;
		}
예제 #2
0
        private static void ProcessBlocks(BlockKey[] keys, ControlFlowGraph graph, RandomGenerator random)
        {
            uint id = 0;

            for (int i = 0; i < keys.Length; i++)
            {
                keys[i].EntryState = id++;
                keys[i].ExitState  = id++;
            }

            var finallyIds = new Dictionary <ExceptionHandler, uint>();
            var ehMap      = new Dictionary <ControlFlowBlock, List <ExceptionHandler> >();

            bool updated;

            do
            {
                updated = false;

                // Update the state ids with the maximum id
                foreach (ControlFlowBlock block in graph)
                {
                    BlockKey key = keys[block.Id];
                    if (block.Sources.Count > 0)
                    {
                        uint newEntry = block.Sources.Select(b => keys[b.Id].ExitState).Max();
                        if (key.EntryState != newEntry)
                        {
                            key.EntryState = newEntry;
                            updated        = true;
                        }
                    }
                    if (block.Targets.Count > 0)
                    {
                        uint newExit = block.Targets.Select(b => keys[b.Id].EntryState).Max();
                        if (key.ExitState != newExit)
                        {
                            key.ExitState = newExit;
                            updated       = true;
                        }
                    }
                    if (block.Footer.OpCode.Code == Code.Endfilter || block.Footer.OpCode.Code == Code.Endfinally)
                    {
                        // Match the exit state within finally/fault/filter
                        List <ExceptionHandler> ehs;
                        if (!ehMap.TryGetValue(block, out ehs))
                        {
                            ehs = new List <ExceptionHandler>();
                            int footerIndex = graph.IndexOf(block.Footer);
                            foreach (var eh in graph.Body.ExceptionHandlers)
                            {
                                if (eh.FilterStart != null && block.Footer.OpCode.Code == Code.Endfilter)
                                {
                                    if (footerIndex >= graph.IndexOf(eh.FilterStart) &&
                                        footerIndex < graph.IndexOf(eh.HandlerStart))
                                    {
                                        ehs.Add(eh);
                                    }
                                }
                                else if (eh.HandlerType == ExceptionHandlerType.Finally ||
                                         eh.HandlerType == ExceptionHandlerType.Fault)
                                {
                                    if (footerIndex >= graph.IndexOf(eh.HandlerStart) &&
                                        footerIndex < graph.IndexOf(eh.HandlerEnd))
                                    {
                                        ehs.Add(eh);
                                    }
                                }
                            }
                            ehMap[block] = ehs;
                        }
                        foreach (var eh in ehs)
                        {
                            uint ehVal;
                            if (finallyIds.TryGetValue(eh, out ehVal))
                            {
                                if (key.ExitState > ehVal)
                                {
                                    finallyIds[eh] = key.ExitState;
                                    updated        = true;
                                }
                                else if (key.ExitState < ehVal)
                                {
                                    key.ExitState = ehVal;
                                    updated       = true;
                                }
                            }
                            else
                            {
                                finallyIds[eh] = key.ExitState;
                                updated        = true;
                            }
                        }
                    }
                    else if (block.Footer.OpCode.Code == Code.Leave || block.Footer.OpCode.Code == Code.Leave_S)
                    {
                        // Match the exit state with finally/fault/filter
                        List <ExceptionHandler> ehs;
                        if (!ehMap.TryGetValue(block, out ehs))
                        {
                            ehs = new List <ExceptionHandler>();
                            int footerIndex = graph.IndexOf(block.Footer);
                            foreach (var eh in graph.Body.ExceptionHandlers)
                            {
                                if (footerIndex >= graph.IndexOf(eh.TryStart) &&
                                    footerIndex < graph.IndexOf(eh.TryEnd))
                                {
                                    ehs.Add(eh);
                                }
                            }
                            ehMap[block] = ehs;
                        }

                        uint?maxVal = null;
                        foreach (var eh in ehs)
                        {
                            uint ehVal;
                            if (finallyIds.TryGetValue(eh, out ehVal) && (maxVal == null || ehVal > maxVal))
                            {
                                if (maxVal != null)
                                {
                                    updated = true;
                                }
                                maxVal = ehVal;
                            }
                        }
                        if (maxVal != null)
                        {
                            if (key.ExitState > maxVal.Value)
                            {
                                maxVal  = key.ExitState;
                                updated = true;
                            }
                            else if (key.ExitState < maxVal.Value)
                            {
                                key.ExitState = maxVal.Value;
                                updated       = true;
                            }
                            foreach (var eh in ehs)
                            {
                                finallyIds[eh] = maxVal.Value;
                            }
                        }
                    }
                    keys[block.Id] = key;
                }
            } while (updated);

            // Replace id with actual values
            var idMap = new Dictionary <uint, uint>();

            for (int i = 0; i < keys.Length; i++)
            {
                BlockKey key = keys[i];

                uint entryId = key.EntryState;
                if (!idMap.TryGetValue(entryId, out key.EntryState))
                {
                    key.EntryState = idMap[entryId] = random.NextUInt32();
                }

                uint exitId = key.ExitState;
                if (!idMap.TryGetValue(exitId, out key.ExitState))
                {
                    key.ExitState = idMap[exitId] = random.NextUInt32();
                }

                keys[i] = key;
            }
        }
예제 #3
0
		static void ProcessBlocks(BlockKey[] keys, ControlFlowGraph graph, RandomGenerator random) {
			uint id = 0;
			for (int i = 0; i < keys.Length; i++) {
				keys[i].EntryState = id++;
				keys[i].ExitState = id++;
			}

			var finallyIds = new Dictionary<ExceptionHandler, uint>();
			var ehMap = new Dictionary<ControlFlowBlock, List<ExceptionHandler>>();

			bool updated;
			do {
				updated = false;

				// Update the state ids with the maximum id
				foreach (ControlFlowBlock block in graph) {
					BlockKey key = keys[block.Id];
					if (block.Sources.Count > 0) {
						uint newEntry = block.Sources.Select(b => keys[b.Id].ExitState).Max();
						if (key.EntryState != newEntry) {
							key.EntryState = newEntry;
							updated = true;
						}
					}
					if (block.Targets.Count > 0) {
						uint newExit = block.Targets.Select(b => keys[b.Id].EntryState).Max();
						if (key.ExitState != newExit) {
							key.ExitState = newExit;
							updated = true;
						}
					}
					if (block.Footer.OpCode.Code == Code.Endfilter || block.Footer.OpCode.Code == Code.Endfinally) {
						// Match the exit state within finally/fault/filter
						List<ExceptionHandler> ehs;
						if (!ehMap.TryGetValue(block, out ehs)) {
							ehs = new List<ExceptionHandler>();
							int footerIndex = graph.IndexOf(block.Footer);
							foreach (var eh in graph.Body.ExceptionHandlers) {
								if (eh.FilterStart != null && block.Footer.OpCode.Code == Code.Endfilter) {
									if (footerIndex >= graph.IndexOf(eh.FilterStart) &&
									    footerIndex < graph.IndexOf(eh.HandlerStart))
										ehs.Add(eh);
								}
								else if (eh.HandlerType == ExceptionHandlerType.Finally ||
								         eh.HandlerType == ExceptionHandlerType.Fault) {
									if (footerIndex >= graph.IndexOf(eh.HandlerStart) &&
									    (eh.HandlerEnd == null || footerIndex < graph.IndexOf(eh.HandlerEnd)))
										ehs.Add(eh);
								}
							}
							ehMap[block] = ehs;
						}
						foreach (var eh in ehs) {
							uint ehVal;
							if (finallyIds.TryGetValue(eh, out ehVal)) {
								if (key.ExitState > ehVal) {
									finallyIds[eh] = key.ExitState;
									updated = true;
								}
								else if (key.ExitState < ehVal) {
									key.ExitState = ehVal;
									updated = true;
								}
							}
							else {
								finallyIds[eh] = key.ExitState;
								updated = true;
							}
						}
					}
					else if (block.Footer.OpCode.Code == Code.Leave || block.Footer.OpCode.Code == Code.Leave_S) {
						// Match the exit state with finally/fault/filter
						List<ExceptionHandler> ehs;
						if (!ehMap.TryGetValue(block, out ehs)) {
							ehs = new List<ExceptionHandler>();
							int footerIndex = graph.IndexOf(block.Footer);
							foreach (var eh in graph.Body.ExceptionHandlers) {
								if (footerIndex >= graph.IndexOf(eh.TryStart) &&
								    (eh.TryEnd == null || footerIndex < graph.IndexOf(eh.TryEnd)))
									ehs.Add(eh);
							}
							ehMap[block] = ehs;
						}

						uint? maxVal = null;
						foreach (var eh in ehs) {
							uint ehVal;
							if (finallyIds.TryGetValue(eh, out ehVal) && (maxVal == null || ehVal > maxVal)) {
								if (maxVal != null)
									updated = true;
								maxVal = ehVal;
							}
						}
						if (maxVal != null) {
							if (key.ExitState > maxVal.Value) {
								maxVal = key.ExitState;
								updated = true;
							}
							else if (key.ExitState < maxVal.Value) {
								key.ExitState = maxVal.Value;
								updated = true;
							}
							foreach (var eh in ehs)
								finallyIds[eh] = maxVal.Value;
						}
					}
					keys[block.Id] = key;
				}
			} while (updated);

			if (random != null) {
				// Replace id with actual values
				var idMap = new Dictionary<uint, uint>();
				for (int i = 0; i < keys.Length; i++) {
					BlockKey key = keys[i];

					uint entryId = key.EntryState;
					if (!idMap.TryGetValue(entryId, out key.EntryState))
						key.EntryState = idMap[entryId] = random.NextUInt32();

					uint exitId = key.ExitState;
					if (!idMap.TryGetValue(exitId, out key.ExitState))
						key.ExitState = idMap[exitId] = random.NextUInt32();

					keys[i] = key;
				}
			}
		}