From bb73f0a8b5172d2b8c4d85803386b4bca6e9d88f Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Sun, 17 Feb 2019 17:09:32 +0200 Subject: [PATCH] Fix overload name generator not taking into accoun the prefix length. Include a specialized overload forwarder for constructors which don't have a free variable containing the native function pointer. Reduce code duplication from overload forwarder retriever with variadic templates (might as well just get rid of it in the future since it doesn't appear to do much). --- include/sqrat/sqratOverloadMethods.h | 125 +++++++++++++-------------- 1 file changed, 60 insertions(+), 65 deletions(-) diff --git a/include/sqrat/sqratOverloadMethods.h b/include/sqrat/sqratOverloadMethods.h index b1bcc6d2..8aff54a7 100644 --- a/include/sqrat/sqratOverloadMethods.h +++ b/include/sqrat/sqratOverloadMethods.h @@ -53,7 +53,7 @@ public: static void Get(const SQChar* name, int args, string & out) { SQChar buf[16] = {'_', 'o'}; unsigned l = I32ToA(args, &buf[2]); - out.append(buf, l); + out.append(buf, l+2); out.push_back('_'); out.append(name); } @@ -116,6 +116,56 @@ inline SQInteger OverloadExecutionForwarder(HSQUIRRELVM vm) { return f(vm); } +// +// Don't include the overloaded call forwarder into the templated class +// to avoid duplicating code that doesn't need to be specialized. +// +inline SQInteger OverloadConstructionForwarder(HSQUIRRELVM vm) { + const SQInteger top = sq_gettop(vm); + // Get the argument count + const int argCount = static_cast(top - 2); + // Subtract environment and base name in free variable^ + const SQChar* funcName; + SQInteger funcNameSize; + // Get the un-mangled function name (free variable) + sq_getstringandsize(vm, -1, &funcName, &funcNameSize); + // Generate the overload mangled name + string overloadName; + overloadName.reserve(funcNameSize+5); + SqOverloadName::Get(funcName, argCount, overloadName); + // Push the overload mangled name on the stack + sq_pushstring(vm, overloadName.c_str(), static_cast(overloadName.size())); + // Lookup the proper overload and get it on the stack +#if !defined (SCRAT_NO_ERROR_CHECKING) + if (SQ_FAILED(sq_get(vm, 1))) { + sq_settop(vm, top); // keep the stack size intact + return sq_throwerror(vm, _SC("wrong number of parameters")); + } +#else + sq_get(vm, 1); +#endif + SQFUNCTION f = nullptr; + // Get the native closure pointer that we must invoke + SQRESULT res = sq_getnativeclosurepointer(vm, -1, &f); + if (SQ_FAILED(res)) { + return res; + // Make sure a native closure pointer is available + } else if (!f) { + return sq_throwerror(vm, _SC("unable to acquire the proper overload closure")); + } + // Restore the stack size by removing the overload closure object + sq_poptop(vm); + // Pop the un-mangled closure name from the stack + // The constructor doesn't expect any free variables + //sq_poptop(vm); // `funcName` becomes invalid after this + // Perform a direct call and store the result + SQRESULT r = f(vm); + // Keep the stack size intact before leaving + sq_settop(vm, top); + // Return the result back to the caller + return r; +} + // // Squirrel Overload Functions // @@ -192,6 +242,11 @@ inline SQFUNCTION SqOverloadFunc(R (* /*method*/)) { return &SqOverload::Func; } +template +inline SQFUNCTION SqOverloadFunc(R (* /*method*/)(A...)) { + return &SqOverload::Func; +} + template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)) { return &SqOverload::Func; @@ -202,73 +257,13 @@ inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)() const ) { return &SqOverload::Func; } -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1) const ) { +template +inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A...) ) { return &SqOverload::Func; } -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const ) { - return &SqOverload::Func; -} - -template -inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const ) { +template +inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A...) const ) { return &SqOverload::Func; }