Prepare flatbuffer support

This commit is contained in:
momo5502
2025-04-27 17:40:51 +02:00
parent 1c671da641
commit d6abbc7e37
11 changed files with 220 additions and 102 deletions

3
.gitmodules vendored
View File

@@ -22,3 +22,6 @@
path = deps/json
url = https://github.com/nlohmann/json.git
branch = master
[submodule "deps/flatbuffers"]
path = deps/flatbuffers
url = https://github.com/google/flatbuffers.git

4
deps/CMakeLists.txt vendored
View File

@@ -3,7 +3,9 @@ add_subdirectory(unicorn)
##########################################
add_subdirectory(json)
option(FLATBUFFERS_BUILD_TESTS "" OFF)
option(FLATBUFFERS_INSTALL "" OFF)
add_subdirectory(flatbuffers)
##########################################

1
deps/flatbuffers vendored Submodule

Submodule deps/flatbuffers added at 609c72ca1a

View File

@@ -16,7 +16,7 @@ endif()
target_link_libraries(debugger PRIVATE
windows-emulator
nlohmann_json
flatbuffers
)
set_property(GLOBAL PROPERTY VS_STARTUP_PROJECT debugger)

View File

@@ -0,0 +1,56 @@
#include "event_handler.hpp"
#include "events.hpp"
#include "message_transmitter.hpp"
namespace debugger
{
namespace
{
void handle_event(event_context& c, const event& e, const nlohmann::json& obj)
{
switch (e.type)
{
case event_type::pause:
c.win_emu.emu().stop();
break;
case event_type::run:
c.resume = true;
break;
default:
break;
}
}
void handle_object(event_context& c, const nlohmann::json& obj)
{
try
{
const auto e = obj.get<event>();
handle_event(c, e, obj);
}
catch (const std::exception& e)
{
puts(e.what());
}
}
}
void handle_events(event_context& c)
{
while (true)
{
suspend_execution(0ms);
const auto obj = receive_object();
if (obj.is_null())
{
break;
}
handle_object(c, obj);
}
}
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <windows_emulator.hpp>
namespace debugger
{
struct event_context
{
windows_emulator& win_emu;
bool resume{false};
};
void handle_events(event_context& c);
}

0
src/debugger/events.fbs Normal file
View File

38
src/debugger/events.hpp Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
namespace debugger
{
enum class event_type
{
invalid = 0,
pause = 1,
run = 2,
register_request = 3,
register_response = 4,
write_memory_request = 5,
write_memory_response = 6,
read_memory_request = 7,
read_memory_response = 8,
};
struct event
{
event_type type{event_type::invalid};
};
template <event_type Type>
struct typed_event : event
{
typed_event()
: event{
.type = Type,
}
{
}
};
using pause_event = typed_event<event_type::pause>;
using run_event = typed_event<event_type::run>;
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(event, type);
}

View File

@@ -2,110 +2,12 @@
#include <windows_emulator.hpp>
#include <cstdio>
#include <nlohmann/json.hpp>
#ifdef OS_EMSCRIPTEN
#include <emscripten.h>
#endif
#include "event_handler.hpp"
#include <utils/finally.hpp>
namespace
{
void suspend_execution(const std::chrono::milliseconds ms = 0ms)
{
#ifdef OS_EMSCRIPTEN
emscripten_sleep(static_cast<uint32_t>(ms.count()));
#else
if (ms > 0ms)
{
std::this_thread::sleep_for(ms);
}
else
{
std::this_thread::yield();
}
#endif
}
void send_message(const std::string& message)
{
#ifdef OS_EMSCRIPTEN
// clang-format off
EM_ASM_({
handleMessage(UTF8ToString($0));
}, message.c_str());
// clang-format on
#else
(void)message;
#endif
}
std::string receive_message()
{
#ifdef OS_EMSCRIPTEN
// clang-format off
auto* ptr = EM_ASM_PTR({
var message = getMessageFromQueue();
if (!message || message.length == 0)
{
return null;
}
const length = lengthBytesUTF8(message) + 1;
const buffer = _malloc(length);
stringToUTF8(message, buffer, length);
return buffer;
});
// clang-format on
if (!ptr)
{
return {};
}
const auto _ = utils::finally([&] {
free(ptr); //
});
return {reinterpret_cast<const char*>(ptr)};
#else
return {};
#endif
}
void send_object(const nlohmann::json& json)
{
const std::string res = json.dump();
send_message(res);
}
nlohmann::json receive_object()
{
auto message = receive_message();
if (message.empty())
{
return {};
}
return nlohmann::json::parse(message);
}
void handle_messages(windows_emulator& win_emu)
{
while (true)
{
suspend_execution(0ms);
const auto message = receive_object();
if (message.is_null())
{
break;
}
puts(message.dump().c_str());
}
}
bool run_emulation(windows_emulator& win_emu)
{
try
@@ -162,7 +64,8 @@ namespace
windows_emulator win_emu{app_settings, settings};
win_emu.callbacks.on_thread_switch = [&] {
handle_messages(win_emu); //
debugger::event_context c{.win_emu = win_emu};
debugger::handle_events(c); //
};
return run_emulation(win_emu);

View File

@@ -0,0 +1,91 @@
#include "message_transmitter.hpp"
#include <platform/compiler.hpp>
#ifdef OS_EMSCRIPTEN
#include <emscripten.h>
#endif
namespace debugger
{
namespace
{
void send_message(const std::string& message)
{
#ifdef OS_EMSCRIPTEN
// clang-format off
EM_ASM_({
handleMessage(UTF8ToString($0));
}, message.c_str());
// clang-format on
#else
(void)message;
#endif
}
std::string receive_message()
{
#ifdef OS_EMSCRIPTEN
// clang-format off
auto* ptr = EM_ASM_PTR({
var message = getMessageFromQueue();
if (!message || message.length == 0)
{
return null;
}
const length = lengthBytesUTF8(message) + 1;
const buffer = _malloc(length);
stringToUTF8(message, buffer, length);
return buffer;
});
// clang-format on
if (!ptr)
{
return {};
}
const auto _ = utils::finally([&] {
free(ptr); //
});
return {reinterpret_cast<const char*>(ptr)};
#else
return {};
#endif
}
void send_object(const nlohmann::json& json)
{
const std::string res = json.dump();
send_message(res);
}
nlohmann::json receive_object()
{
auto message = receive_message();
if (message.empty())
{
return {};
}
return nlohmann::json::parse(message);
}
void suspend_execution(const std::chrono::milliseconds ms)
{
#ifdef OS_EMSCRIPTEN
emscripten_sleep(static_cast<uint32_t>(ms.count()));
#else
if (ms > 0ms)
{
std::this_thread::sleep_for(ms);
}
else
{
std::this_thread::yield();
}
#endif
}
}
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <nlohmann/json.hpp>
namespace debugger
{
void suspend_execution(const std::chrono::milliseconds ms = 0ms);
void send_object(const nlohmann::json& json);
nlohmann::json receive_object();
}