mirror of https://github.com/mgba-emu/mgba.git
Scripting: Hook up Lua strings and add context autodrain pool
This commit is contained in:
parent
af44a65c3d
commit
e3758597f8
|
@ -21,6 +21,7 @@ struct mScriptEngineContext;
|
|||
struct mScriptContext {
|
||||
struct Table rootScope;
|
||||
struct Table engines;
|
||||
struct mScriptList refPool;
|
||||
struct Table weakrefs;
|
||||
uint32_t nextWeakref;
|
||||
};
|
||||
|
@ -51,6 +52,9 @@ struct mScriptEngineContext {
|
|||
void mScriptContextInit(struct mScriptContext*);
|
||||
void mScriptContextDeinit(struct mScriptContext*);
|
||||
|
||||
void mScriptContextFillPool(struct mScriptContext*, struct mScriptValue*);
|
||||
void mScriptContextDrainPool(struct mScriptContext*);
|
||||
|
||||
struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*, struct mScriptEngine2*);
|
||||
void mScriptContextRegisterEngines(struct mScriptContext*);
|
||||
|
||||
|
|
|
@ -101,9 +101,11 @@ CXX_GUARD_START
|
|||
mSCRIPT_TYPE_C_ ## TYPE NAME; \
|
||||
do { \
|
||||
struct mScriptValue* _val = mScriptListGetPointer(STACK, mScriptListSize(STACK) - 1); \
|
||||
bool deref = true; \
|
||||
if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \
|
||||
if (_val->type == mSCRIPT_TYPE_MS_WRAPPER) { \
|
||||
_val = mScriptValueUnwrap(_val); \
|
||||
deref = false; \
|
||||
if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \
|
||||
return false; \
|
||||
} \
|
||||
|
@ -112,7 +114,9 @@ CXX_GUARD_START
|
|||
} \
|
||||
} \
|
||||
NAME = _val->value.mSCRIPT_TYPE_FIELD_ ## TYPE; \
|
||||
mScriptValueDeref(_val); \
|
||||
if (deref) { \
|
||||
mScriptValueDeref(_val); \
|
||||
} \
|
||||
mScriptListResize(STACK, -1); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ static void _contextFindForFile(const char* key, void* value, void* user) {
|
|||
void mScriptContextInit(struct mScriptContext* context) {
|
||||
HashTableInit(&context->rootScope, 0, (void (*)(void*)) mScriptValueDeref);
|
||||
HashTableInit(&context->engines, 0, _engineContextDestroy);
|
||||
mScriptListInit(&context->refPool, 0);
|
||||
TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref);
|
||||
context->nextWeakref = 0;
|
||||
}
|
||||
|
@ -60,6 +61,38 @@ void mScriptContextDeinit(struct mScriptContext* context) {
|
|||
HashTableDeinit(&context->engines);
|
||||
HashTableDeinit(&context->rootScope);
|
||||
HashTableDeinit(&context->weakrefs);
|
||||
mScriptContextDrainPool(context);
|
||||
mScriptListDeinit(&context->refPool);
|
||||
}
|
||||
|
||||
void mScriptContextFillPool(struct mScriptContext* context, struct mScriptValue* value) {
|
||||
if (value->refs == mSCRIPT_VALUE_UNREF) {
|
||||
return;
|
||||
}
|
||||
switch (value->type->base) {
|
||||
case mSCRIPT_TYPE_SINT:
|
||||
case mSCRIPT_TYPE_UINT:
|
||||
case mSCRIPT_TYPE_FLOAT:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
struct mScriptValue* poolEntry = mScriptListAppend(&context->refPool);
|
||||
poolEntry->type = mSCRIPT_TYPE_MS_WRAPPER;
|
||||
poolEntry->value.opaque = value;
|
||||
poolEntry->refs = mSCRIPT_VALUE_UNREF;
|
||||
}
|
||||
|
||||
void mScriptContextDrainPool(struct mScriptContext* context) {
|
||||
size_t i;
|
||||
for (i = 0; i < mScriptListSize(&context->refPool); ++i) {
|
||||
struct mScriptValue* value = mScriptValueUnwrap(mScriptListGetPointer(&context->refPool, i));
|
||||
if (value) {
|
||||
mScriptValueDeref(value);
|
||||
}
|
||||
}
|
||||
mScriptListClear(&context->refPool);
|
||||
}
|
||||
|
||||
struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext* context, struct mScriptEngine2* engine) {
|
||||
|
|
|
@ -198,6 +198,9 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext) {
|
|||
value->value.s32 = lua_toboolean(luaContext->lua, -1);
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
value = mScriptStringCreateFromUTF8(lua_tostring(luaContext->lua, -1));
|
||||
mScriptValueWrap(value, mScriptListAppend(&luaContext->d.context->refPool));
|
||||
mScriptValueDeref(value);
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
return _luaCoerceFunction(luaContext);
|
||||
|
@ -259,6 +262,9 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v
|
|||
ok = false;
|
||||
}
|
||||
break;
|
||||
case mSCRIPT_TYPE_STRING:
|
||||
lua_pushstring(luaContext->lua, ((struct mScriptString*) value->value.opaque)->buffer);
|
||||
break;
|
||||
case mSCRIPT_TYPE_FUNCTION:
|
||||
newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue));
|
||||
newValue->type = value->type;
|
||||
|
@ -426,8 +432,10 @@ bool _luaInvoke(struct mScriptEngineContextLua* luaContext, struct mScriptFrame*
|
|||
}
|
||||
|
||||
if (frame && !_luaPopFrame(luaContext, &frame->returnValues)) {
|
||||
mScriptContextDrainPool(luaContext->d.context);
|
||||
return false;
|
||||
}
|
||||
mScriptContextDrainPool(luaContext->d.context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -468,6 +476,7 @@ int _luaThunk(lua_State* lua) {
|
|||
struct mScriptFrame frame;
|
||||
mScriptFrameInit(&frame);
|
||||
if (!_luaPopFrame(luaContext, &frame.arguments)) {
|
||||
mScriptContextDrainPool(luaContext->d.context);
|
||||
mScriptFrameDeinit(&frame);
|
||||
lua_pushliteral(lua, "Error calling function (setting arguments)");
|
||||
lua_error(lua);
|
||||
|
@ -479,6 +488,7 @@ int _luaThunk(lua_State* lua) {
|
|||
lua_pushliteral(lua, "Error calling function (invoking)");
|
||||
lua_error(lua);
|
||||
}
|
||||
mScriptContextDrainPool(luaContext->d.context);
|
||||
|
||||
if (!_luaPushFrame(luaContext, &frame.returnValues)) {
|
||||
mScriptFrameDeinit(&frame);
|
||||
|
@ -542,6 +552,7 @@ int _luaSetObject(lua_State* lua) {
|
|||
lua_error(lua);
|
||||
}
|
||||
mScriptValueDeref(val);
|
||||
mScriptContextDrainPool(luaContext->d.context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1071,6 +1071,13 @@ bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList
|
|||
if (types->entries[i] == mScriptListGetPointer(frame, i)->type) {
|
||||
continue;
|
||||
}
|
||||
struct mScriptValue* unwrapped = NULL;
|
||||
if (mScriptListGetPointer(frame, i)->type == mSCRIPT_TYPE_MS_WRAPPER) {
|
||||
unwrapped = mScriptValueUnwrap(mScriptListGetPointer(frame, i));
|
||||
if (types->entries[i] == unwrapped->type) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!mScriptCast(types->entries[i], mScriptListGetPointer(frame, i), mScriptListGetPointer(frame, i))) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue