Squirrel: add multiple SQ API functions

Added:
- sq_getstackobj
- sq_pop
- sq_addref
- sq_release
- SQVM::Pop
- RefTable::Get
- RefTable::AddRef
- RefTable::Release
This commit is contained in:
Kawe Mazidjatari 2024-06-01 11:47:45 +02:00
parent 639f4741b1
commit fb9ba0e454
7 changed files with 90 additions and 0 deletions

View File

@ -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"
)

View File

@ -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;

View File

@ -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 { }

View File

@ -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, ...);

View File

@ -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);

View File

@ -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);
}

View File

@ -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]; }