Core: Add scripting debugger callbacks
@@ -10,9 +10,12 @@ #include <mgba-util/common.h>
CXX_GUARD_START +#ifdef USE_DEBUGGERS +#include <mgba/debugger/debugger.h> +#endif + struct mScriptBridge; struct VFile; -struct mDebugger; struct mScriptEngine { const char* (*name)(struct mScriptEngine*);@@ -21,6 +24,10 @@ void (*deinit)(struct mScriptEngine*);
bool (*isScript)(struct mScriptEngine*, const char* name, struct VFile* vf); bool (*loadScript)(struct mScriptEngine*, const char* name, struct VFile* vf); void (*run)(struct mScriptEngine*); + +#ifdef USE_DEBUGGERS + void (*debuggerEntered)(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); +#endif }; struct mScriptBridge* mScriptBridgeCreate(void);@@ -28,8 +35,11 @@ void mScriptBridgeDestroy(struct mScriptBridge*);
void mScriptBridgeInstallEngine(struct mScriptBridge*, struct mScriptEngine*); +#ifdef USE_DEBUGGERS void mScriptBridgeSetDebugger(struct mScriptBridge*, struct mDebugger*); struct mDebugger* mScriptBridgeGetDebugger(struct mScriptBridge*); +void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); +#endif void mScriptBridgeRun(struct mScriptBridge*); bool mScriptBridgeLoadScript(struct mScriptBridge*, const char* name);
@@ -30,7 +30,6 @@ enum mDebuggerState {
DEBUGGER_PAUSED, DEBUGGER_RUNNING, DEBUGGER_CUSTOM, - DEBUGGER_SCRIPT, DEBUGGER_SHUTDOWN };
@@ -428,7 +428,7 @@ debugger->backend->printf(debugger->backend, "Needs a filename\n");
return; } if (debugger->d.bridge && mScriptBridgeLoadScript(debugger->d.bridge, dv->charValue)) { - debugger->d.state = DEBUGGER_SCRIPT; + mScriptBridgeRun(debugger->d.bridge); } else { debugger->backend->printf(debugger->backend, "Failed to load script\n"); }
@@ -97,14 +97,6 @@ } else {
debugger->state = DEBUGGER_RUNNING; } break; - case DEBUGGER_SCRIPT: -#ifdef ENABLE_SCRIPTING - mScriptBridgeRun(debugger->bridge); -#endif - if (debugger->state == DEBUGGER_SCRIPT) { - debugger->state = DEBUGGER_PAUSED; - } - break; case DEBUGGER_SHUTDOWN: return; }@@ -122,6 +114,11 @@ debugger->state = DEBUGGER_PAUSED;
if (debugger->platform->entered) { debugger->platform->entered(debugger->platform, reason, info); } +#ifdef ENABLE_SCRIPTING + if (debugger->bridge) { + mScriptBridgeDebuggerEntered(debugger->bridge, reason, info); + } +#endif } static void mDebuggerInit(void* cpu, struct mCPUComponent* component) {
@@ -32,6 +32,7 @@ file(GLOB PYTHON_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
add_library(${BINARY_NAME}-pylib STATIC ${CMAKE_CURRENT_BINARY_DIR}/lib.c ${PYTHON_SRC}) add_dependencies(${BINARY_NAME}-pylib ${CMAKE_CURRENT_SOURCE_DIR}/_builder.py) set_target_properties(${BINARY_NAME}-pylib PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR};${INCLUDE_DIRECTORIES}") +set_target_properties(${BINARY_NAME}-pylib PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") set(PYTHON_LIBRARY ${BINARY_NAME}-pylib PARENT_SCOPE) add_custom_target(${BINARY_NAME}-py ALL DEPENDS ${BINARY_NAME}-pylib ${CMAKE_CURRENT_BINARY_DIR}/build/lib/${BINARY_NAME}/__init__.py)
@@ -78,6 +78,8 @@ @ffi.def_extern()
def mPythonSetDebugger(_debugger): from mgba.debugger import NativeDebugger global debugger + if debugger and debugger._native == _debugger: + return debugger = _debugger and NativeDebugger(_debugger) @ffi.def_extern()@@ -99,6 +101,16 @@ global pendingCode
for code in pendingCode: exec(code) pendingCode = [] + + @ffi.def_extern() + def mPythonDebuggerEntered(reason, info): + global debugger + if not debugger: + return + if info == ffi.NULL: + info = None + for cb in debugger._cbs: + cb(reason, info) """) if __name__ == "__main__":
@@ -6,9 +6,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "engine.h" #include <mgba/core/scripting.h> -#include <mgba/debugger/debugger.h> #include <mgba-util/string.h> #include <mgba-util/vfs.h> + +#ifdef USE_DEBUGGERS +#include <mgba/debugger/debugger.h> +#endif #include "lib.h"@@ -19,6 +22,10 @@ static bool mPythonScriptEngineIsScript(struct mScriptEngine*, const char* name, struct VFile* vf);
static bool mPythonScriptEngineLoadScript(struct mScriptEngine*, const char* name, struct VFile* vf); static void mPythonScriptEngineRun(struct mScriptEngine*); +#ifdef USE_DEBUGGERS +static void mPythonScriptDebuggerEntered(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); +#endif + struct mPythonScriptEngine { struct mScriptEngine d; struct mScriptBridge* sb;@@ -32,6 +39,9 @@ engine->d.deinit = mPythonScriptEngineDeinit;
engine->d.isScript = mPythonScriptEngineIsScript; engine->d.loadScript = mPythonScriptEngineLoadScript; engine->d.run = mPythonScriptEngineRun; +#ifdef USE_DEBUGGERS + engine->d.debuggerEntered = mPythonScriptDebuggerEntered; +#endif engine->sb = NULL; return engine; }@@ -78,3 +88,16 @@ }
mPythonRunPending(); } + +#ifdef USE_DEBUGGERS +void mPythonScriptDebuggerEntered(struct mScriptEngine* se, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { + struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; + + struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb); + if (!debugger) { + return; + } + + mPythonDebuggerEntered(reason, info); +} +#endif
@@ -1,6 +1,11 @@
-struct mDebugger; +#include "flags.h" + struct VFile; -extern void mPythonSetDebugger(struct mDebugger*); extern bool mPythonLoadScript(const char*, struct VFile*); extern void mPythonRunPending(); + +#ifdef USE_DEBUGGERS +extern void mPythonSetDebugger(struct mDebugger*); +extern void mPythonDebuggerEntered(enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); +#endif
@@ -26,8 +26,18 @@ WATCHPOINT_WRITE = lib.WATCHPOINT_WRITE
WATCHPOINT_READ = lib.WATCHPOINT_READ WATCHPOINT_RW = lib.WATCHPOINT_RW + BREAKPOINT_HARDWARE = lib.BREAKPOINT_HARDWARE + BREAKPOINT_SOFTWARE = lib.BREAKPOINT_SOFTWARE + + ENTER_MANUAL = lib.DEBUGGER_ENTER_MANUAL + ENTER_ATTACHED = lib.DEBUGGER_ENTER_ATTACHED + ENTER_BREAKPOINT = lib.DEBUGGER_ENTER_BREAKPOINT + ENTER_WATCHPOINT = lib.DEBUGGER_ENTER_WATCHPOINT + ENTER_ILLEGAL_OP = lib.DEBUGGER_ENTER_ILLEGAL_OP + def __init__(self, native): self._native = native + self._cbs = [] self._core = Core._detect(native.core) self._core._wasReset = True@@ -65,3 +75,6 @@ def clearWatchpoint(self, address):
if not self._native.platform.clearWatchpoint: raise RuntimeError("Platform does not support watchpoints") self._native.platform.clearWatchpoint(self._native.platform, address) + + def addCallback(self, cb): + self._cbs.append(cb)