rename monostate ctors to zero ctors & make it platform independent

This commit is contained in:
altalk23 2023-03-06 00:52:39 +03:00
parent 0706e52c81
commit c89df7b992
38 changed files with 129 additions and 192 deletions

View file

@ -34,10 +34,7 @@ public:
static constexpr auto CLASS_NAME = "{class_name}";
)GEN";
char const* monostate_constructor = R"GEN( GEODE_MONOSTATE_CONSTRUCTOR_GD({class_name}, {first_base})
)GEN";
char const* monostate_constructor_cutoff = R"GEN( GEODE_MONOSTATE_CONSTRUCTOR_CUTOFF({class_name}, {first_base})
char const* zero_constructor = R"GEN( GEODE_ZERO_CONSTRUCTOR({class_name}, {first_base})
)GEN";
char const* function_definition = R"GEN(
@ -180,9 +177,7 @@ std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singl
// what.
if (!cls.superclasses.empty()) {
single_output += fmt::format(
can_find(cls.superclasses[0], "cocos2d")
? format_strings::monostate_constructor_cutoff
: format_strings::monostate_constructor,
format_strings::zero_constructor,
fmt::arg("class_name", cls.name),
fmt::arg("first_base", cls.superclasses[0])
);

View file

@ -85,13 +85,13 @@ auto {class_name}::{function_name}({parameters}){const} -> decltype({function_na
reinterpret_cast<FunctionType>(func)(this{parameter_comma}{arguments});
// we need to construct it back so that it uhhh ummm doesnt crash
// while going to the child destructors
auto thing = new (this) {class_name}(std::monostate(), sizeof({class_name}));
auto thing = new (this) {class_name}(geode::ZeroConstructor);
CCDestructor::lock(this) = true;
}}
)GEN";
char const* declare_constructor = R"GEN(
{class_name}::{function_name}({parameters}) : {class_name}(std::monostate(), sizeof({class_name})) {{
{class_name}::{function_name}({parameters}) : {class_name}(geode::ZeroConstructor) {{
// here we construct it as normal as we can, then destruct it
// using the generated functions. this ensures no memory gets leaked
// no crashes :pray:

View file

@ -69,28 +69,21 @@ namespace cocos2d::extension {}
#define GEODE_EXPAND(x) x
#define GEODE_INVOKE(macro, ...) GEODE_EXPAND(macro(__VA_ARGS__))
#define GEODE_FILL_CONSTRUCTOR(Class_, Offset_) \
Class_(std::monostate, size_t fill) : \
Class_({}, std::memset(reinterpret_cast<std::byte*>(this) + Offset_, 0, fill - Offset_)) {} \
Class_(std::monostate, void*)
namespace geode {
struct ZeroConstructorType {};
#define GEODE_MONOSTATE_CONSTRUCTOR_BEGIN(Class_) \
GEODE_MACOS(GEODE_FILL_CONSTRUCTOR(Class_, 0){}) \
GEODE_IOS(GEODE_FILL_CONSTRUCTOR(Class_, 0){})
static constexpr auto ZeroConstructor = ZeroConstructorType();
}
#define GEODE_MONOSTATE_CONSTRUCTOR_COCOS(Class_, Base_) \
GEODE_MACOS(Class_(std::monostate, size_t fill) : Base_({}, fill){}) \
GEODE_IOS(Class_(std::monostate, size_t fill) : Base_({}, fill){})
#define GEODE_ZERO_CONSTRUCTOR_BEGIN(Class_) \
Class_(geode::ZeroConstructorType, void*) {} \
Class_(geode::ZeroConstructorType, size_t fill) : \
Class_(geode::ZeroConstructor, std::memset(static_cast<void*>(this), 0, fill)) {} \
Class_(geode::ZeroConstructorType) : Class_(geode::ZeroConstructor, nullptr) {}
#define GEODE_MONOSTATE_CONSTRUCTOR_GD(Class_, Base_) \
GEODE_WINDOWS(Class_(std::monostate, size_t fill) : Base_({}, fill){}) \
GEODE_MACOS(Class_(std::monostate, size_t fill) : Base_({}, fill){}) \
GEODE_IOS(Class_(std::monostate, size_t fill) : Base_({}, fill){})
#define GEODE_MONOSTATE_CONSTRUCTOR_CUTOFF(Class_, Base_) \
GEODE_WINDOWS(GEODE_FILL_CONSTRUCTOR(Class_, sizeof(Base_)) : Base_(){}) \
GEODE_MACOS(Class_(std::monostate, size_t fill) : Base_({}, fill){}) \
GEODE_IOS(Class_(std::monostate, size_t fill) : Base_({}, fill){})
#define GEODE_ZERO_CONSTRUCTOR(Class_, Base_) \
Class_(geode::ZeroConstructorType, size_t fill) : Base_(geode::ZeroConstructor, fill) {} \
Class_(geode::ZeroConstructorType) : Base_(geode::ZeroConstructor, sizeof(Class_)) {}
#define GEODE_NUMBER_OF_ARGS(...) \
GEODE_EXPAND(GEODE_NUMBER_OF_ARGS_(__VA_ARGS__, GEODE_NUMBER_SEQUENCE(), ))

View file

@ -121,6 +121,7 @@ public:
* @js ctor
*/
CCDirector(void);
GEODE_ZERO_CONSTRUCTOR(CCDirector, CCObject)
/**
* @js NA
* @lua NA
@ -146,7 +147,7 @@ public:
/** Get the FPS value */
inline double getAnimationInterval(void) { return m_dAnimationInterval; }
/** Set the FPS value. */
virtual void setAnimationInterval(double dValue) = 0;
virtual void setAnimationInterval(double dValue) {}
/** Whether or not to display the FPS on the bottom-left corner */
inline bool isDisplayStats(void) { return m_bDisplayStats; }
@ -308,13 +309,13 @@ protected:
/** Stops the animation. Nothing will be drawn. The main loop won't be triggered anymore.
If you don't want to pause your animation call [pause] instead.
*/
virtual void stopAnimation(void) = 0;
virtual void stopAnimation(void) {}
/** The main loop is triggered again.
Call this function only if [stopAnimation] was called earlier
@warning Don't call this function to start the main loop. To run the main loop call runWithScene
*/
virtual void startAnimation(void) = 0;
virtual void startAnimation(void) {}
public:
/** Draw the scene.
@ -345,7 +346,7 @@ public:
void setDepthTest(bool bOn);
protected:
virtual void mainLoop(void) = 0;
virtual void mainLoop(void) {}
/** The size in pixels of the surface. It could be different than the screen size.
High-res devices might have a higher surface size than the screen size.

View file

@ -141,6 +141,7 @@ class CC_DLL CCScheduler : public CCObject
GEODE_FRIEND_MODIFY
public:
CCScheduler();
GEODE_ZERO_CONSTRUCTOR(CCScheduler, CCObject)
/**
* @js NA
* @lua NA

View file

@ -140,7 +140,7 @@ public:
* @js ctor
*/
CCNode(void);
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCNode, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCNode, CCObject)
/**
* Default destructor
@ -1638,7 +1638,7 @@ public:
* @js ctor
*/
CCNodeRGBA();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCNodeRGBA, CCNode)
GEODE_ZERO_CONSTRUCTOR(CCNodeRGBA, CCNode)
/**
* @js NA
* @lua NA

View file

@ -112,7 +112,7 @@ protected:
int m_nUnknown;
)
public:
GEODE_MONOSTATE_CONSTRUCTOR_BEGIN(CCObject)
GEODE_ZERO_CONSTRUCTOR_BEGIN(CCObject)
CCObject(void);
/**
* @lua NA

View file

@ -46,7 +46,7 @@ public:
* @lua NA
*/
CCSet(void);
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCSet, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCSet, CCObject)
/**
* @lua NA
*/

View file

@ -47,6 +47,7 @@ class CC_DLL CCString : public CCObject
{
GEODE_FRIEND_MODIFY
public:
GEODE_ZERO_CONSTRUCTOR(CCString, CCObject)
/**
* @lua NA
*/

View file

@ -94,7 +94,7 @@ public:
void setBlendFunc(const ccBlendFunc &blendFunc);
CCDrawNode();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCDrawNode, CCNodeRGBA)
GEODE_ZERO_CONSTRUCTOR(CCDrawNode, CCNodeRGBA)
/** listen the event that coming to foreground on Android
* @js NA

View file

@ -139,7 +139,7 @@ public:
* @js ctor
*/
CCControl();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCControl, CCLayerRGBA)
GEODE_ZERO_CONSTRUCTOR(CCControl, CCLayerRGBA)
virtual bool init(void);
/**

View file

@ -58,7 +58,7 @@ public:
virtual void setColorValue(ccColor3B const&);
)
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCControlColourPicker, CCControl)
GEODE_ZERO_CONSTRUCTOR(CCControlColourPicker, CCControl)
CCControlColourPicker();
virtual ~CCControlColourPicker();

View file

@ -54,7 +54,7 @@ class CC_DLL CCScale9Sprite : public CCNodeRGBA
{
public:
CCScale9Sprite();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCScale9Sprite, CCNodeRGBA)
GEODE_ZERO_CONSTRUCTOR(CCScale9Sprite, CCNodeRGBA)
virtual ~CCScale9Sprite();
public:

View file

@ -69,7 +69,7 @@ public:
* @js ctor
*/
CCScrollView();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCScrollView, CCLayer)
GEODE_ZERO_CONSTRUCTOR(CCScrollView, CCLayer)
/**
* @js NA
* @lua NA

View file

@ -59,7 +59,7 @@ class CC_DLL CCKeypadHandler : public CCObject
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCKeypadHandler, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCKeypadHandler, CCObject)
inline CCKeypadHandler() = default;
virtual ~CCKeypadHandler(void);

View file

@ -198,7 +198,7 @@ public:
* @js ctor
*/
CCLabelBMFont();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCLabelBMFont, CCSpriteBatchNode)
GEODE_ZERO_CONSTRUCTOR(CCLabelBMFont, CCSpriteBatchNode)
/**
* @js NA
* @lua NA

View file

@ -63,6 +63,7 @@ public:
* @js ctor
*/
CCLabelTTF();
GEODE_ZERO_CONSTRUCTOR(CCLabelTTF, CCSprite)
/**
* @js NA
* @lua NA

View file

@ -75,7 +75,7 @@ public:
* @js ctor
*/
CCLayer();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCLayer, CCNode)
GEODE_ZERO_CONSTRUCTOR(CCLayer, CCNode)
/**
* @js NA
* @lua NA
@ -233,7 +233,7 @@ public:
* @js ctor
*/
CCLayerRGBA();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCLayerRGBA, CCLayer)
GEODE_ZERO_CONSTRUCTOR(CCLayerRGBA, CCLayer)
/**
* @js NA
* @lua NA
@ -290,7 +290,7 @@ public:
* @js ctor
*/
CCLayerColor();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCLayerColor, CCLayerRGBA)
GEODE_ZERO_CONSTRUCTOR(CCLayerColor, CCLayerRGBA)
/**
* @js NA
* @lua NA

View file

@ -63,7 +63,7 @@ public:
* @js ctor
*/
CCScene();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCScene, CCNode)
GEODE_ZERO_CONSTRUCTOR(CCScene, CCNode)
/**
* @js NA
* @lua NA

View file

@ -64,7 +64,7 @@ public:
* @js ctor
*/
CCMenu() : m_pSelectedItem(NULL) {}
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCMenu, CCLayerRGBA)
GEODE_ZERO_CONSTRUCTOR(CCMenu, CCLayerRGBA)
/**
* @js NA
* @lua NA

View file

@ -71,7 +71,7 @@ public:
, m_pfnSelector(NULL)
, m_nScriptTapHandler(0)
{}
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCMenuItem, CCNodeRGBA)
GEODE_ZERO_CONSTRUCTOR(CCMenuItem, CCNodeRGBA)
/**
* @js NA
* @lua NA
@ -139,7 +139,7 @@ public:
: m_pLabel(NULL)
, m_fOriginalScale(0.0)
{}
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCMenuItemLabel, CCMenuItem)
GEODE_ZERO_CONSTRUCTOR(CCMenuItemLabel, CCMenuItem)
/**
* @js NA
* @lua NA
@ -292,7 +292,7 @@ public:
,m_pSelectedImage(NULL)
,m_pDisabledImage(NULL)
{}
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCMenuItemSprite, CCMenuItem)
GEODE_ZERO_CONSTRUCTOR(CCMenuItemSprite, CCMenuItem)
/** creates a menu item with a normal, selected and disabled image*/
static CCMenuItemSprite * create(CCNode* normalSprite, CCNode* selectedSprite, CCNode* disabledSprite = NULL);
@ -337,7 +337,7 @@ public:
* @lua NA
*/
CCMenuItemImage(){}
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCMenuItemImage, CCMenuItemSprite)
GEODE_ZERO_CONSTRUCTOR(CCMenuItemImage, CCMenuItemSprite)
/**
* @js NA
* @lua NA

View file

@ -62,24 +62,24 @@ public:
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching() = 0;
virtual bool applicationDidFinishLaunching() { return true; }
/**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground() = 0;
virtual void applicationDidEnterBackground() {}
/**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground() = 0;
virtual void applicationWillEnterForeground() {}
RT_ADD(
virtual void applicationWillBecomeActive() {}
virtual void applicationWillResignActive() {}
virtual void trySaveGame() = 0;
virtual void trySaveGame() {}
virtual void gameDidSave() {}
)
@ -87,18 +87,18 @@ public:
@brief Callback by CCDirector for limit FPS.
@interval The time, expressed in seconds, between current frame and next.
*/
virtual void setAnimationInterval(double interval) = 0;
virtual void setAnimationInterval(double interval) {}
/**
@brief Get current language config
@return Current language config
*/
virtual ccLanguageType getCurrentLanguage() = 0;
virtual ccLanguageType getCurrentLanguage() { return kLanguageEnglish; }
/**
@brief Get target platform
*/
virtual TargetPlatform getTargetPlatform() = 0;
virtual TargetPlatform getTargetPlatform() { return kTargetWindows; }
RT_ADD( virtual void openURL(const char* url) {} )
};

View file

@ -41,8 +41,8 @@ class CCArray;
*/
struct CCTexturePack {
std::string m_id;
std::vector<std::string> m_paths;
std::string m_id;
std::vector<std::string> m_paths;
};
//! @brief Helper class to handle file operations
@ -52,6 +52,8 @@ class CC_DLL CCFileUtils : public TypeInfo
friend class CCArray;
friend class CCDictionary;
public:
GEODE_ZERO_CONSTRUCTOR_BEGIN(CCFileUtils)
/**
* Returns an unique ID for this class.
* @note It's only used for JSBindings now.
@ -339,7 +341,7 @@ public:
* @return The path that can be write/read a file in
* @lua NA
*/
virtual gd::string getWritablePath() = 0;
virtual gd::string getWritablePath() { return ""; }
RT_ADD(virtual gd::string getWritablePath2();)
@ -351,7 +353,7 @@ public:
* @return true if the file exists, otherwise it will return false.
* @lua NA
*/
virtual bool isFileExist(const gd::string& strFilePath) = 0;
virtual bool isFileExist(const gd::string& strFilePath) { return false; }
/**
* Checks whether the path is an absolute path.

View file

@ -46,7 +46,7 @@ public:
@js ctor
*/
CCImage();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCImage, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCImage, CCObject)
/**
* @js NA
* @lua NA

View file

@ -36,7 +36,7 @@ class CC_DLL CCApplication : public CCApplicationProtocol
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_BEGIN(CCApplication)
GEODE_ZERO_CONSTRUCTOR_BEGIN(CCApplication)
CCApplication();
/**
* @js NA

View file

@ -35,7 +35,7 @@ class CC_DLL CCApplication : public CCApplicationProtocol
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_BEGIN(CCApplication)
GEODE_ZERO_CONSTRUCTOR_BEGIN(CCApplication)
CCApplication();
virtual ~CCApplication();

View file

@ -15,7 +15,7 @@ class CC_DLL CCApplication : public CCApplicationProtocol
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_BEGIN(CCApplication)
GEODE_ZERO_CONSTRUCTOR_BEGIN(CCApplication)
CCApplication();
virtual ~CCApplication();

View file

@ -45,6 +45,7 @@ protected:
RT_ADD( virtual ~CCEGLView(); )
public:
CCEGLView();
GEODE_ZERO_CONSTRUCTOR(CCEGLView, CCObject)
RT_REMOVE( virtual ~CCEGLView(); )
/* override functions */

View file

@ -207,7 +207,7 @@ RT_ADD(
class CC_DLL CCKeyboardHandler : public CCObject
{
public:
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCKeyboardHandler, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCKeyboardHandler, CCObject)
inline CCKeyboardHandler() = default;
virtual ~CCKeyboardHandler();

View file

@ -22,7 +22,7 @@ RT_ADD(
class CC_DLL CCMouseHandler : public CCObject
{
public:
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCMouseHandler, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCMouseHandler, CCObject)
inline CCMouseHandler() = default;
virtual ~CCMouseHandler();

View file

@ -168,7 +168,7 @@ public:
* @js ctor
*/
CCSprite(void);
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCSprite, CCNodeRGBA)
GEODE_ZERO_CONSTRUCTOR(CCSprite, CCNodeRGBA)
/**
* Default destructor

View file

@ -68,7 +68,7 @@ public:
* @js ctor
*/
CCSpriteBatchNode();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCSpriteBatchNode, CCNode)
GEODE_ZERO_CONSTRUCTOR(CCSpriteBatchNode, CCNode)
/**
* @js NA
* @lua NA

View file

@ -50,6 +50,7 @@ class CC_DLL CCIMEDelegate
{
GEODE_FRIEND_MODIFY
public:
GEODE_ZERO_CONSTRUCTOR_BEGIN(CCIMEDelegate)
virtual ~CCIMEDelegate();
virtual bool attachWithIME();

View file

@ -117,7 +117,7 @@ public:
* @js ctor
*/
CCTexture2D();
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCTexture2D, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCTexture2D, CCObject)
/**
* @js NA
* @lua NA

View file

@ -48,7 +48,7 @@ class CC_DLL CCTouchHandler : public CCObject
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCTouchHandler, CCObject)
GEODE_ZERO_CONSTRUCTOR(CCTouchHandler, CCObject)
inline CCTouchHandler() = default;
virtual ~CCTouchHandler(void);
@ -86,7 +86,7 @@ class CC_DLL CCStandardTouchHandler : public CCTouchHandler
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCStandardTouchHandler, CCTouchHandler)
GEODE_ZERO_CONSTRUCTOR(CCStandardTouchHandler, CCTouchHandler)
inline CCStandardTouchHandler() = default;
~CCStandardTouchHandler(void);
@ -110,7 +110,7 @@ class CC_DLL CCTargetedTouchHandler : public CCTouchHandler
{
GEODE_FRIEND_MODIFY
public:
GEODE_MONOSTATE_CONSTRUCTOR_COCOS(CCTargetedTouchHandler, CCTouchHandler)
GEODE_ZERO_CONSTRUCTOR(CCTargetedTouchHandler, CCTouchHandler)
inline CCTargetedTouchHandler() = default;
~CCTargetedTouchHandler(void);

View file

@ -134,8 +134,8 @@ namespace geode {
// abusing the internal stuff
// basically we dont want modify to invoke base ctors and dtors
// we already have utilities for these, which are ccdestructor
// and the monostate constructor
Modify() : Base(std::monostate(), sizeof(Base)) {}
// and the zero constructor
Modify() : Base(ZeroConstructor) {}
~Modify() {
cocos2d::CCDestructor::lock(this) = true;

View file

@ -9,36 +9,24 @@
#include <Geode/DefaultInclude.hpp>
#include <cocos-ext.h>
#include <concepts>
#include <cstdlib>
#include <stddef.h>
#include <type_traits>
#include <concepts>
namespace geode::addresser {
template <typename T>
inline intptr_t getVirtual(T func);
template <class Function>
intptr_t getVirtual(Function func);
template <typename T>
inline intptr_t getNonVirtual(T func);
template <class Function>
intptr_t getNonVirtual(Function func);
template <typename T, typename F>
inline F thunkAdjust(T func, F self);
template <class Function, class Class>
Class thunkAdjust(Function func, Class self);
template <typename T, typename F>
inline F rthunkAdjust(T func, F self);
template <class Class>
Class* friendCreate(typename std::void_t<decltype(static_cast<Class* (*)()>(&Class::create))>*) {
auto ret = Class::create();
ret->retain();
return ret;
}
template <class Class>
concept HasCreate = requires() {
{ friendCreate<Class>(nullptr) } -> std::same_as<Class*>;
};
template <class Function, class Class>
Class rthunkAdjust(Function func, Class self);
class GEODE_DLL Addresser final {
template <char C>
@ -76,57 +64,20 @@ namespace geode::addresser {
return thunk;
}
// I gave up
// template <HasCreate Class>
// static Class* generateInstance(Class*) {
// return friendCreate<Class>(nullptr);
// }
// I extra gave up
template <class = void>
static cocos2d::extension::CCScrollView* generateInstance(cocos2d::extension::CCScrollView*) {
return cocos2d::extension::CCScrollView::create({0.0f, 0.0f}, cocos2d::CCLayer::create());
}
template <class = void>
static cocos2d::CCFileUtils* generateInstance(cocos2d::CCFileUtils*) {
return cocos2d::CCFileUtils::sharedFileUtils();
}
template <class Class>
static Class* generateInstance(Class*) {
if constexpr (std::is_abstract_v<Class>) {
// Cant construct abstract classes, so fail early
return nullptr;
} else {
// Create a random memory block with the size of Class
// Assign a pointer to that block and cast it to type Class*
uint8_t dum[sizeof(Class)]{};
auto ptr = reinterpret_cast<Class*>(dum);
// Now you have a object of Class that actually isn't an object of Class and is just a
// random memory But C++ doesn't know that of course So now you can copy an object
// that wasn't there in the first place
// ((oh also get the offsets of the virtual tables))
auto ins = new Class(*ptr);
// this is how the first human was made
return ins;
}
}
template <class Class>
static Class* cachedInstance() {
static auto ret = generateInstance(static_cast<Class*>(nullptr));
static auto ret = new Class(ZeroConstructor);
return ret;
}
/**
* Specialized functionss
*/
template <typename R, typename T, typename... Ps>
static intptr_t addressOfVirtual(R (T::*func)(Ps...)) {
template <class Return, class Class, class... Parameters>
static intptr_t addressOfVirtual(Return (Class::*func)(Parameters...)) {
using geode::cast::reference_cast;
auto ins = cachedInstance<T>();
auto ins = cachedInstance<Class>();
// generateInstance will return nullptr on most abstract classes,
// so dont bother getting the address
if (ins == nullptr) {
@ -136,97 +87,87 @@ namespace geode::addresser {
auto thunk = thunkOf(func);
// [[this + thunk] + offset] is the function we want
auto address = *reinterpret_cast<intptr_t*>(*reinterpret_cast<intptr_t*>(reinterpret_cast<intptr_t>(ins) + thunk) + index);
auto address = *reinterpret_cast<intptr_t*>(
*reinterpret_cast<intptr_t*>(reinterpret_cast<intptr_t>(ins) + thunk) + index
);
address = followThunkFunction(address);
return address;
}
template <typename R, typename T, typename... Ps>
static intptr_t addressOfVirtual(R (T::*func)(Ps...) const) {
return addressOfVirtual(reinterpret_cast<R (T::*)(Ps...)>(func));
template <class Return, class Class, class... Parameters>
static intptr_t addressOfVirtual(Return (Class::*func)(Parameters...) const) {
return addressOfVirtual(reinterpret_cast<Return (Class::*)(Parameters...)>(func));
}
template <typename R, typename T, typename... Ps>
static intptr_t addressOfNonVirtual(R (T::*func)(Ps...) const) {
return addressOfNonVirtual(reinterpret_cast<R (T::*)(Ps...)>(func));
template <class Return, class Class, class... Parameters>
static intptr_t addressOfNonVirtual(Return (Class::*func)(Parameters...) const) {
return addressOfNonVirtual(reinterpret_cast<Return (Class::*)(Parameters...)>(func));
}
static intptr_t followThunkFunction(intptr_t address);
template <typename R, typename T, typename... Ps>
static intptr_t addressOfNonVirtual(R (T::*func)(Ps...)) {
template <class Return, class Class, class... Parameters>
static intptr_t addressOfNonVirtual(Return (Class::*func)(Parameters...)) {
return followThunkFunction(geode::cast::reference_cast<intptr_t>(func));
}
template <typename R, typename... Ps>
static intptr_t addressOfNonVirtual(R (*func)(Ps...)) {
template <class Return, class... Parameters>
static intptr_t addressOfNonVirtual(Return (*func)(Parameters...)) {
return followThunkFunction(geode::cast::reference_cast<intptr_t>(func));
}
template <typename T>
friend intptr_t getVirtual(T func);
template <class Function>
friend intptr_t getVirtual(Function func);
template <typename T>
friend intptr_t getNonVirtual(T func);
template <class Function>
friend intptr_t getNonVirtual(Function func);
template <typename T, typename F>
friend F thunkAdjust(T func, F self);
template <class Function, class Class>
friend Class thunkAdjust(Function func, Class self);
template <typename T, typename F>
friend F rthunkAdjust(T func, F self);
template <class Function, class Class>
friend Class rthunkAdjust(Function func, Class self);
};
#ifdef GEODE_ADDRESSER_TEST
template <typename T>
inline intptr_t getVirtual(T func) {
/**
* Gets the real address of a virtual function
*/
template <class Function>
inline intptr_t getVirtual(Function func) {
return Addresser::addressOfVirtual(func);
}
template <typename T>
inline intptr_t getNonVirtual(T func) {
/**
* Gets the real address of a non-virtual function
*/
template <class Function>
inline intptr_t getNonVirtual(Function func) {
return Addresser::addressOfNonVirtual(func);
}
#else
template <typename T>
inline intptr_t getVirtual(T func) {
// log::debug(
// "Get virtual function address from {}",
// utils::intToHex(geode::cast::reference_cast<intptr_t>(func))
// );
auto addr = Addresser::addressOfVirtual(func);
// log::debug("The address is: {}", utils::intToHex(addr));
return addr;
}
template <typename T>
inline intptr_t getNonVirtual(T func) {
// log::debug(
// "Get non-virtual function address from {}",
// utils::intToHex(geode::cast::reference_cast<intptr_t>(func))
// );
auto addr = Addresser::addressOfNonVirtual(func);
// log::debug("The address is: {}", utils::intToHex(addr));
return addr;
}
template <typename T, typename F>
inline F thunkAdjust(T func, F self) {
/**
* Adjusts a class instance to its appropriate base for the given virtual function
*/
template <class Function, class Class>
inline Class thunkAdjust(Function func, Class self) {
// do NOT delete the line below.
// doing so breaks thunk adjusting on windows.
// why? bruh idk
auto _ = *geode::cast::template union_cast<ptrdiff_t*>(&func);
return (F)((intptr_t)self + Addresser::thunkOf(func));
return (Class)((intptr_t)self + Addresser::thunkOf(func));
}
template <typename T, typename F>
inline F rthunkAdjust(T func, F self) {
/**
* Adjusts a class instance back from its appropriate base for the given virtual function to the original base
*/
template <class Function, class Class>
inline Class rthunkAdjust(Function func, Class self) {
// do NOT delete the line below.
// doing so breaks thunk adjusting on windows.
// why? bruh idk
auto _ = *geode::cast::template union_cast<ptrdiff_t*>(&func);
return (F)((intptr_t)self - Addresser::thunkOf(func));
return (Class)((intptr_t)self - Addresser::thunkOf(func));
}
#endif
}

Binary file not shown.