diff --git a/furdb/include/command.hpp b/furdb/include/command.hpp index 37fb67d..96234e6 100644 --- a/furdb/include/command.hpp +++ b/furdb/include/command.hpp @@ -36,4 +36,9 @@ public: void execute(context& ctx, const command_info& info) override; }; +class break_command final : public command { +public: + void execute(context& ctx, const command_info& info) override; +}; + #endif // COMMAND_HPP diff --git a/furdb/include/context.hpp b/furdb/include/context.hpp index 10c01cc..eb856b8 100644 --- a/furdb/include/context.hpp +++ b/furdb/include/context.hpp @@ -13,6 +13,7 @@ struct context { furvm::function_h mainFunction; bool running = true; + bool halt = false; void run(); }; diff --git a/furdb/src/command.cpp b/furdb/src/command.cpp index 1eee327..fbba535 100644 --- a/furdb/src/command.cpp +++ b/furdb/src/command.cpp @@ -1,5 +1,10 @@ #include "command.hpp" +#include "furvm/executor.hpp" +#include "furvm/function.hpp" +#include "furvm/module.hpp" +#include "furvm/thing.hpp" + #include #include #include @@ -51,5 +56,31 @@ void quit_command::execute(context& ctx, const command_info& info) { void run_command::execute(context& ctx, const command_info& info) { ctx.run(); - std::cout << "Execution finished\n"; +} + +static void breakpoint_hit(furvm::executor& executor, void* data) { + std::cout << "Breakpoint hit\n"; + context* ctx = reinterpret_cast(data); + ctx->halt = true; +} + +void break_command::execute(context& ctx, const command_info& info) { + if (info.args.empty()) { + std::cerr << "Usage: " << info.commandName << " \n"; + return; + } + + std::size_t count = 0; + for (const auto& [id, sigPair] : ctx.mod->function_map()) { + if (sigPair.first != info.args[0]) continue; + const auto& func = ctx.mod->function_at(id); + if (func->type() != furvm::function_t::Normal) continue; + count += 1; + ctx.mod->set_breakpoint(func->position(), furvm::breakpoint{ breakpoint_hit, &ctx }); + } + if (count == 0) { + std::cerr << "No function \"" << info.args[0] << "\" found!\n"; + return; + } + std::cout << "Breakpoint set in " << count << " places\n"; } diff --git a/furdb/src/context.cpp b/furdb/src/context.cpp index 9f4d1ee..c717610 100644 --- a/furdb/src/context.cpp +++ b/furdb/src/context.cpp @@ -1,9 +1,15 @@ #include "context.hpp" +#include +#include + void context::run() { if ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done) executor->push_frame(mod, *mainFunction); - while ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done) { + while ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done && !halt) { executor->step(); } + if ((executor->flags() & furvm::executor_flags::Done) == furvm::executor_flags::Done) { + std::cout << "Execution finished\n"; + } } diff --git a/furdb/src/main.cpp b/furdb/src/main.cpp index d604531..a707628 100644 --- a/furdb/src/main.cpp +++ b/furdb/src/main.cpp @@ -43,8 +43,9 @@ int main(int argc, char** argv) { } static std::unordered_map s_commands; - s_commands["quit"] = s_commands["q"] = new quit_command(); + s_commands["exit"] = s_commands["quit"] = s_commands["q"] = new quit_command(); s_commands["run"] = s_commands["r"] = new run_command(); + s_commands["break"] = s_commands["b"] = new break_command(); try { std::ifstream file(argv[1], std::ios::binary | std::ios::in); diff --git a/furvm/include/furvm/module.hpp b/furvm/include/furvm/module.hpp index 2f1faf8..7a5df9f 100644 --- a/furvm/include/furvm/module.hpp +++ b/furvm/include/furvm/module.hpp @@ -147,7 +147,7 @@ struct mod_type { struct breakpoint { std::function callback; - void* data; + void* data = nullptr; }; class mod {