public CFMangleContext(CFManglerPlugin mangler, MethodDef method, Importer importer) { Mangler = mangler; Method = method; Importer = importer; MethodBody = Method.Body; RootBlock = MethodBody.ParseBlocks(); }
internal Block.Root Parse() { var root = new Block.Root { FlowInfo = _flow = new FlowInfo() }; var ehScopes = new Dictionary <ExceptionHandler, (Block.Seh, Block.Seh, Block.Seh)>(); foreach (var eh in _exceptionHandlers) { var tryBlock = new Block.Seh(BlockType.Try, eh); var handlerType = BlockType.Handler; switch (eh.HandlerType) { case ExceptionHandlerType.Finally: handlerType = BlockType.Finally; break; case ExceptionHandlerType.Fault: handlerType = BlockType.Fault; break; } var handlerBlock = new Block.Seh(handlerType, eh); if (eh.FilterStart != null) { ehScopes[eh] = (tryBlock, handlerBlock, new Block.Seh(BlockType.Filter, eh)); } else { ehScopes[eh] = (tryBlock, handlerBlock, (Block.Seh)null); } Instruction instr; if ((instr = eh.TryStart) != null) { _flow[instr].DepthBefore = 0; } if ((instr = eh.FilterStart) != null) { _flow[instr].DepthBefore = 1; currentMaxStack = 1; } if ((instr = eh.HandlerStart) != null) { var pushed = eh.HandlerType == ExceptionHandlerType.Catch || eh.HandlerType == ExceptionHandlerType.Filter; if (pushed) { _flow[instr].DepthBefore = 1; currentMaxStack = 1; } else { _flow[instr].DepthBefore = 0; } } } var scopeStack = new Stack <Block>(); scopeStack.Push(root); stack = 0; resetStack = false; foreach (var instr in _instructions) { foreach (var eh in _exceptionHandlers) { if (instr == eh.TryEnd) { scopeStack.Pop(); } if (instr == eh.HandlerEnd) { scopeStack.Pop(); } if (eh.FilterStart != null && instr == eh.HandlerStart) { // Filter must precede handler immediately Debug.Assert(scopeStack.Peek().Type == BlockType.Filter); scopeStack.Pop(); } } foreach (var eh in _exceptionHandlers.Reverse()) { var(item1, item2, item3) = ehScopes[eh]; var parent = scopeStack.Count > 0 ? scopeStack.Peek() : null; if (instr == eh.TryStart) { parent?.Add(item1); scopeStack.Push(item1); } if (instr == eh.HandlerStart) { parent?.Add(item2); scopeStack.Push(item2); } if (instr == eh.FilterStart) { parent?.Add(item3); scopeStack.Push(item3); } } var scope = scopeStack.Peek(); if (!(scope.LastChild is Block.Regular block)) { scope.Add(block = new Block.Regular()); } block.Fragment.Add(instr); UpdateStack(instr); } foreach (var eh in _exceptionHandlers) { if (eh.TryEnd == null) { scopeStack.Pop(); } if (eh.HandlerEnd == null) { scopeStack.Pop(); } } _flow.MaxStack = currentMaxStack; Debug.Assert(scopeStack.Count == 1); return(root); }