From 76078d98a4ec420769e19ebe9bb6c799c866bc69 Mon Sep 17 00:00:00 2001 From: VasiliyRyabsev Date: Wed, 30 Oct 2024 15:42:59 +0100 Subject: [PATCH] Rework direct API for object comparison Add sq_direct_is_equal() - this is not the same as invoking ObjCmp() on objects. Logic of this comparison is the same as for <=> operator and it can fail in certain scenarios. Also for safety such comparison of non-numeric types (or classes implementing _cmp metamethod) will be disabled soon. In practice sq_direct_cmp() function was never needed - in all the cases it was used for the equality check. For this, implement sq_direct_is_equal() function. Also simplify sq_direct_cmp() implementation - make it a thin wrapper around SQVM::ObjCmp(). No need for extra logic that differs from VM internals. --- include/sqdirect.h | 1 + sqrat/include/sqrat/sqratFunction.h | 3 +-- sqrat/include/sqrat/sqratObject.h | 3 +-- squirrel/sqdirect.cpp | 23 +++++++++++++++-------- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/sqdirect.h b/include/sqdirect.h index 833c4a9a..a7b3ffe5 100644 --- a/include/sqdirect.h +++ b/include/sqdirect.h @@ -22,6 +22,7 @@ SQUIRREL_API SQRESULT sq_direct_get(HSQUIRRELVM v, const HSQOBJECT *obj, const H SQUIRREL_API SQBool sq_direct_tobool(const HSQOBJECT *o); SQUIRREL_API SQBool sq_direct_cmp(HSQUIRRELVM v, const HSQOBJECT *a, const HSQOBJECT *b, SQInteger *res); +SQUIRREL_API bool sq_direct_is_equal(HSQUIRRELVM v, const HSQOBJECT *a, const HSQOBJECT *b); SQUIRREL_API SQRESULT sq_direct_getuserdata(const HSQOBJECT *obj, SQUserPointer *p, SQUserPointer *typetag=NULL); diff --git a/sqrat/include/sqrat/sqratFunction.h b/sqrat/include/sqrat/sqratFunction.h index 23287e72..63f2d953 100644 --- a/sqrat/include/sqrat/sqratFunction.h +++ b/sqrat/include/sqrat/sqratFunction.h @@ -284,8 +284,7 @@ class Function { if (GetVM() != so.GetVM()) return false; - SQInteger res = 0; - return sq_direct_cmp(vm, &obj, &so.obj, &res) && (res==0); + return sq_direct_is_equal(vm, &obj, &so.obj); } private: diff --git a/sqrat/include/sqrat/sqratObject.h b/sqrat/include/sqrat/sqratObject.h index fed3118b..4190ffa5 100644 --- a/sqrat/include/sqrat/sqratObject.h +++ b/sqrat/include/sqrat/sqratObject.h @@ -203,8 +203,7 @@ class Object { if (GetVM() != so.GetVM()) return false; - SQInteger res = 0; - return sq_direct_cmp(vm, &obj, &so.obj, &res) && (res==0); + return sq_direct_is_equal(vm, &obj, &so.obj); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/squirrel/sqdirect.cpp b/squirrel/sqdirect.cpp index 6495b989..bdc89140 100644 --- a/squirrel/sqdirect.cpp +++ b/squirrel/sqdirect.cpp @@ -32,16 +32,23 @@ SQBool sq_direct_cmp(HSQUIRRELVM v, const HSQOBJECT *a, const HSQOBJECT *b, SQIn const SQObjectPtr &aPtr = static_cast(*a); const SQObjectPtr &bPtr = static_cast(*b); - SQObjectType t1 = sq_type(*a), t2 = sq_type(*b); - if (t1 == t2 || t1==OT_NULL || t2==OT_NULL || (sq_isnumeric(*a) && sq_isnumeric(*b))) - { - SQBool status = v->ObjCmp(aPtr, bPtr, *res); - assert(status); - return status; - } - return false; + return v->ObjCmp(aPtr, bPtr, *res); } + +bool sq_direct_is_equal(HSQUIRRELVM v, const HSQOBJECT *a, const HSQOBJECT *b) +{ + const SQObjectPtr &aPtr = static_cast(*a); + const SQObjectPtr &bPtr = static_cast(*b); + + bool res = false; + bool status = v->IsEqual(aPtr, bPtr, res); + (void)status; + assert(status); // cannot fail + return res; +} + + SQRESULT sq_direct_getuserdata(const HSQOBJECT *obj, SQUserPointer *p, SQUserPointer *typetag) { if (obj->_type != OT_USERDATA)