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 mScriptContext {
|
||||||
struct Table rootScope;
|
struct Table rootScope;
|
||||||
struct Table engines;
|
struct Table engines;
|
||||||
|
struct mScriptList refPool;
|
||||||
struct Table weakrefs;
|
struct Table weakrefs;
|
||||||
uint32_t nextWeakref;
|
uint32_t nextWeakref;
|
||||||
};
|
};
|
||||||
|
@ -51,6 +52,9 @@ struct mScriptEngineContext {
|
||||||
void mScriptContextInit(struct mScriptContext*);
|
void mScriptContextInit(struct mScriptContext*);
|
||||||
void mScriptContextDeinit(struct mScriptContext*);
|
void mScriptContextDeinit(struct mScriptContext*);
|
||||||
|
|
||||||
|
void mScriptContextFillPool(struct mScriptContext*, struct mScriptValue*);
|
||||||
|
void mScriptContextDrainPool(struct mScriptContext*);
|
||||||
|
|
||||||
struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*, struct mScriptEngine2*);
|
struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*, struct mScriptEngine2*);
|
||||||
void mScriptContextRegisterEngines(struct mScriptContext*);
|
void mScriptContextRegisterEngines(struct mScriptContext*);
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,11 @@ CXX_GUARD_START
|
||||||
mSCRIPT_TYPE_C_ ## TYPE NAME; \
|
mSCRIPT_TYPE_C_ ## TYPE NAME; \
|
||||||
do { \
|
do { \
|
||||||
struct mScriptValue* _val = mScriptListGetPointer(STACK, mScriptListSize(STACK) - 1); \
|
struct mScriptValue* _val = mScriptListGetPointer(STACK, mScriptListSize(STACK) - 1); \
|
||||||
|
bool deref = true; \
|
||||||
if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \
|
if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \
|
||||||
if (_val->type == mSCRIPT_TYPE_MS_WRAPPER) { \
|
if (_val->type == mSCRIPT_TYPE_MS_WRAPPER) { \
|
||||||
_val = mScriptValueUnwrap(_val); \
|
_val = mScriptValueUnwrap(_val); \
|
||||||
|
deref = false; \
|
||||||
if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \
|
if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
|
@ -112,7 +114,9 @@ CXX_GUARD_START
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
NAME = _val->value.mSCRIPT_TYPE_FIELD_ ## TYPE; \
|
NAME = _val->value.mSCRIPT_TYPE_FIELD_ ## TYPE; \
|
||||||
|
if (deref) { \
|
||||||
mScriptValueDeref(_val); \
|
mScriptValueDeref(_val); \
|
||||||
|
} \
|
||||||
mScriptListResize(STACK, -1); \
|
mScriptListResize(STACK, -1); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ static void _contextFindForFile(const char* key, void* value, void* user) {
|
||||||
void mScriptContextInit(struct mScriptContext* context) {
|
void mScriptContextInit(struct mScriptContext* context) {
|
||||||
HashTableInit(&context->rootScope, 0, (void (*)(void*)) mScriptValueDeref);
|
HashTableInit(&context->rootScope, 0, (void (*)(void*)) mScriptValueDeref);
|
||||||
HashTableInit(&context->engines, 0, _engineContextDestroy);
|
HashTableInit(&context->engines, 0, _engineContextDestroy);
|
||||||
|
mScriptListInit(&context->refPool, 0);
|
||||||
TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref);
|
TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref);
|
||||||
context->nextWeakref = 0;
|
context->nextWeakref = 0;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +61,38 @@ void mScriptContextDeinit(struct mScriptContext* context) {
|
||||||
HashTableDeinit(&context->engines);
|
HashTableDeinit(&context->engines);
|
||||||
HashTableDeinit(&context->rootScope);
|
HashTableDeinit(&context->rootScope);
|
||||||
HashTableDeinit(&context->weakrefs);
|
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) {
|
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);
|
value->value.s32 = lua_toboolean(luaContext->lua, -1);
|
||||||
break;
|
break;
|
||||||
case LUA_TSTRING:
|
case LUA_TSTRING:
|
||||||
|
value = mScriptStringCreateFromUTF8(lua_tostring(luaContext->lua, -1));
|
||||||
|
mScriptValueWrap(value, mScriptListAppend(&luaContext->d.context->refPool));
|
||||||
|
mScriptValueDeref(value);
|
||||||
break;
|
break;
|
||||||
case LUA_TFUNCTION:
|
case LUA_TFUNCTION:
|
||||||
return _luaCoerceFunction(luaContext);
|
return _luaCoerceFunction(luaContext);
|
||||||
|
@ -259,6 +262,9 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case mSCRIPT_TYPE_STRING:
|
||||||
|
lua_pushstring(luaContext->lua, ((struct mScriptString*) value->value.opaque)->buffer);
|
||||||
|
break;
|
||||||
case mSCRIPT_TYPE_FUNCTION:
|
case mSCRIPT_TYPE_FUNCTION:
|
||||||
newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue));
|
newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue));
|
||||||
newValue->type = value->type;
|
newValue->type = value->type;
|
||||||
|
@ -426,8 +432,10 @@ bool _luaInvoke(struct mScriptEngineContextLua* luaContext, struct mScriptFrame*
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame && !_luaPopFrame(luaContext, &frame->returnValues)) {
|
if (frame && !_luaPopFrame(luaContext, &frame->returnValues)) {
|
||||||
|
mScriptContextDrainPool(luaContext->d.context);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
mScriptContextDrainPool(luaContext->d.context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -468,6 +476,7 @@ int _luaThunk(lua_State* lua) {
|
||||||
struct mScriptFrame frame;
|
struct mScriptFrame frame;
|
||||||
mScriptFrameInit(&frame);
|
mScriptFrameInit(&frame);
|
||||||
if (!_luaPopFrame(luaContext, &frame.arguments)) {
|
if (!_luaPopFrame(luaContext, &frame.arguments)) {
|
||||||
|
mScriptContextDrainPool(luaContext->d.context);
|
||||||
mScriptFrameDeinit(&frame);
|
mScriptFrameDeinit(&frame);
|
||||||
lua_pushliteral(lua, "Error calling function (setting arguments)");
|
lua_pushliteral(lua, "Error calling function (setting arguments)");
|
||||||
lua_error(lua);
|
lua_error(lua);
|
||||||
|
@ -479,6 +488,7 @@ int _luaThunk(lua_State* lua) {
|
||||||
lua_pushliteral(lua, "Error calling function (invoking)");
|
lua_pushliteral(lua, "Error calling function (invoking)");
|
||||||
lua_error(lua);
|
lua_error(lua);
|
||||||
}
|
}
|
||||||
|
mScriptContextDrainPool(luaContext->d.context);
|
||||||
|
|
||||||
if (!_luaPushFrame(luaContext, &frame.returnValues)) {
|
if (!_luaPushFrame(luaContext, &frame.returnValues)) {
|
||||||
mScriptFrameDeinit(&frame);
|
mScriptFrameDeinit(&frame);
|
||||||
|
@ -542,6 +552,7 @@ int _luaSetObject(lua_State* lua) {
|
||||||
lua_error(lua);
|
lua_error(lua);
|
||||||
}
|
}
|
||||||
mScriptValueDeref(val);
|
mScriptValueDeref(val);
|
||||||
|
mScriptContextDrainPool(luaContext->d.context);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1071,6 +1071,13 @@ bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList
|
||||||
if (types->entries[i] == mScriptListGetPointer(frame, i)->type) {
|
if (types->entries[i] == mScriptListGetPointer(frame, i)->type) {
|
||||||
continue;
|
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))) {
|
if (!mScriptCast(types->entries[i], mScriptListGetPointer(frame, i), mScriptListGetPointer(frame, i))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue