Scripting: Hook up Lua strings and add context autodrain pool

This commit is contained in:
Vicki Pfau 2022-05-09 00:41:18 -07:00
parent af44a65c3d
commit e3758597f8
5 changed files with 60 additions and 1 deletions

View File

@ -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*);

View File

@ -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)

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}