Scripting: Make memory blocks weakrefs

This commit is contained in:
Vicki Pfau 2022-05-15 15:48:28 -07:00
parent f3ba5f7692
commit 48f49b74b1
1 changed files with 51 additions and 20 deletions

View File

@ -156,6 +156,7 @@ struct mScriptMemoryAdapter {
struct mScriptCoreAdapter { struct mScriptCoreAdapter {
struct mCore* core; struct mCore* core;
struct mScriptContext* context;
struct mScriptValue memory; struct mScriptValue memory;
}; };
@ -269,7 +270,46 @@ mSCRIPT_DEFINE_DOCSTRING("Write a 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write32, busWrite32) mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write32, busWrite32)
mSCRIPT_DEFINE_END; mSCRIPT_DEFINE_END;
static void _clearMemoryMap(struct mScriptContext* context, struct mScriptCoreAdapter* adapter, bool clear) {
struct TableIterator iter;
if (mScriptTableIteratorStart(&adapter->memory, &iter)) {
while (true) {
struct mScriptValue* weakref = mScriptTableIteratorGetValue(&adapter->memory, &iter);
if (weakref) {
if (clear) {
mScriptContextClearWeakref(context, weakref->value.s32);
}
mScriptValueDeref(weakref);
}
if (!mScriptTableIteratorNext(&adapter->memory, &iter)) {
break;
}
}
}
mScriptTableClear(&adapter->memory);
}
static void _rebuildMemoryMap(struct mScriptContext* context, struct mScriptCoreAdapter* adapter) {
_clearMemoryMap(context, adapter, true);
const struct mCoreMemoryBlock* blocks;
size_t nBlocks = adapter->core->listMemoryBlocks(adapter->core, &blocks);
size_t i;
for (i = 0; i < nBlocks; ++i) {
struct mScriptMemoryAdapter* memadapter = calloc(1, sizeof(*memadapter));
memadapter->core = adapter->core;
memcpy(&memadapter->block, &blocks[i], sizeof(memadapter->block));
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptMemoryAdapter));
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
value->value.opaque = memadapter;
struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName);
mScriptTableInsert(&adapter->memory, key, mScriptContextMakeWeakref(context, value));
mScriptValueDeref(key);
}
}
static void _mScriptCoreAdapterDeinit(struct mScriptCoreAdapter* adapter) { static void _mScriptCoreAdapterDeinit(struct mScriptCoreAdapter* adapter) {
_clearMemoryMap(adapter->context, adapter, false);
adapter->memory.type->free(&adapter->memory); adapter->memory.type->free(&adapter->memory);
} }
@ -299,36 +339,18 @@ mSCRIPT_DEFINE_STRUCT_CAST_TO_MEMBER(mScriptCoreAdapter, S(mCore), _core)
mSCRIPT_DEFINE_STRUCT_CAST_TO_MEMBER(mScriptCoreAdapter, CS(mCore), _core) mSCRIPT_DEFINE_STRUCT_CAST_TO_MEMBER(mScriptCoreAdapter, CS(mCore), _core)
mSCRIPT_DEFINE_END; mSCRIPT_DEFINE_END;
static void _rebuildMemoryMap(struct mScriptCoreAdapter* adapter) {
mScriptTableClear(&adapter->memory);
const struct mCoreMemoryBlock* blocks;
size_t nBlocks = adapter->core->listMemoryBlocks(adapter->core, &blocks);
size_t i;
for (i = 0; i < nBlocks; ++i) {
struct mScriptMemoryAdapter* memadapter = calloc(1, sizeof(*memadapter));
memadapter->core = adapter->core;
memcpy(&memadapter->block, &blocks[i], sizeof(memadapter->block));
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptMemoryAdapter));
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
value->value.opaque = memadapter;
struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName);
mScriptTableInsert(&adapter->memory, key, value);
mScriptValueDeref(key);
}
}
void mScriptContextAttachCore(struct mScriptContext* context, struct mCore* core) { void mScriptContextAttachCore(struct mScriptContext* context, struct mCore* core) {
struct mScriptValue* coreValue = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptCoreAdapter)); struct mScriptValue* coreValue = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptCoreAdapter));
struct mScriptCoreAdapter* adapter = calloc(1, sizeof(*adapter)); struct mScriptCoreAdapter* adapter = calloc(1, sizeof(*adapter));
adapter->core = core; adapter->core = core;
adapter->context = context;
adapter->memory.refs = mSCRIPT_VALUE_UNREF; adapter->memory.refs = mSCRIPT_VALUE_UNREF;
adapter->memory.flags = 0; adapter->memory.flags = 0;
adapter->memory.type = mSCRIPT_TYPE_MS_TABLE; adapter->memory.type = mSCRIPT_TYPE_MS_TABLE;
adapter->memory.type->alloc(&adapter->memory); adapter->memory.type->alloc(&adapter->memory);
_rebuildMemoryMap(adapter); _rebuildMemoryMap(context, adapter);
coreValue->value.opaque = adapter; coreValue->value.opaque = adapter;
coreValue->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER; coreValue->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
@ -336,6 +358,15 @@ void mScriptContextAttachCore(struct mScriptContext* context, struct mCore* core
} }
void mScriptContextDetachCore(struct mScriptContext* context) { void mScriptContextDetachCore(struct mScriptContext* context) {
struct mScriptValue* value = HashTableLookup(&context->rootScope, "emu");
if (!value) {
return;
}
value = mScriptContextAccessWeakref(context, value);
if (!value) {
return;
}
_clearMemoryMap(context, value->value.opaque, true);
mScriptContextRemoveGlobal(context, "emu"); mScriptContextRemoveGlobal(context, "emu");
} }