From 70a49db12718d0ce33c4964d11db7339d038d91c Mon Sep 17 00:00:00 2001 From: Tobiasz Laskowski Date: Fri, 28 Nov 2025 01:43:00 +0000 Subject: [PATCH 1/3] [cppia] Add flag for scriptable overridden methods This allows overridden methods to be marked so that they do not add an addtional slot to the vtable, which has previously caused bugs due to incorrect vtable indices. --- include/hx/Scriptable.h | 8 ++++++++ src/hx/cppia/HaxeNative.cpp | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/include/hx/Scriptable.h b/include/hx/Scriptable.h index db66f25dd..a5f891916 100644 --- a/include/hx/Scriptable.h +++ b/include/hx/Scriptable.h @@ -19,11 +19,19 @@ struct ScriptNamedFunction : public ScriptFunction { ScriptNamedFunction(const ScriptFunction &s) : ScriptFunction(s), name(0), isStatic(false), superExecute(0) { } +#if (HXCPP_API_LEVEL >= 500) + ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, bool inIsOverride=false, StackExecute superExecute=0) + : ScriptFunction(inExe, inSig), name(inName), isStatic(inIsStatic), isOverride(inIsOverride), superExecute(superExecute) { } +#else ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, StackExecute superExecute=0) : ScriptFunction(inExe, inSig), name(inName), isStatic(inIsStatic), superExecute(superExecute) { } +#endif const char *name; bool isStatic; +#if (HXCPP_API_LEVEL >= 500) + bool isOverride; +#endif StackExecute superExecute; }; diff --git a/src/hx/cppia/HaxeNative.cpp b/src/hx/cppia/HaxeNative.cpp index 1b6102025..41073a131 100644 --- a/src/hx/cppia/HaxeNative.cpp +++ b/src/hx/cppia/HaxeNative.cpp @@ -37,7 +37,11 @@ void HaxeNativeClass::addVtableEntries( std::vector &outVtable) if (functions) for(ScriptNamedFunction *func = functions; func->name; func++) +#if (HXCPP_API_LEVEL >= 500) + if (!func->isStatic && !func->isOverride) +#else if (!func->isStatic) +#endif outVtable.push_back( func->name ); } From f3209b6beca46ad67d0b80add7053a266985c990 Mon Sep 17 00:00:00 2001 From: Tobiasz Laskowski Date: Fri, 28 Nov 2025 02:43:18 +0000 Subject: [PATCH 2/3] [cppia] Infer overrides from matching method name For haxe versions that do not tag overridden methods in __scriptableFunctions tables, we can infer overrides at runtime by comparing method names. --- src/hx/cppia/Cppia.h | 7 +++++++ src/hx/cppia/HaxeNative.cpp | 24 ++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/hx/cppia/Cppia.h b/src/hx/cppia/Cppia.h index 0137f2937..fa7d99109 100644 --- a/src/hx/cppia/Cppia.h +++ b/src/hx/cppia/Cppia.h @@ -575,6 +575,9 @@ struct CppiaVar +#if (HXCPP_API_LEVEL >= 500) +# define NATIVE_CLASS_OVERRIDES_MARKED +#endif class HaxeNativeClass { @@ -596,6 +599,10 @@ class HaxeNativeClass static HaxeNativeClass *findClass(const std::string &inName); static HaxeNativeClass *hxObject(); static void link(); +#ifndef NATIVE_CLASS_OVERRIDES_MARKED +private: + void addVtableEntries( std::vector &outVtable, hx::UnorderedSet &outMethodsSet); +#endif }; class HaxeNativeInterface diff --git a/src/hx/cppia/HaxeNative.cpp b/src/hx/cppia/HaxeNative.cpp index 41073a131..6575493d4 100644 --- a/src/hx/cppia/HaxeNative.cpp +++ b/src/hx/cppia/HaxeNative.cpp @@ -30,6 +30,7 @@ HaxeNativeClass::HaxeNativeClass(const std::string &inName, int inDataOffset, Sc haxeSuper = 0; } +#ifdef NATIVE_CLASS_OVERRIDES_MARKED void HaxeNativeClass::addVtableEntries( std::vector &outVtable) { if (haxeSuper) @@ -37,13 +38,28 @@ void HaxeNativeClass::addVtableEntries( std::vector &outVtable) if (functions) for(ScriptNamedFunction *func = functions; func->name; func++) -#if (HXCPP_API_LEVEL >= 500) if (!func->isStatic && !func->isOverride) -#else - if (!func->isStatic) -#endif outVtable.push_back( func->name ); } +#else +void HaxeNativeClass::addVtableEntries(std::vector& outVtable) { + hx::UnorderedSet methodsSet; + addVtableEntries(outVtable, methodsSet); +} + +void HaxeNativeClass::addVtableEntries( std::vector &outVtable, hx::UnorderedSet& outMethodsSet) +{ + if (haxeSuper) + haxeSuper->addVtableEntries(outVtable, outMethodsSet); + + if (functions) + for (ScriptNamedFunction* func = functions; func->name; func++) + if (!func->isStatic && outMethodsSet.find(func->name) == outMethodsSet.end()) { + outVtable.push_back(func->name); + outMethodsSet.emplace(func->name); + } +} +#endif void HaxeNativeClass::dump() { From e378ab783043cd4914d8e81217f00a5c37aacc43 Mon Sep 17 00:00:00 2001 From: Tobiasz Laskowski Date: Mon, 15 Dec 2025 11:34:33 +0000 Subject: [PATCH 3/3] [cppia] Swap scriptable func argument order This way is a bit more backwards compatible. An overridden method will always have a super version provided. --- include/hx/Scriptable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hx/Scriptable.h b/include/hx/Scriptable.h index a5f891916..d3bd89e8f 100644 --- a/include/hx/Scriptable.h +++ b/include/hx/Scriptable.h @@ -20,7 +20,7 @@ struct ScriptNamedFunction : public ScriptFunction ScriptNamedFunction(const ScriptFunction &s) : ScriptFunction(s), name(0), isStatic(false), superExecute(0) { } #if (HXCPP_API_LEVEL >= 500) - ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, bool inIsOverride=false, StackExecute superExecute=0) + ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, StackExecute superExecute=0, bool inIsOverride=false) : ScriptFunction(inExe, inSig), name(inName), isStatic(inIsStatic), isOverride(inIsOverride), superExecute(superExecute) { } #else ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, StackExecute superExecute=0)