From 42a8edc4cd19f25b87313653a02975c130248b7b Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:43:28 +0200 Subject: [PATCH] Squirrel: add multiple SQ API functions Added: - sq_getstackobj - sq_pop - sq_addref - sq_release - SQVM::Pop - RefTable::Get - RefTable::AddRef - RefTable::Release --- src/vscript/CMakeLists.txt | 1 + .../languages/squirrel_re/include/sqstate.h | 4 +++ .../languages/squirrel_re/include/squirrel.h | 19 ++++++++++++ .../languages/squirrel_re/include/sqvm.h | 4 +++ .../languages/squirrel_re/squirrel/sqapi.cpp | 30 +++++++++++++++++++ .../squirrel_re/squirrel/sqstate.cpp | 22 ++++++++++++++ .../languages/squirrel_re/squirrel/sqvm.cpp | 10 +++++++ 7 files changed, 90 insertions(+) create mode 100644 src/vscript/languages/squirrel_re/squirrel/sqstate.cpp diff --git a/src/vscript/CMakeLists.txt b/src/vscript/CMakeLists.txt index f7c28ec1..ff13f9a6 100644 --- a/src/vscript/CMakeLists.txt +++ b/src/vscript/CMakeLists.txt @@ -23,6 +23,7 @@ add_sources( SOURCE_GROUP "Squirrel_RE/squirrel" "languages/squirrel_re/squirrel/sqstring.cpp" "languages/squirrel_re/squirrel/sqtable.cpp" "languages/squirrel_re/squirrel/sqmem.cpp" + "languages/squirrel_re/squirrel/sqstate.cpp" "languages/squirrel_re/squirrel/sqvm.cpp" ) diff --git a/src/vscript/languages/squirrel_re/include/sqstate.h b/src/vscript/languages/squirrel_re/include/sqstate.h index 1adbf85a..01aefb85 100644 --- a/src/vscript/languages/squirrel_re/include/sqstate.h +++ b/src/vscript/languages/squirrel_re/include/sqstate.h @@ -13,6 +13,10 @@ struct RefTable { SQUnsignedInteger refs; struct RefNode* next; }; + void AddRef(SQObject& obj); + SQBool Release(SQObject& obj); + + RefTable::RefNode* Get(SQObject& obj, SQHash& mainpos, RefNode** prev, bool add); private: SQUnsignedInteger _numofslots; SQUnsignedInteger _slotused; diff --git a/src/vscript/languages/squirrel_re/include/squirrel.h b/src/vscript/languages/squirrel_re/include/squirrel.h index 6b5c5b64..1244ed98 100644 --- a/src/vscript/languages/squirrel_re/include/squirrel.h +++ b/src/vscript/languages/squirrel_re/include/squirrel.h @@ -47,6 +47,9 @@ to the following restrictions: #define _SC(a) a +#define SQTrue (1) +#define SQFalse (0) + typedef long SQInteger; typedef unsigned long SQUnsignedInteger; typedef short SQShort; @@ -64,6 +67,8 @@ typedef SQInteger SQRESULT; typedef int ScriptDataType_t; typedef struct SQVM* HSQUIRRELVM; +//typedef SQObject HSQOBJECT; + struct SQBufState; typedef char SQChar; @@ -170,6 +175,8 @@ SQRESULT sq_getthread(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM* thread); SQRESULT sq_getstring(HSQUIRRELVM v, SQInteger idx, const SQChar** c); SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx); SQInteger sq_gettop(HSQUIRRELVM v); +SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, SQObject* po); +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop); SQRESULT sq_pushroottable(HSQUIRRELVM v); void sq_pushbool(HSQUIRRELVM v, SQBool b); void sq_pushstring(HSQUIRRELVM v, const SQChar* string, SQInteger len); @@ -186,6 +193,9 @@ SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerr SQRESULT sq_startconsttable(HSQUIRRELVM v); SQRESULT sq_endconsttable(HSQUIRRELVM v); +void sq_addref(HSQUIRRELVM v, SQObject* po); +SQBool sq_release(HSQUIRRELVM v, SQObject* po); + /*UTILITY MACRO*/ #define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) #define sq_istable(o) ((o)._type==OT_TABLE) @@ -227,6 +237,9 @@ inline SQRESULT (*v_sq_endconsttable)(HSQUIRRELVM v); inline SQString* (*v_StringTable__Add)(void* a1, const SQChar* str, SQInteger len); +inline void* /*RefTable::RefNode*/ (*v_RefTable__Get)(void* /*RefTable*/ thisp, SQObject* obj, SQHash* mainpos, void*/*RefTable::RefNode**/ prev, bool add); +inline SQBool(*v_RefTable__Release)(void* /*RefTable*/ thisp, SQObject* obj); + /////////////////////////////////////////////////////////////////////////////// class VSquirrelAPI : public IDetour { @@ -250,6 +263,9 @@ class VSquirrelAPI : public IDetour LogFunAdr("sq_endconsttable", v_sq_endconsttable); LogFunAdr("StringTable::Add", v_StringTable__Add); + + LogFunAdr("RefTable::Get", v_RefTable__Get); + LogFunAdr("RefTable::Release", v_RefTable__Release); } virtual void GetFun(void) const { @@ -271,6 +287,9 @@ class VSquirrelAPI : public IDetour g_GameDll.FindPatternSIMD("8B 41 78 45 33 C0 FF C8 8B D0 89 41 78 48 C1 E2 04 48 03 91 ?? ?? ?? ?? 8B 02 48 C7 02 ?? ?? ?? ?? 25 ?? ?? ?? ?? 74 15").GetPtr(v_sq_endconsttable); g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 41 8D 4D FF").FollowNearCallSelf().GetPtr(v_StringTable__Add); + + g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? FF 40 10 FF C6").FollowNearCallSelf().GetPtr(v_RefTable__Get); + g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 40 84 7D BC").FollowNearCallSelf().GetPtr(v_RefTable__Release); } virtual void GetVar(void) const { } virtual void GetCon(void) const { } diff --git a/src/vscript/languages/squirrel_re/include/sqvm.h b/src/vscript/languages/squirrel_re/include/sqvm.h index 7f82b708..0bcbd025 100644 --- a/src/vscript/languages/squirrel_re/include/sqvm.h +++ b/src/vscript/languages/squirrel_re/include/sqvm.h @@ -20,6 +20,9 @@ struct SQVM : public CHAINABLE_OBJ { void PrintObjVal(const SQObject* oin, SQObject* oout); + void Pop(); + void Pop(SQInteger n); + // push sqobjectptr on to the stack void Push(const SQObjectPtr& o); @@ -59,6 +62,7 @@ static_assert(offsetof(SQVM, _top) == 0x78); static_assert(offsetof(SQVM, _nnativecalls) == 0x130); inline SQObjectPtr& stack_get(HSQUIRRELVM v, SQInteger idx) { return ((idx >= 0) ? (v->_stackbase[idx-1]) : (v->GetUp(idx))); } +#define _ss(_vm_) (_vm_)->_sharedstate /* ==== SQUIRREL ======================================================================================================================================================== */ inline SQRESULT(*v_SQVM_PrintFunc)(HSQUIRRELVM v, SQChar* fmt, ...); diff --git a/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp b/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp index 707df29f..b5e213af 100644 --- a/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp +++ b/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp @@ -94,6 +94,20 @@ SQInteger sq_gettop(HSQUIRRELVM v) return (v->_top - v->_bottom); } +//--------------------------------------------------------------------------------- +SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, SQObject* po) +{ + *po = stack_get(v, idx); + return SQ_OK; +} + +//--------------------------------------------------------------------------------- +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + Assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + //--------------------------------------------------------------------------------- SQRESULT sq_pushroottable(HSQUIRRELVM v) { @@ -174,16 +188,32 @@ SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerr return v_sq_call(v, params, retval, raiseerror); } +//--------------------------------------------------------------------------------- SQRESULT sq_startconsttable(HSQUIRRELVM v) { return v_sq_startconsttable(v); } +//--------------------------------------------------------------------------------- SQRESULT sq_endconsttable(HSQUIRRELVM v) { return v_sq_endconsttable(v); } +//--------------------------------------------------------------------------------- +void sq_addref(HSQUIRRELVM v, SQObject* po) +{ + if (!ISREFCOUNTED(sq_type(*po))) return; + _ss(v)->_refs_table.AddRef(*po); +} + +//--------------------------------------------------------------------------------- +SQBool sq_release(HSQUIRRELVM v, SQObject* po) +{ + if (!ISREFCOUNTED(sq_type(*po))) return SQTrue; + return _ss(v)->_refs_table.Release(*po); +} + void VSquirrelAPI::Detour(const bool bAttach) const { DetourSetup(&v_sq_pushroottable, &sq_pushroottable, bAttach); diff --git a/src/vscript/languages/squirrel_re/squirrel/sqstate.cpp b/src/vscript/languages/squirrel_re/squirrel/sqstate.cpp new file mode 100644 index 00000000..bd7d6077 --- /dev/null +++ b/src/vscript/languages/squirrel_re/squirrel/sqstate.cpp @@ -0,0 +1,22 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqstate.h" + +void RefTable::AddRef(SQObject& obj) +{ + SQHash mainpos; + RefNode* prev; + RefNode* ref = Get(obj, mainpos, &prev, true); + ref->refs++; +} + +SQBool RefTable::Release(SQObject& obj) +{ + return v_RefTable__Release(this, &obj); +} + +RefTable::RefNode* RefTable::Get(SQObject& obj, SQHash& mainpos, RefNode** prev, bool add) +{ + return (RefTable::RefNode*)v_RefTable__Get(this, &obj, &mainpos, prev, add); +} diff --git a/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp b/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp index ae478ea1..c24d234b 100644 --- a/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp +++ b/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp @@ -174,6 +174,16 @@ void SQVM_LogicError(SQBool bPrompt) v_SQVM_LogicError(bPrompt); } +void SQVM::Pop() { + _stack[--_top] = _null_; +} + +void SQVM::Pop(SQInteger n) { + for (SQInteger i = 0; i < n; i++) { + _stack[--_top] = _null_; + } +} + void SQVM::Push(const SQObjectPtr& o) { _stack[_top++] = o; } SQObjectPtr& SQVM::Top() { return _stack[_top - 1]; } SQObjectPtr& SQVM::PopGet() { return _stack[--_top]; }