From f3ba5f769211302d1d4629de53fa288d184d3d20 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 13 May 2022 00:40:18 -0700 Subject: [PATCH] Scripting: API cleanup --- include/mgba/core/thread.h | 7 +++---- include/mgba/script/context.h | 4 +++- include/mgba/script/types.h | 3 ++- src/core/scripting.c | 1 - src/core/test/scripting.c | 4 +--- src/core/thread.c | 1 + src/script/context.c | 26 ++++++++++++++++++++------ src/script/engines/lua.c | 19 ++++++++----------- src/script/test/lua.c | 12 +++--------- src/script/types.c | 15 +++++++++++++++ 10 files changed, 56 insertions(+), 36 deletions(-) diff --git a/include/mgba/core/thread.h b/include/mgba/core/thread.h index 72e9de7b5..aa059f652 100644 --- a/include/mgba/core/thread.h +++ b/include/mgba/core/thread.h @@ -11,10 +11,6 @@ CXX_GUARD_START #include -#ifdef ENABLE_SCRIPTING -#include -#include -#endif struct mCoreThread; struct mCore; @@ -27,6 +23,9 @@ struct mThreadLogger { struct mCoreThread* p; }; +#ifdef ENABLE_SCRIPTING +struct mScriptContext; +#endif struct mCoreThreadInternal; struct mCoreThread { // Input diff --git a/include/mgba/script/context.h b/include/mgba/script/context.h index bc9233025..8104295d7 100644 --- a/include/mgba/script/context.h +++ b/include/mgba/script/context.h @@ -45,7 +45,7 @@ struct mScriptEngineContext { bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*); struct mScriptValue* (*getGlobal)(struct mScriptEngineContext*, const char* name); - bool (*load)(struct mScriptEngineContext*, struct VFile*, const char** error); + bool (*load)(struct mScriptEngineContext*, struct VFile*); bool (*run)(struct mScriptEngineContext*); const char* (*getError)(struct mScriptEngineContext*); }; @@ -60,7 +60,9 @@ struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext* void mScriptContextRegisterEngines(struct mScriptContext*); void mScriptContextSetGlobal(struct mScriptContext*, const char* key, struct mScriptValue* value); +struct mScriptValue* mScriptContextGetGlobal(struct mScriptContext*, const char* key); void mScriptContextRemoveGlobal(struct mScriptContext*, const char* key); +struct mScriptValue* mScriptContextEnsureGlobal(struct mScriptContext*, const char* key, const struct mScriptType* type); uint32_t mScriptContextSetWeakref(struct mScriptContext*, struct mScriptValue* value); struct mScriptValue* mScriptContextMakeWeakref(struct mScriptContext*, struct mScriptValue* value); diff --git a/include/mgba/script/types.h b/include/mgba/script/types.h index 69d7abd66..9c008717b 100644 --- a/include/mgba/script/types.h +++ b/include/mgba/script/types.h @@ -491,7 +491,6 @@ enum mScriptTypeBase { mSCRIPT_TYPE_FUNCTION, mSCRIPT_TYPE_OPAQUE, mSCRIPT_TYPE_OBJECT, - mSCRIPT_TYPE_TUPLE, mSCRIPT_TYPE_LIST, mSCRIPT_TYPE_TABLE, mSCRIPT_TYPE_WRAPPER, @@ -645,6 +644,8 @@ struct mScriptValue* mScriptValueUnwrap(struct mScriptValue* val); const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val); struct mScriptValue* mScriptStringCreateFromUTF8(const char* string); +struct mScriptValue* mScriptValueCreateFromUInt(uint32_t value); +struct mScriptValue* mScriptValueCreateFromSInt(int32_t value); bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value); bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key); diff --git a/src/core/scripting.c b/src/core/scripting.c index 52fa9a76b..7618e72f8 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -315,7 +315,6 @@ static void _rebuildMemoryMap(struct mScriptCoreAdapter* adapter) { struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName); mScriptTableInsert(&adapter->memory, key, value); mScriptValueDeref(key); - mScriptValueDeref(value); } } diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index 0f5e55f7f..fd6dbc8ca 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -69,9 +69,7 @@ static const uint8_t _fakeGBROM[0x4000] = { #define LOAD_PROGRAM(PROG) \ do { \ struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \ - const char* error = NULL; \ - assert_true(lua->load(lua, vf, &error)); \ - assert_null(error); \ + assert_true(lua->load(lua, vf)); \ vf->close(vf); \ } while(0) diff --git a/src/core/thread.c b/src/core/thread.c index fb773e8ba..ee46569cd 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -8,6 +8,7 @@ #include #include #ifdef ENABLE_SCRIPTING +#include #include #endif #include diff --git a/src/script/context.c b/src/script/context.c index 9778a6ebe..2ee2dead0 100644 --- a/src/script/context.c +++ b/src/script/context.c @@ -59,7 +59,7 @@ void mScriptContextInit(struct mScriptContext* context) { HashTableInit(&context->engines, 0, _engineContextDestroy); mScriptListInit(&context->refPool, 0); TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref); - context->nextWeakref = 0; + context->nextWeakref = 1; HashTableInit(&context->callbacks, 0, (void (*)(void*)) mScriptValueDeref); } @@ -123,10 +123,7 @@ void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, st if (oldValue) { mScriptContextClearWeakref(context, oldValue->value.u32); } - uint32_t weakref = mScriptContextSetWeakref(context, value); - mScriptValueDeref(value); - value = mScriptValueAlloc(mSCRIPT_TYPE_MS_WEAKREF); - value->value.u32 = weakref; + value = mScriptContextMakeWeakref(context, value); HashTableInsert(&context->rootScope, key, value); struct mScriptKVPair pair = { .key = key, @@ -135,6 +132,14 @@ void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, st HashTableEnumerate(&context->engines, _contextAddGlobal, &pair); } +struct mScriptValue* mScriptContextGetGlobal(struct mScriptContext* context, const char* key) { + struct mScriptValue* weakref = HashTableLookup(&context->rootScope, key); + if (!weakref) { + return NULL; + } + return mScriptContextAccessWeakref(context, weakref); +} + void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key) { if (!HashTableLookup(&context->rootScope, key)) { return; @@ -148,6 +153,15 @@ void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key) } } +struct mScriptValue* mScriptContextEnsureGlobal(struct mScriptContext* context, const char* key, const struct mScriptType* type) { + struct mScriptValue* value = mScriptContextGetGlobal(context, key); + if (!value) { + mScriptContextSetGlobal(context, key, mScriptValueAlloc(type)); + value = mScriptContextGetGlobal(context, key); + } + return value; +} + uint32_t mScriptContextSetWeakref(struct mScriptContext* context, struct mScriptValue* value) { mScriptValueRef(value); TableInsert(&context->weakrefs, context->nextWeakref, value); @@ -219,7 +233,7 @@ bool mScriptContextLoadVF(struct mScriptContext* context, const char* name, stru if (!info.context) { return false; } - return info.context->load(info.context, vf, NULL); + return info.context->load(info.context, vf); } bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) { diff --git a/src/script/engines/lua.c b/src/script/engines/lua.c index b7153af1c..8533b7a22 100644 --- a/src/script/engines/lua.c +++ b/src/script/engines/lua.c @@ -18,7 +18,7 @@ static void _luaDestroy(struct mScriptEngineContext*); static bool _luaIsScript(struct mScriptEngineContext*, const char*, struct VFile*); static struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext*, const char* name); static bool _luaSetGlobal(struct mScriptEngineContext*, const char* name, struct mScriptValue*); -static bool _luaLoad(struct mScriptEngineContext*, struct VFile*, const char** error); +static bool _luaLoad(struct mScriptEngineContext*, struct VFile*); static bool _luaRun(struct mScriptEngineContext*); static const char* _luaGetError(struct mScriptEngineContext*); @@ -333,28 +333,25 @@ static const char* _reader(lua_State* lua, void* context, size_t* size) { return reader->block; } -bool _luaLoad(struct mScriptEngineContext* ctx, struct VFile* vf, const char** error) { +bool _luaLoad(struct mScriptEngineContext* ctx, struct VFile* vf) { struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx; struct mScriptEngineLuaReader data = { .vf = vf }; + if (luaContext->lastError) { + free(luaContext->lastError); + luaContext->lastError = NULL; + } int ret = lua_load(luaContext->lua, _reader, &data, NULL, "t"); switch (ret) { case LUA_OK: - if (error) { - *error = NULL; - } luaContext->func = luaL_ref(luaContext->lua, LUA_REGISTRYINDEX); return true; case LUA_ERRSYNTAX: - if (error) { - *error = "Syntax error"; - } + luaContext->lastError = strdup(lua_tostring(luaContext->lua, -1)); + lua_pop(luaContext->lua, 1); break; default: - if (error) { - *error = "Unknown error"; - } break; } return false; diff --git a/src/script/test/lua.c b/src/script/test/lua.c index 437fe4131..d0889ce86 100644 --- a/src/script/test/lua.c +++ b/src/script/test/lua.c @@ -15,9 +15,7 @@ #define LOAD_PROGRAM(PROG) \ do { \ struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \ - const char* error = NULL; \ - assert_true(lua->load(lua, vf, &error)); \ - assert_null(error); \ + assert_true(lua->load(lua, vf)); \ vf->close(vf); \ } while(0) @@ -116,9 +114,7 @@ M_TEST_DEFINE(loadGood) { const char* program = "-- test\n"; struct VFile* vf = VFileFromConstMemory(program, strlen(program)); - const char* error = NULL; - assert_true(lua->load(lua, vf, &error)); - assert_null(error); + assert_true(lua->load(lua, vf)); lua->destroy(lua); mScriptContextDeinit(&context); @@ -132,9 +128,7 @@ M_TEST_DEFINE(loadBadSyntax) { const char* program = "Invalid syntax! )\n"; struct VFile* vf = VFileFromConstMemory(program, strlen(program)); - const char* error = NULL; - assert_false(lua->load(lua, vf, &error)); - assert_non_null(error); + assert_false(lua->load(lua, vf)); lua->destroy(lua); mScriptContextDeinit(&context); diff --git a/src/script/types.c b/src/script/types.c index a6ba0abc4..b455b11de 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -741,6 +741,17 @@ struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) { internal->buffer = strdup(string); return val; } +struct mScriptValue* mScriptValueCreateFromSInt(int32_t value) { + struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_S32); + val->value.s32 = value; + return val; +} + +struct mScriptValue* mScriptValueCreateFromUInt(uint32_t value) { + struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_U32); + val->value.u32 = value; + return val; +} bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value) { if (table->type != mSCRIPT_TYPE_MS_TABLE) { @@ -768,6 +779,9 @@ bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key) { } struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScriptValue* key) { + if (table->type == mSCRIPT_TYPE_MS_WRAPPER) { + table = mScriptValueUnwrap(table); + } if (table->type != mSCRIPT_TYPE_MS_TABLE) { return false; } @@ -1003,6 +1017,7 @@ static bool _accessRawMember(struct mScriptClassMember* member, void* raw, bool break; case mSCRIPT_TYPE_TABLE: val->refs = mSCRIPT_VALUE_UNREF; + val->flags = 0; val->type = mSCRIPT_TYPE_MS_WRAPPER; val->value.opaque = raw; break;