static void Validate(ScopeBlock scope) { scope.Validate(); foreach (var child in scope.Children) { Validate(child); } }
private void PostProcessMethod(MethodDef method, bool isExport) { CFG.ScopeBlock scope = this.Runtime.LookupMethod(method); var ilTransformer = new ILPostTransformer(method, scope, this.Runtime); ilTransformer.Transform(); }
static void AddScopeBlock(ScopeBlock block, ScopeBlock child) { if (block.Content.Count > 0) { var newScope = new ScopeBlock(); foreach (var instrBlock in block.Content) { newScope.Content.Add(instrBlock); } block.Content.Clear(); block.Children.Add(newScope); } block.Children.Add(child); }
static void AddBasicBlock(ScopeBlock block, BasicBlock <CILInstrList> child) { if (block.Children.Count > 0) { var last = block.Children.Last(); if (last.Type != ScopeType.None) { last = new ScopeBlock(); block.Children.Add(last); } block = last; } Debug.Assert(block.Children.Count == 0); block.Content.Add(child); }
private static bool SearchBlockInternal(ScopeBlock scope, IBasicBlock target, Stack <ScopeBlock> scopeStack) { if (scope.Content.Count > 0) { if (scope.Content.Contains(target)) { scopeStack.Push(scope); return(true); } return(false); } scopeStack.Push(scope); foreach (var child in scope.Children) { if (SearchBlockInternal(child, target, scopeStack)) { return(true); } } scopeStack.Pop(); return(false); }
static ScopeBlock AssignScopes(CilBody body, List <BasicBlock <CILInstrList> > blocks) { var ehScopes = new Dictionary <ExceptionHandler, Tuple <ScopeBlock, ScopeBlock, ScopeBlock> >(); foreach (var eh in body.ExceptionHandlers) { var tryBlock = new ScopeBlock(ScopeType.Try, eh); var handlerBlock = new ScopeBlock(ScopeType.Handler, eh); if (eh.FilterStart != null) { var filterBlock = new ScopeBlock(ScopeType.Filter, eh); ehScopes[eh] = Tuple.Create(tryBlock, handlerBlock, filterBlock); } else { ehScopes[eh] = Tuple.Create(tryBlock, handlerBlock, (ScopeBlock)null); } } var root = new ScopeBlock(); var scopeStack = new Stack <ScopeBlock>(); scopeStack.Push(root); foreach (var block in blocks) { var header = block.Content[0]; foreach (ExceptionHandler eh in body.ExceptionHandlers) { Tuple <ScopeBlock, ScopeBlock, ScopeBlock> ehScope = ehScopes[eh]; if (header == eh.TryEnd) { var pop = scopeStack.Pop(); Debug.Assert(pop == ehScope.Item1); } if (header == eh.HandlerEnd) { var pop = scopeStack.Pop(); Debug.Assert(pop == ehScope.Item2); } if (eh.FilterStart != null && header == eh.HandlerStart) { // Filter must precede handler immediately Debug.Assert(scopeStack.Peek().Type == ScopeType.Filter); var pop = scopeStack.Pop(); Debug.Assert(pop == ehScope.Item3); } } foreach (ExceptionHandler eh in body.ExceptionHandlers.Reverse()) { Tuple <ScopeBlock, ScopeBlock, ScopeBlock> ehScope = ehScopes[eh]; ScopeBlock parent = scopeStack.Count > 0 ? scopeStack.Peek() : null; if (header == eh.TryStart) { if (parent != null) { AddScopeBlock(parent, ehScope.Item1); } scopeStack.Push(ehScope.Item1); } if (header == eh.HandlerStart) { if (parent != null) { AddScopeBlock(parent, ehScope.Item2); } scopeStack.Push(ehScope.Item2); } if (header == eh.FilterStart) { if (parent != null) { AddScopeBlock(parent, ehScope.Item3); } scopeStack.Push(ehScope.Item3); } } ScopeBlock scope = scopeStack.Peek(); AddBasicBlock(scope, block); } foreach (ExceptionHandler eh in body.ExceptionHandlers) { if (eh.TryEnd == null) { var pop = scopeStack.Pop(); Debug.Assert(pop == ehScopes[eh].Item1); } if (eh.HandlerEnd == null) { var pop = scopeStack.Pop(); Debug.Assert(pop == ehScopes[eh].Item2); } } Debug.Assert(scopeStack.Count == 1); Validate(root); return(root); }