diff --git a/ecmascript/jspandafile/debug_info_extractor.cpp b/ecmascript/jspandafile/debug_info_extractor.cpp index be336ba50e9ce71982b0f5feaa82ba6388cd7e9d..e8e8764a2d65971314f056bca1a75755a3aabe08 100644 --- a/ecmascript/jspandafile/debug_info_extractor.cpp +++ b/ecmascript/jspandafile/debug_info_extractor.cpp @@ -19,13 +19,14 @@ #include "libpandabase/utils/utf.h" #include "libpandafile/class_data_accessor-inl.h" #include "libpandafile/debug_data_accessor-inl.h" -#include "libpandafile/line_program_state.h" +#include "libpandafile/line_number_program.h" namespace panda::ecmascript { using panda::panda_file::ClassDataAccessor; using panda::panda_file::DebugInfoDataAccessor; using panda::panda_file::LineNumberProgramItem; using panda::panda_file::LineProgramState; +using panda::panda_file::LineNumberProgramProcessor; using panda::panda_file::MethodDataAccessor; using panda::panda_file::ProtoDataAccessor; @@ -39,186 +40,126 @@ DebugInfoExtractor::DebugInfoExtractor(const JSPandaFile *jsPandaFile) Extract(jsPandaFile->GetPandaFile()); } -class LineNumberProgramProcessor { +class LineNumberProgramHandler { public: - LineNumberProgramProcessor(LineProgramState state, const uint8_t *program) : state_(state), program_(program) {} + explicit LineNumberProgramHandler(LineProgramState *state) : state_(state) {} + ~LineNumberProgramHandler() = default; - ~LineNumberProgramProcessor() = default; + NO_COPY_SEMANTIC(LineNumberProgramHandler); + NO_MOVE_SEMANTIC(LineNumberProgramHandler); - NO_COPY_SEMANTIC(LineNumberProgramProcessor); - NO_MOVE_SEMANTIC(LineNumberProgramProcessor); - - void Process() + LineProgramState *GetState() const { - auto opcode = ReadOpcode(); - lnt_.push_back({static_cast(state_.GetAddress()), static_cast(state_.GetLine())}); - while (opcode != Opcode::END_SEQUENCE) { - switch (opcode) { - case Opcode::ADVANCE_LINE: { - HandleAdvanceLine(); - break; - } - case Opcode::ADVANCE_PC: { - HandleAdvancePc(); - break; - } - case Opcode::SET_FILE: { - HandleSetFile(); - break; - } - case Opcode::SET_SOURCE_CODE: { - HandleSetSourceCode(); - break; - } - case Opcode::SET_PROLOGUE_END: - case Opcode::SET_EPILOGUE_BEGIN: - break; - case Opcode::START_LOCAL: { - HandleStartLocal(); - break; - } - case Opcode::START_LOCAL_EXTENDED: { - HandleStartLocalExtended(); - break; - } - case Opcode::RESTART_LOCAL: { - LOG(FATAL, ECMASCRIPT) << "Opcode RESTART_LOCAL is not supported"; - break; - } - case Opcode::END_LOCAL: { - HandleEndLocal(); - break; - } - case Opcode::SET_COLUMN: { - HandleSetColumn(); - break; - } - default: { - HandleSpecialOpcode(opcode); - break; - } - } - opcode = ReadOpcode(); - } - // process end offset + return state_; } - LineNumberTable GetLineNumberTable() const + void ProcessBegin() { - return lnt_; + lnt_.push_back({state_->GetAddress(), state_->GetLine()}); } - ColumnNumberTable GetColumnNumberTable() const + void ProcessEnd() { - return cnt_; } - LocalVariableTable GetLocalVariableTable() const + bool HandleAdvanceLine(int32_t lineDiff) const { - return lvt_; + state_->AdvanceLine(lineDiff); + return true; } - const uint8_t *GetFile() const + bool HandleAdvancePc(uint32_t pcDiff) const { - return state_.GetFile(); + state_->AdvancePc(pcDiff); + return true; } - const uint8_t *GetSourceCode() const + bool HandleSetFile(uint32_t sourceFileId) const { - return state_.GetSourceCode(); + state_->SetFile(sourceFileId); + return true; } -private: - using Opcode = LineNumberProgramItem::Opcode; - - Opcode ReadOpcode() + bool HandleSetSourceCode(uint32_t sourceCodeId) const { - auto opcode = static_cast(*program_); - ++program_; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - return opcode; + state_->SetSourceCode(sourceCodeId); + return true; } - int32_t ReadRegisterNumber() + bool HandleSetPrologueEnd() const { - auto [regiserNumber, n, isFull] = leb128::DecodeSigned(program_); - LOG_IF(!isFull, FATAL, ECMASCRIPT) << "Cannot read a register number"; - program_ += n; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - return regiserNumber; + return true; } - void HandleAdvanceLine() + bool HandleSetEpilogueBegin() const { - auto line_diff = state_.ReadSLeb128(); - state_.AdvanceLine(line_diff); + return true; } - void HandleAdvancePc() + bool HandleStartLocal(int32_t regNumber, uint32_t nameId, [[maybe_unused]] uint32_t typeId) { - auto pc_diff = state_.ReadULeb128(); - state_.AdvancePc(pc_diff); + const char *name = GetStringFromConstantPool(state_->GetPandaFile(), nameId); + lvt_.insert(std::make_pair(name, regNumber)); + return true; } - void HandleSetFile() + bool HandleStartLocalExtended(int32_t regNumber, uint32_t nameId, [[maybe_unused]] uint32_t typeId, + [[maybe_unused]] uint32_t typeSignatureId) { - state_.SetFile(state_.ReadULeb128()); + const char *name = GetStringFromConstantPool(state_->GetPandaFile(), nameId); + lvt_.insert(std::make_pair(name, regNumber)); + return true; } - void HandleSetSourceCode() + bool HandleEndLocal([[maybe_unused]] int32_t regNumber) { - state_.SetSourceCode(state_.ReadULeb128()); + return true; } - void HandleSetPrologueEnd() {} + bool HandleSetColumn(int32_t columnNumber) + { + state_->SetColumn(columnNumber); + cnt_.push_back({state_->GetAddress(), state_->GetColumn()}); + return true; + } - void HandleSetEpilogueBegin() {} + bool HandleSpecialOpcode(uint32_t pcOffset, int32_t lineOffset) + { + state_->AdvancePc(pcOffset); + state_->AdvanceLine(lineOffset); + lnt_.push_back({state_->GetAddress(), state_->GetLine()}); + return true; + } - void HandleStartLocal() + LineNumberTable GetLineNumberTable() const { - auto regNumber = ReadRegisterNumber(); - auto nameIndex = state_.ReadULeb128(); - [[maybe_unused]] auto typeIndex = state_.ReadULeb128(); - const char *name = GetStringFromConstantPool(state_.GetPandaFile(), nameIndex); - lvt_.insert(std::make_pair(name, regNumber)); + return lnt_; } - void HandleStartLocalExtended() + LocalVariableTable GetLocalVariableTable() const { - auto regNumber = ReadRegisterNumber(); - auto nameIndex = state_.ReadULeb128(); - [[maybe_unused]] auto typeIndex = state_.ReadULeb128(); - [[maybe_unused]] auto typeSignatureIndex = state_.ReadULeb128(); - const char *name = GetStringFromConstantPool(state_.GetPandaFile(), nameIndex); - lvt_.insert(std::make_pair(name, regNumber)); + return lvt_; } - void HandleEndLocal() + ColumnNumberTable GetColumnNumberTable() const { - [[maybe_unused]] auto regNumber = ReadRegisterNumber(); - // process end offset + return cnt_; } - void HandleSetColumn() + const uint8_t *GetFile() const { - auto cn = state_.ReadULeb128(); - state_.SetColumn(cn); - cnt_.push_back({static_cast(state_.GetAddress()), static_cast(state_.GetColumn())}); + return state_->GetFile(); } - void HandleSpecialOpcode(LineNumberProgramItem::Opcode opcode) + const uint8_t *GetSourceCode() const { - ASSERT(static_cast(opcode) >= LineNumberProgramItem::OPCODE_BASE); - - auto adjustOpcode = static_cast(static_cast(opcode) - LineNumberProgramItem::OPCODE_BASE); - auto pcOffset = static_cast(adjustOpcode / LineNumberProgramItem::LINE_RANGE); - int32_t lineOffset = - static_cast(adjustOpcode) % LineNumberProgramItem::LINE_RANGE + LineNumberProgramItem::LINE_BASE; - state_.AdvancePc(pcOffset); - state_.AdvanceLine(lineOffset); - lnt_.push_back({static_cast(state_.GetAddress()), static_cast(state_.GetLine())}); + return state_->GetSourceCode(); } - LineProgramState state_; - const uint8_t *program_; +private: + using Opcode = LineNumberProgramItem::Opcode; + + LineProgramState *state_; LineNumberTable lnt_; LocalVariableTable lvt_; ColumnNumberTable cnt_; @@ -250,16 +191,17 @@ void DebugInfoExtractor::Extract(const panda_file::File *pf) LineProgramState state(pandaFile, sourceFileId.value_or(panda_file::File::EntityId(0)), dda.GetLineStart(), dda.GetConstantPool()); - LineNumberProgramProcessor programProcessor(state, program); + LineNumberProgramHandler handler(&state); + LineNumberProgramProcessor programProcessor(program, &handler); programProcessor.Process(); panda_file::File::EntityId methodId = mda.GetMethodId(); - const char *sourceFile = utf::Mutf8AsCString(programProcessor.GetFile()); - const char *sourceCode = utf::Mutf8AsCString(programProcessor.GetSourceCode()); + const char *sourceFile = utf::Mutf8AsCString(handler.GetFile()); + const char *sourceCode = utf::Mutf8AsCString(handler.GetSourceCode()); methods_.insert(std::make_pair(methodId.GetOffset(), MethodDebugInfo {sourceFile, sourceCode, - programProcessor.GetLineNumberTable(), - programProcessor.GetColumnNumberTable(), - programProcessor.GetLocalVariableTable()})); + handler.GetLineNumberTable(), + handler.GetColumnNumberTable(), + handler.GetLocalVariableTable()})); }); } } diff --git a/ecmascript/jspandafile/debug_info_extractor.h b/ecmascript/jspandafile/debug_info_extractor.h index 87e12a8dbd982d0d34f16140985c1a8e6719f946..86fe0fc142dc40caee252c79da6b0333dce6d245 100644 --- a/ecmascript/jspandafile/debug_info_extractor.h +++ b/ecmascript/jspandafile/debug_info_extractor.h @@ -46,7 +46,7 @@ using ColumnNumberTable = CVector; * uint32_t startOffset * uint32_t endOffset */ -using LocalVariableTable = CUnorderedMap; +using LocalVariableTable = CUnorderedMap; // name, regNumber // public for debugger class PUBLIC_API DebugInfoExtractor {