diff --git a/src/3rdparty/squirrel/squirrel/sqapi.cpp b/src/3rdparty/squirrel/squirrel/sqapi.cpp index 80c5d816e8..56f3ef7b47 100644 --- a/src/3rdparty/squirrel/squirrel/sqapi.cpp +++ b/src/3rdparty/squirrel/squirrel/sqapi.cpp @@ -57,13 +57,12 @@ HSQUIRRELVM sq_open(SQInteger initialstacksize) SQSharedState *ss; SQVM *v; sq_new(ss, SQSharedState); - v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); - new (v) SQVM(ss); + v = new (SQAllocationTag{}) SQVM(ss); ss->_root_vm = v; if(v->Init(nullptr, initialstacksize)) { return v; } else { - sq_delete(v, SQVM); + sq_delete_refcounted(v, SQVM); return nullptr; } return v; @@ -75,14 +74,13 @@ HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) SQVM *v; ss=_ss(friendvm); - v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); - new (v) SQVM(ss); + v = new (SQAllocationTag{}) SQVM(ss); if(v->Init(friendvm, initialstacksize)) { friendvm->Push(v); return v; } else { - sq_delete(v, SQVM); + sq_delete_refcounted(v, SQVM); return nullptr; } } diff --git a/src/3rdparty/squirrel/squirrel/sqarray.h b/src/3rdparty/squirrel/squirrel/sqarray.h index 13ae11619c..6ccd9ab0f9 100644 --- a/src/3rdparty/squirrel/squirrel/sqarray.h +++ b/src/3rdparty/squirrel/squirrel/sqarray.h @@ -12,8 +12,7 @@ private: } public: static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ - SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); - new (newarray) SQArray(ss,nInitialSize); + SQArray *newarray = new (SQAllocationTag{}) SQArray(ss,nInitialSize); return newarray; } #ifndef NO_GARBAGE_COLLECTOR @@ -84,7 +83,7 @@ public: } void FinalFree() override { - sq_delete(this, SQArray); + sq_delete_refcounted(this, SQArray); } SQObjectPtrVec _values; }; diff --git a/src/3rdparty/squirrel/squirrel/sqclass.cpp b/src/3rdparty/squirrel/squirrel/sqclass.cpp index 643685c9e6..9f134a9101 100644 --- a/src/3rdparty/squirrel/squirrel/sqclass.cpp +++ b/src/3rdparty/squirrel/squirrel/sqclass.cpp @@ -147,9 +147,8 @@ void SQInstance::Init(SQSharedState *ss) ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); } -SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) +SQInstance::SQInstance(SQSharedState *ss, SQClass *c) { - _memsize = memsize; _class = c; SQUnsignedInteger nvalues = _class->_defaultvalues.size(); for(SQUnsignedInteger n = 0; n < nvalues; n++) { @@ -158,9 +157,8 @@ SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) Init(ss); } -SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) +SQInstance::SQInstance(SQSharedState *ss, SQInstance *i) { - _memsize = memsize; _class = i->_class; SQUnsignedInteger nvalues = _class->_defaultvalues.size(); for(SQUnsignedInteger n = 0; n < nvalues; n++) { diff --git a/src/3rdparty/squirrel/squirrel/sqclass.h b/src/3rdparty/squirrel/squirrel/sqclass.h index 4fb6ecbd97..7a16fa9439 100644 --- a/src/3rdparty/squirrel/squirrel/sqclass.h +++ b/src/3rdparty/squirrel/squirrel/sqclass.h @@ -31,8 +31,7 @@ struct SQClass : public CHAINABLE_OBJ SQClass(SQSharedState *ss,SQClass *base); public: static SQClass* Create(SQSharedState *ss,SQClass *base) { - SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); - new (newclass) SQClass(ss, base); + SQClass *newclass = new (SQAllocationTag{}) SQClass(ss, base); return newclass; } ~SQClass(); @@ -55,7 +54,7 @@ public: void Lock() { _locked = true; if(_base) _base->Lock(); } void Release() { if (_hook) { _hook(_typetag,0);} - sq_delete(this, SQClass); + sq_delete_refcounted(this, SQClass); } void Finalize(); #ifndef NO_GARBAGE_COLLECTOR @@ -81,14 +80,13 @@ public: struct SQInstance : public SQDelegable { void Init(SQSharedState *ss); - SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); - SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); + SQInstance(SQSharedState *ss, SQClass *c); + SQInstance(SQSharedState *ss, SQInstance *c); public: static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { SQInteger size = calcinstancesize(theclass); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new (newinst) SQInstance(ss, theclass,size); + SQInstance *newinst = new (SQSizedAllocationTag(size)) SQInstance(ss, theclass); if(theclass->_udsize) { newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); } @@ -97,8 +95,7 @@ public: SQInstance *Clone(SQSharedState *ss) { SQInteger size = calcinstancesize(_class); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new (newinst) SQInstance(ss, this,size); + SQInstance *newinst = new (SQSizedAllocationTag(size)) SQInstance(ss, this); if(_class->_udsize) { newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); } @@ -143,9 +140,7 @@ public: } void FinalFree() override { - SQInteger size = _memsize; - this->~SQInstance(); - SQ_FREE(this, size); + sq_delete_refcounted(this, SQInstance); } void Finalize() override; #ifndef NO_GARBAGE_COLLECTOR @@ -157,7 +152,6 @@ public: SQClass *_class; SQUserPointer _userpointer; SQRELEASEHOOK _hook; - SQInteger _memsize; SQObjectPtr _values[1]; }; diff --git a/src/3rdparty/squirrel/squirrel/sqclosure.h b/src/3rdparty/squirrel/squirrel/sqclosure.h index 49a84b7924..5e07f88f57 100644 --- a/src/3rdparty/squirrel/squirrel/sqclosure.h +++ b/src/3rdparty/squirrel/squirrel/sqclosure.h @@ -10,12 +10,11 @@ private: SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} public: static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){ - SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure)); - new (nc) SQClosure(ss,func); + SQClosure *nc = new (SQAllocationTag{}) SQClosure(ss,func); return nc; } void Release(){ - sq_delete(this,SQClosure); + sq_delete_refcounted(this,SQClosure); } SQClosure *Clone() { @@ -48,8 +47,7 @@ private: SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=nullptr;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} public: static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ - SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); - new (nc) SQGenerator(ss,closure); + SQGenerator *nc = new (SQAllocationTag{}) SQGenerator(ss,closure); return nc; } ~SQGenerator() @@ -61,7 +59,7 @@ public: _stack.resize(0); _closure=_null_;} void Release(){ - sq_delete(this,SQGenerator); + sq_delete_refcounted(this,SQGenerator); } bool Yield(SQVM *v); bool Resume(SQVM *v,SQInteger target); @@ -84,8 +82,7 @@ private: public: static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func) { - SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure)); - new (nc) SQNativeClosure(ss,func); + SQNativeClosure *nc = new (SQAllocationTag{}) SQNativeClosure(ss,func); return nc; } SQNativeClosure *Clone() @@ -103,7 +100,7 @@ public: REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } void Release(){ - sq_delete(this,SQNativeClosure); + sq_delete_refcounted(this,SQNativeClosure); } #ifndef NO_GARBAGE_COLLECTOR void EnqueueMarkObjectForChildren(SQGCMarkerQueue &queue); diff --git a/src/3rdparty/squirrel/squirrel/sqfuncproto.h b/src/3rdparty/squirrel/squirrel/sqfuncproto.h index 2966d06544..f03990a313 100644 --- a/src/3rdparty/squirrel/squirrel/sqfuncproto.h +++ b/src/3rdparty/squirrel/squirrel/sqfuncproto.h @@ -97,10 +97,9 @@ public: SQInteger nfunctions,SQInteger noutervalues, SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) { - SQFunctionProto *f; //I compact the whole class and members in a single memory allocation - f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); - new (f) SQFunctionProto(ninstructions, nliterals, nparameters, nfunctions, noutervalues, nlineinfos, nlocalvarinfos, ndefaultparams); + size_t size = _FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); + SQFunctionProto *f = new (SQSizedAllocationTag(size)) SQFunctionProto(ninstructions, nliterals, nparameters, nfunctions, noutervalues, nlineinfos, nlocalvarinfos, ndefaultparams); return f; } void Release(){ @@ -110,9 +109,8 @@ public: _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); - SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); this->~SQFunctionProto(); - sq_vm_free(this,size); + SQFunctionProto::SQDeallocate(this); } const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); SQInteger GetLine(SQInstruction *curr); diff --git a/src/3rdparty/squirrel/squirrel/sqobject.cpp b/src/3rdparty/squirrel/squirrel/sqobject.cpp index 298efe610c..1af27a4660 100644 --- a/src/3rdparty/squirrel/squirrel/sqobject.cpp +++ b/src/3rdparty/squirrel/squirrel/sqobject.cpp @@ -90,7 +90,7 @@ SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) { if(!_weakref) { - sq_new(_weakref,SQWeakRef); + _weakref = new (SQAllocationTag{}) SQWeakRef(); _weakref->_obj._type = type; _weakref->_obj._unVal.pRefCounted = this; } @@ -109,7 +109,7 @@ void SQWeakRef::Release() { if(ISREFCOUNTED(_obj._type)) { _obj._unVal.pRefCounted->_weakref = nullptr; } - sq_delete(this,SQWeakRef); + sq_delete_refcounted(this,SQWeakRef); } bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { diff --git a/src/3rdparty/squirrel/squirrel/sqobject.h b/src/3rdparty/squirrel/squirrel/sqobject.h index 77d09301c6..2787345c51 100644 --- a/src/3rdparty/squirrel/squirrel/sqobject.h +++ b/src/3rdparty/squirrel/squirrel/sqobject.h @@ -54,6 +54,14 @@ enum SQMetaMethod{ #define MINPOWER2 4 +struct SQAllocationTag{}; + +struct SQSizedAllocationTag { + size_t alloc_size; + + SQSizedAllocationTag(size_t alloc_size) : alloc_size(alloc_size) {} +}; + struct SQRefCounted { SQRefCounted() { _uiRef = 0; _weakref = nullptr; } @@ -63,23 +71,44 @@ struct SQRefCounted struct SQWeakRef *_weakref; virtual void Release()=0; + inline void *operator new(size_t size, SQRefCounted *place) = delete; + inline void operator delete(void *ptr, SQRefCounted *place) = delete; + /* Placement new/delete to prevent memory leaks if constructor throws an exception. */ - inline void *operator new(size_t size, SQRefCounted *place) + inline void *operator new(size_t size, SQAllocationTag tag) { - place->size = size; - return place; + size += sizeof(size_t); + size_t *ptr = (size_t *)SQ_MALLOC(size); + *ptr = size; + return ptr + 1; } - inline void operator delete(void *ptr, SQRefCounted *place) + inline static void SQDeallocate(void *ptr) { - SQ_FREE(ptr, place->size); + size_t *base = static_cast(ptr) - 1; + SQ_FREE(base, *base); + } + + inline void operator delete(void *ptr, SQAllocationTag tag) + { + SQDeallocate(ptr); + } + + inline void *operator new(size_t size, SQSizedAllocationTag sized_tag) + { + size_t alloc_size = sized_tag.alloc_size + sizeof(size_t); + size_t *ptr = (size_t *)SQ_MALLOC(alloc_size); + *ptr = alloc_size; + return ptr + 1; + } + + inline void operator delete(void *ptr, SQSizedAllocationTag sized_tag) + { + SQDeallocate(ptr); } /* Never used but required. */ inline void operator delete(void *ptr) { NOT_REACHED(); } - -private: - size_t size; }; struct SQWeakRef : SQRefCounted diff --git a/src/3rdparty/squirrel/squirrel/sqstate.cpp b/src/3rdparty/squirrel/squirrel/sqstate.cpp index c0c6b70c5c..7ccef9d849 100644 --- a/src/3rdparty/squirrel/squirrel/sqstate.cpp +++ b/src/3rdparty/squirrel/squirrel/sqstate.cpp @@ -564,8 +564,7 @@ SQString *SQStringTable::Add(const SQChar *news,SQInteger len) return s; //found } - SQString *t=(SQString *)SQ_MALLOC(len+sizeof(SQString)); - new (t) SQString(news, len); + SQString *t = new (SQSizedAllocationTag(len + sizeof(SQString))) SQString(news, len); t->_next = _strings[h]; _strings[h] = t; _slotused++; @@ -615,9 +614,7 @@ void SQStringTable::Remove(SQString *bs) else _strings[h] = s->_next; _slotused--; - SQInteger slen = s->_len; - s->~SQString(); - SQ_FREE(s,sizeof(SQString) + slen); + sq_delete_refcounted(s, SQString); return; } prev = s; diff --git a/src/3rdparty/squirrel/squirrel/sqtable.h b/src/3rdparty/squirrel/squirrel/sqtable.h index 6bdda15773..513be1878b 100644 --- a/src/3rdparty/squirrel/squirrel/sqtable.h +++ b/src/3rdparty/squirrel/squirrel/sqtable.h @@ -45,8 +45,7 @@ private: public: static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) { - SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); - new (newtable) SQTable(ss, nInitialSize); + SQTable *newtable = new (SQAllocationTag{}) SQTable(ss, nInitialSize); newtable->_delegate = nullptr; return newtable; } @@ -87,7 +86,7 @@ public: } void FinalFree() override { - sq_delete(this, SQTable); + sq_delete_refcounted(this, SQTable); } }; diff --git a/src/3rdparty/squirrel/squirrel/squserdata.h b/src/3rdparty/squirrel/squirrel/squserdata.h index aed3e83498..7f78926f94 100644 --- a/src/3rdparty/squirrel/squirrel/squserdata.h +++ b/src/3rdparty/squirrel/squirrel/squserdata.h @@ -13,8 +13,7 @@ struct SQUserData : SQDelegable } static SQUserData* Create(SQSharedState *ss, SQInteger size) { - SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1)); - new (ud) SQUserData(ss, size); + SQUserData *ud = new (SQSizedAllocationTag(sizeof(SQUserData)+(size-1))) SQUserData(ss, size); return ud; } #ifndef NO_GARBAGE_COLLECTOR @@ -23,9 +22,7 @@ struct SQUserData : SQDelegable #endif void Release() { if (_hook) _hook(_val,_size); - SQInteger tsize = _size - 1; - this->~SQUserData(); - SQ_FREE(this, sizeof(SQUserData) + tsize); + sq_delete_refcounted(this, SQUserData); } SQInteger _size; diff --git a/src/3rdparty/squirrel/squirrel/squtils.h b/src/3rdparty/squirrel/squirrel/squtils.h index d7d260dba4..b6a52375e5 100644 --- a/src/3rdparty/squirrel/squirrel/squtils.h +++ b/src/3rdparty/squirrel/squirrel/squtils.h @@ -2,14 +2,17 @@ #ifndef _SQUTILS_H_ #define _SQUTILS_H_ +#include + void *sq_vm_malloc(SQUnsignedInteger size); void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); void sq_vm_free(void *p,SQUnsignedInteger size); #define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} -#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} +#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));static_assert(!std::is_base_of());} +#define sq_delete_refcounted(__ptr,__type) {__ptr->~__type();__ptr->SQDeallocate(__ptr);} #define SQ_MALLOC(__size) sq_vm_malloc((__size)); -#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_FREE(__ptr,__size) {sq_vm_free((__ptr),(__size));static_assert(!std::is_base_of>());} #define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); //sqvector mini vector class, supports objects by value diff --git a/src/3rdparty/squirrel/squirrel/sqvm.h b/src/3rdparty/squirrel/squirrel/sqvm.h index dbfe2309c7..80a36682e1 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.h +++ b/src/3rdparty/squirrel/squirrel/sqvm.h @@ -122,7 +122,7 @@ public: _callsstack = &_callstackdata[0]; _alloccallsstacksize = newsize; } - void Release(){ sq_delete(this,SQVM); } //does nothing + void Release(){ sq_delete_refcounted(this,SQVM); } //does nothing //////////////////////////////////////////////////////////////////////////// //stack functions for the api void Remove(SQInteger n);