mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-02-21 20:27:13 +01:00
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).
This commit is contained in:
parent
3ef97727b6
commit
bb73f0a8b5
@ -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<int>(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<SQInteger>(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<R>::Func;
|
||||
}
|
||||
|
||||
template <class R, class... A>
|
||||
inline SQFUNCTION SqOverloadFunc(R (* /*method*/)(A...)) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)) {
|
||||
return &SqOverload<R>::Func;
|
||||
@ -202,73 +257,13 @@ inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)() const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1) const ) {
|
||||
template <class C, class R, class... A>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A...) ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const ) {
|
||||
template <class C, class R, class... A>
|
||||
inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A...) const ) {
|
||||
return &SqOverload<R>::Func;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user