public CilBody CopyTo(CilBody body) { body.KeepOldMaxStack = KeepOldMaxStack; body.InitLocals = InitLocals; body.HeaderSize = HeaderSize; body.MaxStack = MaxStack; body.LocalVarSigTok = LocalVarSigTok; body.Instructions.Clear(); body.Instructions.AddRange(Instructions); body.ExceptionHandlers.Clear(); body.ExceptionHandlers.AddRange(ExceptionHandlers); body.Variables.Clear(); body.Variables.AddRange(this.Locals); body.Scope = this.Scope; body.UpdateInstructionOffsets(); return body; }
public Trace(CilBody body, bool hasReturnValue) { RefCount = new Dictionary<uint, int>(); BrRefs = new Dictionary<uint, List<Instruction>>(); BeforeStack = new Dictionary<uint, int>(); AfterStack = new Dictionary<uint, int>(); body.UpdateInstructionOffsets(); foreach (ExceptionHandler eh in body.ExceptionHandlers) { BeforeStack[eh.TryStart.Offset] = 0; BeforeStack[eh.HandlerStart.Offset] = (eh.HandlerType != ExceptionHandlerType.Finally ? 1 : 0); if (eh.FilterStart != null) BeforeStack[eh.FilterStart.Offset] = 1; } int currentStack = 0; for (int i = 0; i < body.Instructions.Count; i++) { var instr = body.Instructions[i]; if (BeforeStack.ContainsKey(instr.Offset)) currentStack = BeforeStack[instr.Offset]; BeforeStack[instr.Offset] = currentStack; instr.UpdateStack(ref currentStack, hasReturnValue); AfterStack[instr.Offset] = currentStack; uint offset; switch (instr.OpCode.FlowControl) { case FlowControl.Branch: offset = ((Instruction)instr.Operand).Offset; if (!BeforeStack.ContainsKey(offset)) BeforeStack[offset] = currentStack; Increment(RefCount, offset); BrRefs.AddListEntry(offset, instr); currentStack = 0; continue; case FlowControl.Call: if (instr.OpCode.Code == Code.Jmp) currentStack = 0; break; case FlowControl.Cond_Branch: if (instr.OpCode.Code == Code.Switch) { foreach (Instruction target in (Instruction[])instr.Operand) { if (!BeforeStack.ContainsKey(target.Offset)) BeforeStack[target.Offset] = currentStack; Increment(RefCount, target.Offset); BrRefs.AddListEntry(target.Offset, instr); } } else { offset = ((Instruction)instr.Operand).Offset; if (!BeforeStack.ContainsKey(offset)) BeforeStack[offset] = currentStack; Increment(RefCount, offset); BrRefs.AddListEntry(offset, instr); } break; case FlowControl.Meta: case FlowControl.Next: case FlowControl.Break: break; case FlowControl.Return: case FlowControl.Throw: continue; default: throw new UnreachableException(); } if (i + 1 < body.Instructions.Count) { offset = body.Instructions[i + 1].Offset; Increment(RefCount, offset); } } }