Scripting: API cleanup

This commit is contained in:
Vicki Pfau 2022-05-13 00:40:18 -07:00
parent ca073379fb
commit f3ba5f7692
10 changed files with 56 additions and 36 deletions

View File

@ -11,10 +11,6 @@
CXX_GUARD_START CXX_GUARD_START
#include <mgba/core/log.h> #include <mgba/core/log.h>
#ifdef ENABLE_SCRIPTING
#include <mgba/core/scripting.h>
#include <mgba/script/context.h>
#endif
struct mCoreThread; struct mCoreThread;
struct mCore; struct mCore;
@ -27,6 +23,9 @@ struct mThreadLogger {
struct mCoreThread* p; struct mCoreThread* p;
}; };
#ifdef ENABLE_SCRIPTING
struct mScriptContext;
#endif
struct mCoreThreadInternal; struct mCoreThreadInternal;
struct mCoreThread { struct mCoreThread {
// Input // Input

View File

@ -45,7 +45,7 @@ struct mScriptEngineContext {
bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*); bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*);
struct mScriptValue* (*getGlobal)(struct mScriptEngineContext*, const char* name); 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*); bool (*run)(struct mScriptEngineContext*);
const char* (*getError)(struct mScriptEngineContext*); const char* (*getError)(struct mScriptEngineContext*);
}; };
@ -60,7 +60,9 @@ struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*
void mScriptContextRegisterEngines(struct mScriptContext*); void mScriptContextRegisterEngines(struct mScriptContext*);
void mScriptContextSetGlobal(struct mScriptContext*, const char* key, struct mScriptValue* value); 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); 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); uint32_t mScriptContextSetWeakref(struct mScriptContext*, struct mScriptValue* value);
struct mScriptValue* mScriptContextMakeWeakref(struct mScriptContext*, struct mScriptValue* value); struct mScriptValue* mScriptContextMakeWeakref(struct mScriptContext*, struct mScriptValue* value);

View File

@ -491,7 +491,6 @@ enum mScriptTypeBase {
mSCRIPT_TYPE_FUNCTION, mSCRIPT_TYPE_FUNCTION,
mSCRIPT_TYPE_OPAQUE, mSCRIPT_TYPE_OPAQUE,
mSCRIPT_TYPE_OBJECT, mSCRIPT_TYPE_OBJECT,
mSCRIPT_TYPE_TUPLE,
mSCRIPT_TYPE_LIST, mSCRIPT_TYPE_LIST,
mSCRIPT_TYPE_TABLE, mSCRIPT_TYPE_TABLE,
mSCRIPT_TYPE_WRAPPER, mSCRIPT_TYPE_WRAPPER,
@ -645,6 +644,8 @@ struct mScriptValue* mScriptValueUnwrap(struct mScriptValue* val);
const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val); const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val);
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string); 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 mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value);
bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key); bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key);

View File

@ -315,7 +315,6 @@ static void _rebuildMemoryMap(struct mScriptCoreAdapter* adapter) {
struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName); struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName);
mScriptTableInsert(&adapter->memory, key, value); mScriptTableInsert(&adapter->memory, key, value);
mScriptValueDeref(key); mScriptValueDeref(key);
mScriptValueDeref(value);
} }
} }

View File

@ -69,9 +69,7 @@ static const uint8_t _fakeGBROM[0x4000] = {
#define LOAD_PROGRAM(PROG) \ #define LOAD_PROGRAM(PROG) \
do { \ do { \
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \ struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
const char* error = NULL; \ assert_true(lua->load(lua, vf)); \
assert_true(lua->load(lua, vf, &error)); \
assert_null(error); \
vf->close(vf); \ vf->close(vf); \
} while(0) } while(0)

View File

@ -8,6 +8,7 @@
#include <mgba/core/blip_buf.h> #include <mgba/core/blip_buf.h>
#include <mgba/core/core.h> #include <mgba/core/core.h>
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
#include <mgba/script/context.h>
#include <mgba/core/scripting.h> #include <mgba/core/scripting.h>
#endif #endif
#include <mgba/core/serialize.h> #include <mgba/core/serialize.h>

View File

@ -59,7 +59,7 @@ void mScriptContextInit(struct mScriptContext* context) {
HashTableInit(&context->engines, 0, _engineContextDestroy); HashTableInit(&context->engines, 0, _engineContextDestroy);
mScriptListInit(&context->refPool, 0); mScriptListInit(&context->refPool, 0);
TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref); TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref);
context->nextWeakref = 0; context->nextWeakref = 1;
HashTableInit(&context->callbacks, 0, (void (*)(void*)) mScriptValueDeref); HashTableInit(&context->callbacks, 0, (void (*)(void*)) mScriptValueDeref);
} }
@ -123,10 +123,7 @@ void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, st
if (oldValue) { if (oldValue) {
mScriptContextClearWeakref(context, oldValue->value.u32); mScriptContextClearWeakref(context, oldValue->value.u32);
} }
uint32_t weakref = mScriptContextSetWeakref(context, value); value = mScriptContextMakeWeakref(context, value);
mScriptValueDeref(value);
value = mScriptValueAlloc(mSCRIPT_TYPE_MS_WEAKREF);
value->value.u32 = weakref;
HashTableInsert(&context->rootScope, key, value); HashTableInsert(&context->rootScope, key, value);
struct mScriptKVPair pair = { struct mScriptKVPair pair = {
.key = key, .key = key,
@ -135,6 +132,14 @@ void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, st
HashTableEnumerate(&context->engines, _contextAddGlobal, &pair); 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) { void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key) {
if (!HashTableLookup(&context->rootScope, key)) { if (!HashTableLookup(&context->rootScope, key)) {
return; 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) { uint32_t mScriptContextSetWeakref(struct mScriptContext* context, struct mScriptValue* value) {
mScriptValueRef(value); mScriptValueRef(value);
TableInsert(&context->weakrefs, context->nextWeakref, value); TableInsert(&context->weakrefs, context->nextWeakref, value);
@ -219,7 +233,7 @@ bool mScriptContextLoadVF(struct mScriptContext* context, const char* name, stru
if (!info.context) { if (!info.context) {
return false; 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) { bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) {

View File

@ -18,7 +18,7 @@ static void _luaDestroy(struct mScriptEngineContext*);
static bool _luaIsScript(struct mScriptEngineContext*, const char*, struct VFile*); static bool _luaIsScript(struct mScriptEngineContext*, const char*, struct VFile*);
static struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext*, const char* name); static struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext*, const char* name);
static bool _luaSetGlobal(struct mScriptEngineContext*, const char* name, struct mScriptValue*); 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 bool _luaRun(struct mScriptEngineContext*);
static const char* _luaGetError(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; 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 mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx;
struct mScriptEngineLuaReader data = { struct mScriptEngineLuaReader data = {
.vf = vf .vf = vf
}; };
if (luaContext->lastError) {
free(luaContext->lastError);
luaContext->lastError = NULL;
}
int ret = lua_load(luaContext->lua, _reader, &data, NULL, "t"); int ret = lua_load(luaContext->lua, _reader, &data, NULL, "t");
switch (ret) { switch (ret) {
case LUA_OK: case LUA_OK:
if (error) {
*error = NULL;
}
luaContext->func = luaL_ref(luaContext->lua, LUA_REGISTRYINDEX); luaContext->func = luaL_ref(luaContext->lua, LUA_REGISTRYINDEX);
return true; return true;
case LUA_ERRSYNTAX: case LUA_ERRSYNTAX:
if (error) { luaContext->lastError = strdup(lua_tostring(luaContext->lua, -1));
*error = "Syntax error"; lua_pop(luaContext->lua, 1);
}
break; break;
default: default:
if (error) {
*error = "Unknown error";
}
break; break;
} }
return false; return false;

View File

@ -15,9 +15,7 @@
#define LOAD_PROGRAM(PROG) \ #define LOAD_PROGRAM(PROG) \
do { \ do { \
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \ struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
const char* error = NULL; \ assert_true(lua->load(lua, vf)); \
assert_true(lua->load(lua, vf, &error)); \
assert_null(error); \
vf->close(vf); \ vf->close(vf); \
} while(0) } while(0)
@ -116,9 +114,7 @@ M_TEST_DEFINE(loadGood) {
const char* program = "-- test\n"; const char* program = "-- test\n";
struct VFile* vf = VFileFromConstMemory(program, strlen(program)); struct VFile* vf = VFileFromConstMemory(program, strlen(program));
const char* error = NULL; assert_true(lua->load(lua, vf));
assert_true(lua->load(lua, vf, &error));
assert_null(error);
lua->destroy(lua); lua->destroy(lua);
mScriptContextDeinit(&context); mScriptContextDeinit(&context);
@ -132,9 +128,7 @@ M_TEST_DEFINE(loadBadSyntax) {
const char* program = "Invalid syntax! )\n"; const char* program = "Invalid syntax! )\n";
struct VFile* vf = VFileFromConstMemory(program, strlen(program)); struct VFile* vf = VFileFromConstMemory(program, strlen(program));
const char* error = NULL; assert_false(lua->load(lua, vf));
assert_false(lua->load(lua, vf, &error));
assert_non_null(error);
lua->destroy(lua); lua->destroy(lua);
mScriptContextDeinit(&context); mScriptContextDeinit(&context);

View File

@ -741,6 +741,17 @@ struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) {
internal->buffer = strdup(string); internal->buffer = strdup(string);
return val; 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) { bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value) {
if (table->type != mSCRIPT_TYPE_MS_TABLE) { 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) { 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) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return false; return false;
} }
@ -1003,6 +1017,7 @@ static bool _accessRawMember(struct mScriptClassMember* member, void* raw, bool
break; break;
case mSCRIPT_TYPE_TABLE: case mSCRIPT_TYPE_TABLE:
val->refs = mSCRIPT_VALUE_UNREF; val->refs = mSCRIPT_VALUE_UNREF;
val->flags = 0;
val->type = mSCRIPT_TYPE_MS_WRAPPER; val->type = mSCRIPT_TYPE_MS_WRAPPER;
val->value.opaque = raw; val->value.opaque = raw;
break; break;