diff --git a/es2panda/compiler/core/emitter.cpp b/es2panda/compiler/core/emitter.cpp index d807dfc245ccf255b4f0f56033d7dcabe7c39912..cb117f420ffa0a481d39d528a774356084162ecd 100644 --- a/es2panda/compiler/core/emitter.cpp +++ b/es2panda/compiler/core/emitter.cpp @@ -148,6 +148,11 @@ util::StringView FunctionEmitter::SourceCode() const return pg_->Binder()->Program()->SourceCode(); } +lexer::LineIndex &FunctionEmitter::GetLineIndex() const +{ + return const_cast(pg_->Binder()->Program()->GetLineIndex()); +} + static Format MatchFormat(const IRNode *node, const Formats &formats) { std::array regs {}; @@ -201,6 +206,8 @@ static size_t GetIRNodeWholeLength(const IRNode *node) void FunctionEmitter::GenInstructionDebugInfo(const IRNode *ins, panda::pandasm::Ins *pandaIns) { const ir::AstNode *astNode = ins->Node(); + constexpr size_t INVALID_LINE = -1; + constexpr uint32_t INVALID_COL = -1; ASSERT(astNode != nullptr); @@ -211,7 +218,7 @@ void FunctionEmitter::GenInstructionDebugInfo(const IRNode *ins, panda::pandasm: } } - pandaIns->ins_debug.line_number = astNode->Range().start.line; + pandaIns->ins_debug.line_number = astNode ? astNode->Range().start.line : INVALID_LINE; if (pg_->IsDebug()) { size_t insLen = GetIRNodeWholeLength(ins); @@ -222,7 +229,8 @@ void FunctionEmitter::GenInstructionDebugInfo(const IRNode *ins, panda::pandasm: offset_ += insLen; - pandaIns->ins_debug.column_number = astNode->Range().start.index; + pandaIns->ins_debug.column_number = astNode ? + (GetLineIndex().GetLocation(astNode->Range().start).col - 1) : INVALID_COL; } } diff --git a/es2panda/compiler/core/emitter.h b/es2panda/compiler/core/emitter.h index addf4b142b4daaeb21c86c5edcf424de01ea2c0b..7054a6d1b1032aab829c64a5556b05057b97f451 100644 --- a/es2panda/compiler/core/emitter.h +++ b/es2panda/compiler/core/emitter.h @@ -81,6 +81,7 @@ private: void GenSourceFileDebugInfo(); void GenVariablesDebugInfo(); util::StringView SourceCode() const; + lexer::LineIndex &GetLineIndex() const; void GenLiteralBuffers(); void GenBufferLiterals(const LiteralBuffer *buff); diff --git a/es2panda/compiler/core/function.cpp b/es2panda/compiler/core/function.cpp index 8e1aafacb71f1223c68fdc77bf0927e2149809f6..3f4a050ea07cc44fde3dc3c1d3779b8e2fdf6b89 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -199,8 +199,10 @@ static VReg CompileFunctionOrProgram(PandaGen *pg) void Function::Compile(PandaGen *pg) { VReg lexEnv = CompileFunctionOrProgram(pg); + pg->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION); pg->CopyFunctionArguments(pg->RootNode()); pg->InitializeLexEnv(pg->RootNode(), lexEnv); + pg->SetSourceLocationFlag(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION); pg->SortCatchTables(); } diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index cf6cc329cde938ac9350f00843131db13c0e419c..842deb1f871d4de3c47376434644da656c6e2ca5 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -179,6 +179,13 @@ public: return ic_.Size(); } + void SetSourceLocationFlag(lexer::SourceLocationFlag flag) + { + sa_.SetSourceLocationFlag(flag); + ra_.SetSourceLocationFlag(flag); + rra_.SetSourceLocationFlag(flag); + } + bool IsDebug() const; uint32_t ParamCount() const; uint32_t FormalParametersCount() const; diff --git a/es2panda/compiler/core/regAllocator.h b/es2panda/compiler/core/regAllocator.h index ec7bfefc6382d6886e243e69f430db24178f97a5..e028d9698325588fc7532f5e1240f6671d0962f4 100644 --- a/es2panda/compiler/core/regAllocator.h +++ b/es2panda/compiler/core/regAllocator.h @@ -17,6 +17,7 @@ #define ES2PANDA_COMPILER_CORE_REG_ALLOCATOR_H #include +#include #include namespace panda::es2panda::ir { @@ -29,11 +30,24 @@ class PandaGen; class AllocatorBase { public: - explicit AllocatorBase(PandaGen *pg) : pg_(pg) {}; + explicit AllocatorBase(PandaGen *pg) + : pg_(pg), sourceLocationFlag_(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION) + { + } NO_COPY_SEMANTIC(AllocatorBase); NO_MOVE_SEMANTIC(AllocatorBase); ~AllocatorBase() = default; + void SetSourceLocationFlag(lexer::SourceLocationFlag flag) + { + sourceLocationFlag_ = flag; + } + + lexer::SourceLocationFlag GetSourceLocationFlag() const + { + return sourceLocationFlag_; + } + protected: void PushBack(IRNode *ins); ArenaAllocator *Allocator() const; @@ -41,7 +55,9 @@ protected: template T *Alloc(const ir::AstNode *node, Args &&... args) { - return Allocator()->New(node, std::forward(args)...); + ir::AstNode *invalidNode = nullptr; + return Allocator()->New((GetSourceLocationFlag() == lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION) ? + invalidNode : node, std::forward(args)...); } template @@ -51,6 +67,7 @@ protected: } PandaGen *pg_; + lexer::SourceLocationFlag sourceLocationFlag_; // for instructions that need to be set with invalid debuginfo }; class SimpleAllocator : public AllocatorBase { diff --git a/es2panda/compiler/core/regScope.cpp b/es2panda/compiler/core/regScope.cpp index 588340ed6b4b47818e86663c4e2567f64498c294..6426709aad4840e85003626cba7b6afda3a2d98b 100644 --- a/es2panda/compiler/core/regScope.cpp +++ b/es2panda/compiler/core/regScope.cpp @@ -112,6 +112,7 @@ FunctionRegScope::FunctionRegScope(PandaGen *pg) : RegScope(pg), envScope_(pg->A pg_->debugInfo_.variableDebugInfo.push_back(funcScope); } + pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION); pg_->LoadAccFromArgs(pg_->rootNode_); if (funcScope->IsModuleScope()) { @@ -119,6 +120,7 @@ FunctionRegScope::FunctionRegScope(PandaGen *pg) : RegScope(pg), envScope_(pg->A } Hoisting::Hoist(pg); + pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION); } FunctionRegScope::~FunctionRegScope() diff --git a/es2panda/lexer/lexer.cpp b/es2panda/lexer/lexer.cpp index 880527188e5aa9296a1ee95482f6557810e2b1d1..bd7b785c80efc946ffc5b6569a8778a06e49913a 100644 --- a/es2panda/lexer/lexer.cpp +++ b/es2panda/lexer/lexer.cpp @@ -145,8 +145,14 @@ void Lexer::SkipMultiLineComment() ThrowError("Unterminated multi-line comment"); break; } + case LEX_CHAR_CR: { + if (Iterator().Peek() == LEX_CHAR_LF) { + Iterator().Forward(1); + } + + [[fallthrough]]; + } case LEX_CHAR_LF: - case LEX_CHAR_CR: case LEX_CHAR_LS: case LEX_CHAR_PS: { pos_.nextTokenLine++; diff --git a/es2panda/lexer/token/sourceLocation.cpp b/es2panda/lexer/token/sourceLocation.cpp index 9d1e4ea60474c0cdcdee2a703c35ae8e5bab8698..2fb3443837c09d91028c71ea5aed73f32f8b4bae 100644 --- a/es2panda/lexer/token/sourceLocation.cpp +++ b/es2panda/lexer/token/sourceLocation.cpp @@ -79,8 +79,8 @@ SourceLocation LineIndex::GetLocation(SourcePosition pos) noexcept size_t diff = pos.index - entry.lineStart; for (const auto &range : entry.ranges) { - if (diff < range.cnt) { - col += diff; + if (diff < (range.cnt * range.byteSize)) { + col += (diff / range.byteSize) ; break; } diff --git a/es2panda/lexer/token/sourceLocation.h b/es2panda/lexer/token/sourceLocation.h index 7f0fa27a2c521d90aa35eac03f8d8f505804a2c4..a9c193ed169fe1a4b493fb860f07b10cd849736c 100644 --- a/es2panda/lexer/token/sourceLocation.h +++ b/es2panda/lexer/token/sourceLocation.h @@ -25,6 +25,11 @@ namespace panda::es2panda::lexer { +enum class SourceLocationFlag { + VALID_SOURCE_LOCATION, + INVALID_SOURCE_LOCATION +}; + class SourcePosition { public: explicit SourcePosition() noexcept = default; @@ -93,8 +98,9 @@ private: class LineIndex { public: explicit LineIndex(const util::StringView &source) noexcept; - NO_COPY_SEMANTIC(LineIndex); - NO_MOVE_SEMANTIC(LineIndex); + explicit LineIndex() noexcept = default; + DEFAULT_COPY_SEMANTIC(LineIndex); + DEFAULT_MOVE_SEMANTIC(LineIndex); ~LineIndex() = default; SourceLocation GetLocation(SourcePosition pos) noexcept; diff --git a/es2panda/parser/program/program.cpp b/es2panda/parser/program/program.cpp index 42bee0341657f3772c677b0a7d8125ae637bbb4b..128c80dd137285ab605aa552fb0b91687a2e5801 100644 --- a/es2panda/parser/program/program.cpp +++ b/es2panda/parser/program/program.cpp @@ -36,7 +36,8 @@ Program::Program(Program &&other) sourceCode_(other.sourceCode_), sourceFile_(other.sourceFile_), kind_(other.kind_), - extension_(other.extension_) + extension_(other.extension_), + lineIndex_(other.lineIndex_) { other.binder_ = nullptr; other.ast_ = nullptr; @@ -51,6 +52,7 @@ Program &Program::operator=(Program &&other) sourceFile_ = other.sourceFile_; kind_ = other.kind_; extension_ = other.extension_; + lineIndex_ = other.lineIndex_; other.ast_ = nullptr; diff --git a/es2panda/parser/program/program.h b/es2panda/parser/program/program.h index 75f399e87988d0fc6d7a4887ee99d3a88de43c7a..c32afee7a9a8df429db0eb8ce34d1d42a605ef46 100644 --- a/es2panda/parser/program/program.h +++ b/es2panda/parser/program/program.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_PARSER_INCLUDE_PROGRAM_H #define ES2PANDA_PARSER_INCLUDE_PROGRAM_H +#include #include #include #include @@ -77,6 +78,11 @@ public: return sourceFile_.View(); } + const lexer::LineIndex &GetLineIndex() const + { + return lineIndex_; + } + ir::BlockStatement *Ast() { return ast_; @@ -96,6 +102,7 @@ public: { sourceCode_ = util::UString(sourceCode, Allocator()); sourceFile_ = util::UString(sourceFile, Allocator()); + lineIndex_ = lexer::LineIndex(SourceCode()); } std::string Dump() const; @@ -109,6 +116,7 @@ private: util::UString sourceFile_ {}; ScriptKind kind_ {}; ScriptExtension extension_ {}; + lexer::LineIndex lineIndex_ {}; }; } // namespace panda::es2panda::parser