From 7f777b5e3d27d22e2d9f8329930ce88213ea588a Mon Sep 17 00:00:00 2001 From: ineed bots Date: Wed, 27 Dec 2023 14:57:53 -0600 Subject: [PATCH] feature(compiler): produce a developer map, mapping instruction opcode pos to source line number --- include/xsk/arc/assembler.hpp | 2 ++ include/xsk/arc/common/assembly.hpp | 1 + include/xsk/arc/common/types.hpp | 2 +- include/xsk/arc/compiler.hpp | 1 + include/xsk/gsc/assembler.hpp | 2 ++ include/xsk/gsc/common/assembly.hpp | 1 + include/xsk/gsc/common/types.hpp | 2 +- include/xsk/gsc/compiler.hpp | 1 + src/arc/assembler.cpp | 13 +++++++++++++ src/arc/compiler.cpp | 19 +++++++++++++++++++ src/gsc/assembler.cpp | 13 +++++++++++++ src/gsc/compiler.cpp | 19 +++++++++++++++++++ src/tool/main.cpp | 14 ++++++++++++++ 13 files changed, 88 insertions(+), 2 deletions(-) diff --git a/include/xsk/arc/assembler.hpp b/include/xsk/arc/assembler.hpp index 792f502d..af215ebb 100644 --- a/include/xsk/arc/assembler.hpp +++ b/include/xsk/arc/assembler.hpp @@ -17,6 +17,7 @@ class assembler function const* func_; assembly const* assembly_; utils::writer script_; + utils::writer dev_map_; std::unordered_map strpool_; std::vector exports_; std::vector imports_; @@ -26,6 +27,7 @@ class assembler public: assembler(context const* ctx); auto assemble(assembly const& data, std::string const& name = {}) -> buffer; + auto get_dev_map() -> buffer; private: auto assemble_function(function& func) -> void; diff --git a/include/xsk/arc/common/assembly.hpp b/include/xsk/arc/common/assembly.hpp index a8c1b3a6..8efc27a5 100644 --- a/include/xsk/arc/common/assembly.hpp +++ b/include/xsk/arc/common/assembly.hpp @@ -166,6 +166,7 @@ struct instruction u32 size; opcode opcode; std::vector data; + std::optional pos; static auto make() -> instruction::ptr { diff --git a/include/xsk/arc/common/types.hpp b/include/xsk/arc/common/types.hpp index d9a6ccd2..d9f417a6 100644 --- a/include/xsk/arc/common/types.hpp +++ b/include/xsk/arc/common/types.hpp @@ -6,9 +6,9 @@ #pragma once #include "xsk/arc/common/asset.hpp" +#include "xsk/arc/common/location.hpp" #include "xsk/arc/common/assembly.hpp" #include "xsk/arc/common/buffer.hpp" -#include "xsk/arc/common/location.hpp" #include "xsk/arc/common/exception.hpp" #include "xsk/arc/common/lookahead.hpp" #include "xsk/arc/common/directive.hpp" diff --git a/include/xsk/arc/compiler.hpp b/include/xsk/arc/compiler.hpp index 47ad5fd7..ea0d5c06 100644 --- a/include/xsk/arc/compiler.hpp +++ b/include/xsk/arc/compiler.hpp @@ -25,6 +25,7 @@ class compiler bool can_break_; bool can_continue_; bool developer_thread_; + std::optional debug_pos_; public: compiler(context* ctx); diff --git a/include/xsk/gsc/assembler.hpp b/include/xsk/gsc/assembler.hpp index 98fa1613..1cd5e62a 100644 --- a/include/xsk/gsc/assembler.hpp +++ b/include/xsk/gsc/assembler.hpp @@ -18,10 +18,12 @@ class assembler assembly const* assembly_; utils::writer script_; utils::writer stack_; + utils::writer dev_map_; public: assembler(context const* ctx); auto assemble(assembly const& data) -> std::pair; + auto get_dev_map() -> buffer; private: auto assemble_function(function const& func) -> void; diff --git a/include/xsk/gsc/common/assembly.hpp b/include/xsk/gsc/common/assembly.hpp index e4dd6df1..73f199b4 100644 --- a/include/xsk/gsc/common/assembly.hpp +++ b/include/xsk/gsc/common/assembly.hpp @@ -228,6 +228,7 @@ struct instruction u32 size; opcode opcode; std::vector data; + std::optional pos; static auto make() -> instruction::ptr { diff --git a/include/xsk/gsc/common/types.hpp b/include/xsk/gsc/common/types.hpp index 32fe5376..b9dc7f74 100644 --- a/include/xsk/gsc/common/types.hpp +++ b/include/xsk/gsc/common/types.hpp @@ -8,8 +8,8 @@ #include "xsk/gsc/common/asset.hpp" #include "xsk/gsc/common/scope.hpp" #include "xsk/gsc/common/buffer.hpp" -#include "xsk/gsc/common/assembly.hpp" #include "xsk/gsc/common/location.hpp" +#include "xsk/gsc/common/assembly.hpp" #include "xsk/gsc/common/exception.hpp" #include "xsk/gsc/common/lookahead.hpp" #include "xsk/gsc/common/directive.hpp" diff --git a/include/xsk/gsc/compiler.hpp b/include/xsk/gsc/compiler.hpp index 19eb0726..fe5a897b 100644 --- a/include/xsk/gsc/compiler.hpp +++ b/include/xsk/gsc/compiler.hpp @@ -28,6 +28,7 @@ class compiler bool can_continue_; bool developer_thread_; bool animload_; + std::optional debug_pos_; public: compiler(context* ctx); diff --git a/src/arc/assembler.cpp b/src/arc/assembler.cpp index c7f53f2e..f88d9e67 100644 --- a/src/arc/assembler.cpp +++ b/src/arc/assembler.cpp @@ -18,6 +18,7 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> buffe { assembly_ = &data; script_.clear(); + dev_map_.clear(); strpool_.clear(); exports_.clear(); imports_.clear(); @@ -226,6 +227,11 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> buffe return buffer{ script_.data(), script_.pos() }; } +auto assembler::get_dev_map() -> buffer +{ + return buffer{ dev_map_.data(), dev_map_.pos() }; +} + auto assembler::assemble_function(function& func) -> void { auto labels = std::unordered_map(); @@ -270,6 +276,13 @@ auto assembler::assemble_function(function& func) -> void auto assembler::assemble_instruction(instruction const& inst) -> void { + if (inst.pos.has_value()) + { + dev_map_.write(script_.pos()); + dev_map_.write(inst.pos->line); + dev_map_.write(inst.pos->column); + } + script_.write(static_cast(ctx_->opcode_id(inst.opcode))); switch (inst.opcode) diff --git a/src/arc/compiler.cpp b/src/arc/compiler.cpp index 8e1b4e92..4aa4b0c9 100644 --- a/src/arc/compiler.cpp +++ b/src/arc/compiler.cpp @@ -138,6 +138,8 @@ auto compiler::emit_decl_function(decl_function const& func) -> void auto compiler::emit_stmt(stmt const& stm) -> void { + debug_pos_ = stm.loc().begin; + switch (stm.kind()) { case node::stmt_list: @@ -686,6 +688,8 @@ auto compiler::emit_stmt_prof_end(stmt_prof_end const&) -> void auto compiler::emit_expr(expr const& exp) -> void { + debug_pos_ = exp.loc().begin; + switch (exp.kind()) { case node::expr_paren: @@ -1867,6 +1871,11 @@ auto compiler::emit_opcode(opcode op) -> void inst->size = ctx_->opcode_size(op); inst->index = index_; + if (debug_pos_.has_value()) + { + inst->pos = debug_pos_; + } + index_ += inst->size; } @@ -1880,6 +1889,11 @@ auto compiler::emit_opcode(opcode op, std::string const& data) -> void inst->index = index_; inst->data.push_back(data); + if (debug_pos_.has_value()) + { + inst->pos = debug_pos_; + } + index_ += inst->size; } @@ -1893,6 +1907,11 @@ auto compiler::emit_opcode(opcode op, std::vector const& data) -> v inst->index = index_; inst->data = data; + if (debug_pos_.has_value()) + { + inst->pos = debug_pos_; + } + index_ += inst->size; } diff --git a/src/gsc/assembler.cpp b/src/gsc/assembler.cpp index b7113747..eccba686 100644 --- a/src/gsc/assembler.cpp +++ b/src/gsc/assembler.cpp @@ -19,6 +19,7 @@ auto assembler::assemble(assembly const& data) -> std::pair assembly_ = &data; script_.clear(); stack_.clear(); + dev_map_.clear(); script_.write(ctx_->opcode_id(opcode::OP_End)); @@ -30,6 +31,11 @@ auto assembler::assemble(assembly const& data) -> std::pair return { buffer{ script_.data(), script_.pos() }, buffer{ stack_.data(), stack_.pos() } }; } +auto assembler::get_dev_map() -> buffer +{ + return buffer{ dev_map_.data(), dev_map_.pos() }; +} + auto assembler::assemble_function(function const& func) -> void { func_ = &func; @@ -61,6 +67,13 @@ auto assembler::assemble_function(function const& func) -> void auto assembler::assemble_instruction(instruction const& inst) -> void { + if (inst.pos.has_value()) + { + dev_map_.write(script_.pos()); + dev_map_.write(inst.pos->line); + dev_map_.write(inst.pos->column); + } + script_.write(ctx_->opcode_id(inst.opcode)); switch (inst.opcode) diff --git a/src/gsc/compiler.cpp b/src/gsc/compiler.cpp index 4b37b6df..a0cb753f 100644 --- a/src/gsc/compiler.cpp +++ b/src/gsc/compiler.cpp @@ -147,6 +147,8 @@ auto compiler::emit_decl_function(decl_function const& func) -> void auto compiler::emit_stmt(stmt const& stm, scope& scp, bool last) -> void { + debug_pos_ = stm.loc().begin; + switch (stm.kind()) { case node::stmt_list: @@ -925,6 +927,8 @@ auto compiler::emit_stmt_assertmsg(stmt_assertmsg const&, scope&) -> void auto compiler::emit_expr(expr const& exp, scope& scp) -> void { + debug_pos_ = exp.loc().begin; + switch (exp.kind()) { case node::expr_paren: @@ -2198,6 +2202,11 @@ auto compiler::emit_opcode(opcode op) -> void inst->size = ctx_->opcode_size(op); inst->index = index_; + if (debug_pos_.has_value()) + { + inst->pos = debug_pos_; + } + index_ += inst->size; } @@ -2211,6 +2220,11 @@ auto compiler::emit_opcode(opcode op, std::string const& data) -> void inst->index = index_; inst->data.push_back(data); + if (debug_pos_.has_value()) + { + inst->pos = debug_pos_; + } + index_ += inst->size; } @@ -2224,6 +2238,11 @@ auto compiler::emit_opcode(opcode op, std::vector const& data) -> v inst->index = index_; inst->data = data; + if (debug_pos_.has_value()) + { + inst->pos = debug_pos_; + } + index_ += inst->size; } diff --git a/src/tool/main.cpp b/src/tool/main.cpp index fa9163b2..bbe45d5a 100644 --- a/src/tool/main.cpp +++ b/src/tool/main.cpp @@ -286,6 +286,13 @@ auto compile_file(game game, mach mach, fs::path file, fs::path rel) -> void auto result = script.serialize(); utils::file::save(fs::path{ "compiled" } / rel, result); std::cout << fmt::format("compiled {}\n", rel.generic_string()); + + auto dev_map = contexts[game][mach]->assembler().get_dev_map(); + if (dev_map.size > 0) + { + utils::file::save(fs::path{ "compiled" } / fs::path{ "developer_maps" } / rel, dev_map.data, dev_map.size); + std::cout << fmt::format("wrote developer map {}\n", rel.generic_string()); + } } } } @@ -753,6 +760,13 @@ void compile_file(game game, mach mach, fs::path const& file, fs::path rel) utils::file::save(fs::path{ "compiled" } / rel, outbin.data, outbin.size); std::cout << fmt::format("compiled {}\n", rel.generic_string()); + + auto dev_map = contexts[game][mach]->assembler().get_dev_map(); + if (dev_map.size > 0) + { + utils::file::save(fs::path{ "compiled" } / fs::path{ "developer_maps" } / rel, dev_map.data, dev_map.size); + std::cout << fmt::format("wrote developer map {}\n", rel.generic_string()); + } } catch (std::exception const& e) {