mirror of https://github.com/mgba-emu/mgba.git
Core: Add symbol lookups from scripts
This commit is contained in:
parent
6a3002d398
commit
220b786c9c
|
@ -24,6 +24,7 @@ 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*);
|
||||
bool (*lookupSymbol)(struct mScriptEngine*, const char* name, int32_t* out);
|
||||
|
||||
#ifdef USE_DEBUGGERS
|
||||
void (*debuggerEntered)(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
|
||||
|
@ -44,6 +45,8 @@ void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReas
|
|||
void mScriptBridgeRun(struct mScriptBridge*);
|
||||
bool mScriptBridgeLoadScript(struct mScriptBridge*, const char* name);
|
||||
|
||||
bool mScriptBridgeLookupSymbol(struct mScriptBridge*, const char* name, int32_t* out);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,12 @@ struct mScriptInfo {
|
|||
bool success;
|
||||
};
|
||||
|
||||
struct mScriptSymbol {
|
||||
const char* name;
|
||||
int32_t* out;
|
||||
bool success;
|
||||
};
|
||||
|
||||
static void _seDeinit(void* value) {
|
||||
struct mScriptEngine* se = value;
|
||||
se->deinit(se);
|
||||
|
@ -33,6 +39,15 @@ static void _seTryLoad(const char* key, void* value, void* user) {
|
|||
}
|
||||
}
|
||||
|
||||
static void _seLookupSymbol(const char* key, void* value, void* user) {
|
||||
UNUSED(key);
|
||||
struct mScriptEngine* se = value;
|
||||
struct mScriptSymbol* si = user;
|
||||
if (!si->success) {
|
||||
si->success = se->lookupSymbol(se, si->name, si->out);
|
||||
}
|
||||
}
|
||||
|
||||
static void _seRun(const char* key, void* value, void* user) {
|
||||
UNUSED(key);
|
||||
UNUSED(user);
|
||||
|
@ -111,3 +126,13 @@ bool mScriptBridgeLoadScript(struct mScriptBridge* sb, const char* name) {
|
|||
vf->close(vf);
|
||||
return info.success;
|
||||
}
|
||||
|
||||
bool mScriptBridgeLookupSymbol(struct mScriptBridge* sb, const char* name, int32_t* out) {
|
||||
struct mScriptSymbol info = {
|
||||
.name = name,
|
||||
.out = out,
|
||||
.success = false
|
||||
};
|
||||
HashTableEnumerate(&sb->engines, _seLookupSymbol, &info);
|
||||
return info.success;
|
||||
}
|
||||
|
|
|
@ -551,6 +551,11 @@ static void _lookupIdentifier(struct mDebugger* debugger, const char* name, stru
|
|||
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
|
||||
if (cliDebugger->system) {
|
||||
uint32_t value;
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
if (debugger->bridge && mScriptBridgeLookupSymbol(debugger->bridge, name, &dv->intValue)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (debugger->core->symbolTable && mDebuggerSymbolLookup(debugger->core->symbolTable, name, &dv->intValue, &dv->segmentValue)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -72,22 +72,26 @@ ffi.embedding_api('\n'.join(lines))
|
|||
|
||||
ffi.embedding_init_code("""
|
||||
from mgba._pylib import ffi, lib
|
||||
debugger = None
|
||||
symbols = {}
|
||||
globalSyms = {
|
||||
'symbols': symbols
|
||||
}
|
||||
pendingCode = []
|
||||
|
||||
@ffi.def_extern()
|
||||
def mPythonSetDebugger(_debugger):
|
||||
def mPythonSetDebugger(debugger):
|
||||
from mgba.debugger import NativeDebugger, CLIDebugger
|
||||
global debugger
|
||||
if debugger and debugger._native == _debugger:
|
||||
oldDebugger = globalSyms.get('debugger')
|
||||
if oldDebugger and oldDebugger._native == debugger:
|
||||
return
|
||||
if not _debugger:
|
||||
debugger = None
|
||||
if oldDebugger and not debugger:
|
||||
del globalSyms['debugger']
|
||||
return
|
||||
if _debugger.type == lib.DEBUGGER_CLI:
|
||||
debugger = CLIDebugger(_debugger)
|
||||
if debugger.type == lib.DEBUGGER_CLI:
|
||||
debugger = CLIDebugger(debugger)
|
||||
else:
|
||||
debugger = NativeDebugger(_debugger)
|
||||
debugger = NativeDebugger(debugger)
|
||||
globalSyms['debugger'] = debugger
|
||||
|
||||
@ffi.def_extern()
|
||||
def mPythonLoadScript(name, vf):
|
||||
|
@ -106,18 +110,40 @@ ffi.embedding_init_code("""
|
|||
def mPythonRunPending():
|
||||
global pendingCode
|
||||
for code in pendingCode:
|
||||
exec(code)
|
||||
exec(code, globalSyms, {})
|
||||
pendingCode = []
|
||||
|
||||
@ffi.def_extern()
|
||||
def mPythonDebuggerEntered(reason, info):
|
||||
global debugger
|
||||
debugger = globalSyms['debugger']
|
||||
if not debugger:
|
||||
return
|
||||
if info == ffi.NULL:
|
||||
info = None
|
||||
for cb in debugger._cbs:
|
||||
cb(reason, info)
|
||||
|
||||
@ffi.def_extern()
|
||||
def mPythonLookupSymbol(name, outptr):
|
||||
name = ffi.string(name).decode('utf-8')
|
||||
if name not in symbols:
|
||||
return False
|
||||
sym = symbols[name]
|
||||
val = None
|
||||
try:
|
||||
val = int(sym)
|
||||
except:
|
||||
try:
|
||||
val = sym()
|
||||
except:
|
||||
pass
|
||||
if val is None:
|
||||
return False
|
||||
try:
|
||||
outptr[0] = ffi.cast('int32_t', val)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
""")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -21,6 +21,7 @@ static void mPythonScriptEngineDeinit(struct mScriptEngine*);
|
|||
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*);
|
||||
static bool mPythonScriptEngineLookupSymbol(struct mScriptEngine*, const char* name, int32_t* out);
|
||||
|
||||
#ifdef USE_DEBUGGERS
|
||||
static void mPythonScriptDebuggerEntered(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
|
||||
|
@ -39,6 +40,7 @@ struct mPythonScriptEngine* mPythonCreateScriptEngine(void) {
|
|||
engine->d.isScript = mPythonScriptEngineIsScript;
|
||||
engine->d.loadScript = mPythonScriptEngineLoadScript;
|
||||
engine->d.run = mPythonScriptEngineRun;
|
||||
engine->d.lookupSymbol = mPythonScriptEngineLookupSymbol;
|
||||
#ifdef USE_DEBUGGERS
|
||||
engine->d.debuggerEntered = mPythonScriptDebuggerEntered;
|
||||
#endif
|
||||
|
@ -89,6 +91,11 @@ void mPythonScriptEngineRun(struct mScriptEngine* se) {
|
|||
mPythonRunPending();
|
||||
}
|
||||
|
||||
bool mPythonScriptEngineLookupSymbol(struct mScriptEngine* se, const char* name, int32_t* out) {
|
||||
struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se;
|
||||
return mPythonLookupSymbol(name, out);
|
||||
}
|
||||
|
||||
#ifdef USE_DEBUGGERS
|
||||
void mPythonScriptDebuggerEntered(struct mScriptEngine* se, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
|
||||
struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se;
|
||||
|
|
|
@ -4,6 +4,7 @@ struct VFile;
|
|||
|
||||
extern bool mPythonLoadScript(const char*, struct VFile*);
|
||||
extern void mPythonRunPending();
|
||||
extern bool mPythonLookupSymbol(const char* name, int32_t* out);
|
||||
|
||||
#ifdef USE_DEBUGGERS
|
||||
extern void mPythonSetDebugger(struct mDebugger*);
|
||||
|
|
Loading…
Reference in New Issue