Why are the asCALL_CDECL_OBJ[LAST|FIRST] calling conventions only supported in methods?

Started by
3 comments, last by WitchLord 2 years, 2 months ago

TLDR: It seems pretty trivial to add support for them in all contexts, which can be pretty convenient.

I am currently working on augmenting AS' registration system with a little utility to save on boilerplate. Among this is the ability to wrap a factory function for a reference type so that it also registers the new object with the reference counter. This wrapper can't be a template method, because it relies on partial template specialization to deduce the function arguments, which isn't available for methods. This establishes the need to somehow pass a reference to the reference counter to this wrapper.. And `asCALL_CDECL_OBJ[LAST|FIRST]` seems like the perfect fit! However, since factory behaviors are not methods, angelscript refuses to register it with the necessary calling convention! I've gone ahead and simply enabled support for non-methods with the aforementioned calling conventions and it seems to work flawlessly!

Of course it's totally possible that everything will explode, crash and burn any second now, but ignoring that, the restriction here seems pretty arbitrary.

Advertisement

asCALL_CDECL_OBJ[FIRST|LAST] are meant to be used in place of asCALL_THISCALL to allow the application to create custom wrappers for class methods without actually changing the class implementation.

The question is not if it is possible to change them to be used for factory functions as well, but instead: What should AngelScript pass as the object pointer, and where will AngelScript get that pointer from? You say you want to pass a reference to the reference counter. Is it a new instance of the reference counter for each object created by the factory, or is it a common reference counter for all objects created by the factory? If it is a unique instance of reference counter for each object, how does AngelScript know to create this instance to pass it to the factory function? If not a unique instance, how will AngelScript know the pointer that should be passed to the factory?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

@WitchLord Sorry, what I forgot to mention was that the pointer passed to the function being registered would simply be the auxiliary pointer, for which all the necessary logic seems to already exist.

Here's a .diff of all that this change would encompass to my understanding:

diff --git a/sdk/angelscript/source/as_callfunc.cpp b/sdk/angelscript/source/as_callfunc.cpp
index 4941967e..c208d36f 100644
--- a/sdk/angelscript/source/as_callfunc.cpp
+++ b/sdk/angelscript/source/as_callfunc.cpp
@@ -71,6 +71,19 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 	}
 
 	asDWORD base = callConv;
+	if ( base == asCALL_CDECL_OBJFIRST || base == asCALL_CDECL_OBJLAST )
+	{
+		internal->callConv =
+			base == asCALL_CDECL_OBJFIRST ? ICC_CDECL_OBJFIRST : ICC_CDECL_OBJLAST;
+		if ( !isMethod )
+		{
+			if ( auxiliary == 0 )
+				return asINVALID_ARG;
+			internal->auxiliary = auxiliary;
+		}
+		return 0;
+	}
+
 	if( !isMethod )
 	{
 		if( base == asCALL_CDECL )
@@ -151,11 +164,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 		}
 		else
 #endif
-		if( base == asCALL_CDECL_OBJLAST )
-			internal->callConv = ICC_CDECL_OBJLAST;
-		else if( base == asCALL_CDECL_OBJFIRST )
-			internal->callConv = ICC_CDECL_OBJFIRST;
-		else if (base == asCALL_GENERIC)
+		if (base == asCALL_GENERIC)
 		{
 			internal->callConv = ICC_GENERIC_METHOD;
 			internal->auxiliary = auxiliary;

Yes, with the use of the auxiliary pointer this should be just fine.

I'll review your patch in detail, create some test cases, and merge it into the library.

Thanks for the contribution.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement