/// <summary> /// Finds basic block targets. /// </summary> /// <returns></returns> /// <exception cref="InvalidCompilerException"></exception> private SortedSet<int> FindBasicBlockTargets() { var targets = new SortedSet<int>(); targets.Add(0); // Find out all targets labels for (var ctx = new Context(InstructionSet, 0); ctx.Index >= 0; ctx.GotoNext()) { switch (ctx.Instruction.FlowControl) { case FlowControl.Next: continue; case FlowControl.Call: continue; case FlowControl.Break: goto case FlowControl.UnconditionalBranch; case FlowControl.Return: continue; case FlowControl.Throw: continue; case FlowControl.UnconditionalBranch: { //Debug.Assert(ctx.BranchTargets.Length == 1); targets.AddIfNew(ctx.BranchTargets[0]); continue; } case FlowControl.Switch: goto case FlowControl.ConditionalBranch; case FlowControl.ConditionalBranch: { foreach (int target in ctx.BranchTargets) targets.AddIfNew(target); targets.AddIfNew(ctx.Next.Label); continue; } case FlowControl.EndFinally: continue; case FlowControl.Leave: { //Debug.Assert(ctx.BranchTargets.Length == 1); targets.AddIfNew(ctx.BranchTargets[0]); continue; } default: throw new InvalidCompilerException(); } } // Add exception targets foreach (var handler in MethodCompiler.Method.ExceptionHandlers) { targets.AddIfNew(handler.HandlerStart); targets.AddIfNew(handler.TryStart); if (handler.FilterOffset != null) targets.AddIfNew(handler.FilterOffset.Value); } //foreach (var target in targets) //{ // //trace.Log("Target: " + target.ToString("X4")); //} return targets; }