Esempio n. 1
0
        /// <summary>
        /// 开始调试
        /// </summary>
        public void Run()
        {
            // 获取源代码-中间代码信息
            intermediateCodeInformations = GetIntermediateCodeInformation();

            nextLines = new Dictionary <int, List <int> >();

            savedInstructions = new Dictionary <int, IntermediateCode>();

            // 获取最大行信息
            maxLine = int.MinValue;

            foreach (int key in intermediateCodeInformations.Keys)
            {
                if (key > maxLine)
                {
                    maxLine = key;
                }
            }

            // 遍历断点信息
            foreach (int breakpoint in breakpoints)
            {
                // 保存断点处指令并替换为int指令
                if (intermediateCodeInformations.ContainsKey(breakpoint))
                {
                    IntermediateCodeInformation information = intermediateCodeInformations[breakpoint];
                    int address            = information.Address;
                    IntermediateCode saved = vm.ReplaceWithInt(address);
                    savedInstructions.Add(address, saved);
                }
            }
            vm.Run();
        }
Esempio n. 2
0
        /// <summary>
        /// 移除断点
        /// </summary>
        /// <param name="breakpoint">断点行号</param>
        public void RemoveBreakpoint(int breakpoint)
        {
            // 移除断点
            breakpoints.Remove(breakpoint);

            // 恢复原始中间指令
            IntermediateCodeInformation information = intermediateCodeInformations[breakpoint];
            int address            = information.Address;
            IntermediateCode saved = savedInstructions[address];

            savedInstructions.Remove(address);
            vm.Resume(address, saved);
        }
Esempio n. 3
0
        /// <summary>
        /// 增加断点
        /// </summary>
        /// <param name="breakpoint">断点行号</param>
        public void AddBreakpoint(int breakpoint)
        {
            // 寻找插入位置
            int index = 0, length = breakpoints.Count;

            while (index < length && breakpoints[index] < breakpoint)
            {
                index++;
            }
            breakpoints.Insert(index, breakpoint);

            // 保存并替换中间指令为int
            IntermediateCodeInformation information = intermediateCodeInformations[breakpoint];
            int address            = information.Address;
            IntermediateCode saved = vm.ReplaceWithInt(address);

            savedInstructions.Add(address, saved);
        }
Esempio n. 4
0
        /// <summary>
        /// 获取源代码-中间代码信息
        /// </summary>
        /// <returns>源代码中间代码信息</returns>
        private Dictionary <int, IntermediateCodeInformation> GetIntermediateCodeInformation()
        {
            int length = codesArray.Count;
            Dictionary <int, IntermediateCodeInformation> informations = new Dictionary <int, IntermediateCodeInformation>();

            // 遍历中间代码
            for (int i = 0; i < length; i++)
            {
                IntermediateCode current = codesArray[i];
                int currentLine          = current.lineNum;
                IntermediateCodeInformation currentInformation;

                // 判断该中间指令对应源代码的行是否已经加入信息表中
                if (informations.TryGetValue(currentLine, out currentInformation))
                {
                    // 该行含函数调用则更新函数入口地址列表
                    if (current.type == InstructionType.call)
                    {
                        currentInformation.IsFunctionCall = true;
                        currentInformation.FuncionEntryList.AddLast((int)current.operant);
                        currentInformation.IsFunctionBody = false;
                        informations[currentLine]         = currentInformation;
                    }
                }
                else
                {
                    // 该行源代码首条中间指令
                    currentInformation                  = new IntermediateCodeInformation();
                    currentInformation.Address          = i;
                    currentInformation.Line             = currentLine;
                    currentInformation.IsFunctionCall   = false;
                    currentInformation.FuncionEntryList = new LinkedList <int>();
                    currentInformation.IsFunctionBody   = false;
                    informations.Add(currentLine, currentInformation);
                }
            }
            foreach (FunctionInformation information in functionInformationTable.Values)
            {
                int line = codesArray[information.enrtyAddress].lineNum;
                informations[line].IsFunctionBody = true;
            }
            return(informations);
        }
Esempio n. 5
0
        private void ReplaceNextLine(int line)
        {
            // 如果当前行不是最后一行
            if (line != maxLine)
            {
                // 判断是否已缓存该行的下一行
                if (!nextLines.ContainsKey(line))
                {
                    // 判断是否为函数体的行
                    int functionEntry = -1;
                    foreach (FunctionInformation information in functionInformationTable.Values)
                    {
                        if (information.enrtyAddress <= intermediateCodeInformations[line].Address && information.outAddress >= intermediateCodeInformations[line].Address)
                        {
                            functionEntry = information.enrtyAddress;
                            break;
                        }
                    }

                    if (functionEntry != -1)
                    {
                        // 若是函数体中的断点则判断是否被调用
                        foreach (KeyValuePair <int, IntermediateCodeInformation> information in intermediateCodeInformations)
                        {
                            IntermediateCodeInformation currentInforamtion = information.Value;
                            if (currentInforamtion.IsFunctionCall && currentInforamtion.FuncionEntryList.Contains(functionEntry))
                            {
                                // 若被调用则获取调用语句的下一行
                                // 同时保存该行的下一行
                                if (information.Key != maxLine)
                                {
                                    int nextLine = GetNextLine(information.Key);
                                    while (intermediateCodeInformations[nextLine].IsFunctionBody && nextLine < maxLine)
                                    {
                                        nextLine = GetNextLine(nextLine);
                                    }
                                    nextLines.Add(line, new List <int> {
                                        GetNextLine(line), nextLine
                                    });
                                    break;
                                }
                                else
                                {
                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        // 非函数体中的直接获取下一行
                        int nextLine = GetNextLine(line);
                        while (intermediateCodeInformations[nextLine].IsFunctionBody && nextLine < maxLine)
                        {
                            nextLine = GetNextLine(nextLine);
                        }
                        nextLines.Add(line, new List <int> {
                            nextLine
                        });
                    }
                }


                foreach (int nextLine in nextLines[line])
                {
                    // 对下一行源代码对应的中间代码进行保存并替换int
                    IntermediateCodeInformation nextLineInformation = intermediateCodeInformations[nextLine];
                    int nextLineAddress = nextLineInformation.Address;
                    if (!savedInstructions.ContainsKey(nextLineAddress))
                    {
                        IntermediateCode nextLineSaved = vm.ReplaceWithInt(nextLineAddress);
                        savedInstructions.Add(nextLineAddress, nextLineSaved);
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// 处理中断
        /// </summary>
        private void HandleInterrupt()
        {
            NeedDebug?.Invoke();
            // 挂起调试器进程等待用户操作
            Thread.CurrentThread.Suspend();

            // 根据用户输入决定调试模式
            switch (mode)
            {
            case -1:
                vm.Stop();
                break;

            case 0:
                // Step into模式
                // 根据当前行号获取保存的中间代码
                int line0 = vm.GetLastCodeInformation().Line;
                IntermediateCodeInformation information0 = intermediateCodeInformations[line0];
                int address0           = information0.Address;
                IntermediateCode saved = savedInstructions[address0];


                // 查询当前行是否为函数调用
                if (information0.IsFunctionCall)
                {
                    // 对函数入口表中的每一个函数入口指令进行保存并替换int指令
                    foreach (int functionEntry in information0.FuncionEntryList)
                    {
                        if (!savedInstructions.ContainsKey(functionEntry))
                        {
                            IntermediateCode function = vm.ReplaceWithInt(functionEntry);
                            savedInstructions.Add(functionEntry, function);
                        }
                    }
                }

                // 单条执行中间代码
                vm.InterpretSingleInstruction(saved);

                // 对下一行源代码对应的中间代码进行保存并替换int
                ReplaceNextLine(line0);

                break;

            case 1:
                // Step over模式
                // 根据当前行号获取保存的中间代码
                int line1 = vm.GetLastCodeInformation().Line;
                IntermediateCodeInformation information1 = intermediateCodeInformations[line1];
                int address1            = information1.Address;
                IntermediateCode saved1 = savedInstructions[address1];

                // 单条执行中间代码
                vm.InterpretSingleInstruction(saved1);

                // 对下一行源代码对应的中间代码进行保存并替换int
                ReplaceNextLine(line1);

                break;

            case 2:
                // Continue模式
                // 根据当前行号获取保存的中间代码
                int line2 = vm.GetLastCodeInformation().Line;
                IntermediateCodeInformation information2 = intermediateCodeInformations[line2];
                int address2            = information2.Address;
                IntermediateCode saved2 = savedInstructions[address2];

                // 单条执行中间代码
                vm.InterpretSingleInstruction(saved2);

                break;

            default:
                // 其他模式
                break;
            }
        }