示例#1
0
		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;
		}
示例#2
0
            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);
                    }
                }
            }