diff --git a/sp/src/vscript/vscript_squirrel.cpp b/sp/src/vscript/vscript_squirrel.cpp index be83623d..a6975fc7 100644 --- a/sp/src/vscript/vscript_squirrel.cpp +++ b/sp/src/vscript/vscript_squirrel.cpp @@ -79,25 +79,35 @@ struct ReadStateMap } } - bool CheckCache(CUtlBuffer* pBuffer, HSQOBJECT** obj) + bool CheckCache(CUtlBuffer* pBuffer, HSQUIRRELVM vm, int * outmarker) { int marker = pBuffer->GetInt(); auto idx = cache.Find(marker); if (idx != cache.InvalidIndex()) { - *obj = &cache[idx]; + sq_pushobject(vm, cache[idx]); return true; } else { - HSQOBJECT temp; - sq_resetobject(&temp); - auto idx = cache.Insert(marker, temp); - *obj = &cache[idx]; + *outmarker = marker; return false; } } + + void StoreInCache(int marker, HSQOBJECT& obj) + { + cache.Insert(marker, obj); + } + + void StoreTopInCache(int marker) + { + HSQOBJECT obj; + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + cache.Insert(marker, obj); + } }; class SquirrelVM : public IScriptVM @@ -3085,10 +3095,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } case OT_TABLE: { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } @@ -3096,8 +3105,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) int count = pBuffer->GetInt(); sq_newtableex(vm_, count); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); sq_push(vm_, -2); sq_setdelegate(vm_, -2); @@ -3115,17 +3123,15 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } case OT_ARRAY: { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } int count = pBuffer->GetInt(); sq_newarray(vm_, count); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); for (int i = 0; i < count; ++i) { @@ -3137,10 +3143,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } case OT_CLOSURE: { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } @@ -3152,8 +3157,8 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) sq_pushnull(vm_); break; } - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + + readState.StoreTopInCache(marker); } else { @@ -3187,9 +3192,8 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) sq_poptop(vm_); } - *obj = ret; - sq_addref(vm_, obj); - sq_pushobject(vm_, *obj); + vm_->Push(ret); + readState.StoreTopInCache(marker); } ReadObject(pBuffer, readState); @@ -3198,10 +3202,12 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) sq_getstackobj(vm_, -1, &env); if (!sq_isnull(env)) { - if (_closure( *obj ) == nullptr) + HSQOBJECT obj; + sq_getstackobj(vm_, -2, &obj); + if (_closure(obj) == nullptr) Warning("Closure is null\n"); else - _closure(*obj)->_env = _refcounted(env)->GetWeakRef(sq_type(env)); + _closure(obj)->_env = _refcounted(env)->GetWeakRef(sq_type(env)); } sq_poptop(vm_); @@ -3226,10 +3232,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } case OT_CLASS: { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } @@ -3238,8 +3243,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) if (classType == VectorClassType) { sq_pushobject(vm_, vectorClass_); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); } else if (classType == NativeClassType) { @@ -3254,8 +3258,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) sq_pushnull(vm_); } sq_remove(vm_, -2); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); } else if (classType == ScriptClassType) { @@ -3267,8 +3270,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } sq_newclass(vm_, hasBase); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); sq_pushnull(vm_); ReadObject(pBuffer, readState); @@ -3292,10 +3294,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } case OT_INSTANCE: { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } @@ -3310,8 +3311,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) ReadObject(pBuffer, readState); sq_call(vm_, 2, SQTrue, SQFalse); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); sq_remove(vm_, -2); @@ -3340,8 +3340,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) if (sq_isinstance(singleton) && _instance(singleton)->_class == _class(klass)) { foundSingleton = true; - *obj = singleton; - sq_addref(vm_, obj); + + readState.StoreInCache(marker, singleton); + sq_addref(vm_, &singleton); sq_pop(vm_, 2); break; } @@ -3355,25 +3356,28 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) ((ScriptClassDesc_t*)typetag)->m_pszScriptName); } - sq_pushobject(vm_, *obj); + sq_pushobject(vm_, singleton); break; } + + HSQOBJECT obj; sq_createinstance(vm_, -1); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + readState.StoreInCache(marker, obj); sq_remove(vm_, -2); { // HACK: No way to get the default values part from accessing the class directly - SQUnsignedInteger nvalues = _instance(*obj)->_class->_defaultvalues.size(); + SQUnsignedInteger nvalues = _instance(obj)->_class->_defaultvalues.size(); for (SQUnsignedInteger n = 0; n < nvalues; n++) { ReadObject(pBuffer, readState); HSQOBJECT val; sq_resetobject(&val); sq_getstackobj(vm_, -1, &val); - _instance(*obj)->_values[n] = val; + _instance(obj)->_values[n] = val; sq_pop(vm_, 1); } } @@ -3436,10 +3440,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } case OT_FUNCPROTO: //internal usage only { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } @@ -3452,15 +3455,13 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } vm_->Push(ret); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); } case OT_OUTER: //internal usage only { - HSQOBJECT* obj = nullptr; - if (readState.CheckCache(pBuffer, &obj)) + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) { - sq_pushobject(vm_, *obj); break; } @@ -3473,8 +3474,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) outer->_valptr = &(outer->_value); sq_poptop(vm_); vm_->Push(outer); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + readState.StoreTopInCache(marker); break; } @@ -3496,10 +3496,12 @@ void SquirrelVM::ReadState(CUtlBuffer* pBuffer) sq_pushroottable(vm_); - HSQOBJECT* obj = nullptr; - readState.CheckCache(pBuffer, &obj); - sq_getstackobj(vm_, -1, obj); - sq_addref(vm_, obj); + HSQOBJECT obj; + int marker = 0; + readState.CheckCache(pBuffer, vm_, &marker); + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + readState.StoreInCache(marker, obj); int count = pBuffer->GetInt();