Fixing issue with vscript restore having issues with cached weak references

This commit is contained in:
James Mitchell 2020-05-31 12:06:43 +10:00
parent 4966b79f84
commit 30032b70c9

View File

@ -52,9 +52,19 @@ struct WriteStateMap
struct ReadStateMap struct ReadStateMap
{ {
CUtlMap<int, HSQOBJECT> cache; CUtlMap<int, HSQOBJECT> cache;
ReadStateMap() : cache(DefLessFunc(int)) HSQUIRRELVM vm_;
ReadStateMap(HSQUIRRELVM vm) : cache(DefLessFunc(int)), vm_(vm)
{} {}
~ReadStateMap()
{
FOR_EACH_MAP_FAST(cache, i)
{
HSQOBJECT& obj = cache[i];
sq_release(vm_, &obj);
}
}
bool CheckCache(CUtlBuffer* pBuffer, HSQOBJECT** obj) bool CheckCache(CUtlBuffer* pBuffer, HSQOBJECT** obj)
{ {
int marker = pBuffer->GetInt(); int marker = pBuffer->GetInt();
@ -2415,6 +2425,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
int count = pBuffer->GetInt(); int count = pBuffer->GetInt();
sq_newtableex(vm_, count); sq_newtableex(vm_, count);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
sq_push(vm_, -2); sq_push(vm_, -2);
sq_setdelegate(vm_, -2); sq_setdelegate(vm_, -2);
@ -2442,6 +2453,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
int count = pBuffer->GetInt(); int count = pBuffer->GetInt();
sq_newarray(vm_, count); sq_newarray(vm_, count);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
@ -2469,6 +2481,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
break; break;
} }
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
} }
else else
{ {
@ -2492,6 +2505,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
*obj = ret; *obj = ret;
sq_addref(vm_, obj);
sq_pushobject(vm_, *obj); sq_pushobject(vm_, *obj);
} }
@ -2553,6 +2567,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
sq_remove(vm_, -2); sq_remove(vm_, -2);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
} }
else if (classType == ScriptClassType) else if (classType == ScriptClassType)
{ {
@ -2565,6 +2580,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_newclass(vm_, hasBase); sq_newclass(vm_, hasBase);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
sq_pushnull(vm_); sq_pushnull(vm_);
ReadObject(pBuffer, readState); ReadObject(pBuffer, readState);
@ -2623,6 +2639,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
{ {
foundSingleton = true; foundSingleton = true;
*obj = singleton; *obj = singleton;
sq_addref(vm_, obj);
sq_pop(vm_, 2); sq_pop(vm_, 2);
break; break;
} }
@ -2642,6 +2659,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_createinstance(vm_, -1); sq_createinstance(vm_, -1);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
sq_remove(vm_, -2); sq_remove(vm_, -2);
@ -2731,6 +2749,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
vm_->Push(ret); vm_->Push(ret);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
} }
case OT_OUTER: //internal usage only case OT_OUTER: //internal usage only
{ {
@ -2751,6 +2770,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_poptop(vm_); sq_poptop(vm_);
vm_->Push(outer); vm_->Push(outer);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
break; break;
} }
@ -2768,13 +2788,14 @@ void SquirrelVM::ReadState(CUtlBuffer* pBuffer)
{ {
SquirrelSafeCheck safeCheck(vm_); SquirrelSafeCheck safeCheck(vm_);
ReadStateMap readState; ReadStateMap readState(vm_);
sq_pushroottable(vm_); sq_pushroottable(vm_);
HSQOBJECT* obj = nullptr; HSQOBJECT* obj = nullptr;
readState.CheckCache(pBuffer, &obj); readState.CheckCache(pBuffer, &obj);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
int count = pBuffer->GetInt(); int count = pBuffer->GetInt();