Internal Changes
This commit is contained in:
parent
308a36b4ba
commit
c803572e24
68
data/out.h
68
data/out.h
@ -15,20 +15,33 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
// Internal Macros
|
||||||
|
#define __PREVENT_DESTRUCTION(self) \
|
||||||
|
~self() = delete
|
||||||
|
#define __PREVENT_CONSTRUCTION(self) \
|
||||||
|
self() = delete; \
|
||||||
|
__PREVENT_DESTRUCTION(self)
|
||||||
|
#define __PREVENT_COPY(self) \
|
||||||
|
self(const self &) = delete; \
|
||||||
|
self &operator=(const self &) = delete
|
||||||
|
|
||||||
// Virtual Function Information
|
// Virtual Function Information
|
||||||
template <typename T>
|
struct __VirtualFunctionInfo {
|
||||||
class __Function;
|
// Constructors
|
||||||
template <typename T>
|
template <typename Ret, typename Self, typename Super, typename... Args>
|
||||||
class __VirtualFunctionInfo {
|
__VirtualFunctionInfo(Ret (**const addr_)(Self, Args...), Ret (*const parent_)(Super, Args...)):
|
||||||
__VirtualFunctionInfo(T *const addr_, void *const parent_):
|
addr((void **) addr_),
|
||||||
addr(addr_),
|
parent((void *) parent_) {}
|
||||||
parent(parent_) {}
|
template <typename T>
|
||||||
|
__VirtualFunctionInfo(T **const addr_, const std::nullptr_t parent_):
|
||||||
|
__VirtualFunctionInfo(addr_, (T *) parent_) {}
|
||||||
|
// Method
|
||||||
[[nodiscard]] bool can_overwrite() const {
|
[[nodiscard]] bool can_overwrite() const {
|
||||||
return ((void *) *addr) != parent;
|
return *addr != parent;
|
||||||
}
|
}
|
||||||
T *const addr;
|
// Properties
|
||||||
|
void **const addr;
|
||||||
void *const parent;
|
void *const parent;
|
||||||
friend class __Function<std::remove_pointer_t<T>>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Thunks
|
// Thunks
|
||||||
@ -36,25 +49,32 @@ typedef void *(*thunk_enabler_t)(void *target, void *thunk);
|
|||||||
extern thunk_enabler_t thunk_enabler;
|
extern thunk_enabler_t thunk_enabler;
|
||||||
|
|
||||||
// Function Information
|
// Function Information
|
||||||
|
template <typename T>
|
||||||
|
class __Function;
|
||||||
template <typename Ret, typename... Args>
|
template <typename Ret, typename... Args>
|
||||||
class __Function<Ret(Args...)> {
|
class __Function<Ret(Args...)> {
|
||||||
|
// Prevent Copying
|
||||||
|
__PREVENT_COPY(__Function);
|
||||||
|
__PREVENT_DESTRUCTION(__Function);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Types
|
// Types
|
||||||
using ptr_type = Ret (*)(Args...);
|
typedef Ret (*ptr_type)(Args...);
|
||||||
using type = std::function<Ret(Args...)>;
|
typedef std::function<Ret(Args...)> type;
|
||||||
using overwrite_type = std::function<Ret(const type &, Args...)>;
|
typedef std::function<Ret(const type &, Args...)> overwrite_type;
|
||||||
|
|
||||||
// Normal Function
|
// Normal Function
|
||||||
__Function(const char *const name_, const ptr_type func_, const ptr_type thunk_):
|
__Function(const std::string name_, const ptr_type thunk_, const ptr_type func_):
|
||||||
func(func_),
|
func(func_),
|
||||||
enabled(true),
|
enabled(true),
|
||||||
name(name_),
|
name(name_),
|
||||||
backup(func_),
|
backup(func_),
|
||||||
thunk(thunk_) {}
|
thunk(thunk_) {}
|
||||||
// Virtual Function
|
// Virtual Function
|
||||||
__Function(const char *const name_, ptr_type *const func_, void *const parent, const ptr_type thunk_):
|
template <typename Parent>
|
||||||
|
__Function(const std::string name_, const ptr_type thunk_, ptr_type *const func_, const Parent parent):
|
||||||
func(__VirtualFunctionInfo(func_, parent)),
|
func(__VirtualFunctionInfo(func_, parent)),
|
||||||
enabled(std::get<__VirtualFunctionInfo<ptr_type>>(func).can_overwrite()),
|
enabled(std::get<__VirtualFunctionInfo>(func).can_overwrite()),
|
||||||
name(name_),
|
name(name_),
|
||||||
backup(*get_vtable_addr()),
|
backup(*get_vtable_addr()),
|
||||||
thunk(thunk_) {}
|
thunk(thunk_) {}
|
||||||
@ -91,7 +111,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[[nodiscard]] ptr_type *get_vtable_addr() const {
|
[[nodiscard]] ptr_type *get_vtable_addr() const {
|
||||||
return std::get<__VirtualFunctionInfo<ptr_type>>(func).addr;
|
return (ptr_type *) std::get<__VirtualFunctionInfo>(func).addr;
|
||||||
}
|
}
|
||||||
[[nodiscard]] type get_thunk_target() const {
|
[[nodiscard]] type get_thunk_target() const {
|
||||||
if (thunk_target) {
|
if (thunk_target) {
|
||||||
@ -103,7 +123,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Current Function
|
// Current Function
|
||||||
std::variant<ptr_type, __VirtualFunctionInfo<ptr_type>> func;
|
std::variant<ptr_type, __VirtualFunctionInfo> func;
|
||||||
[[nodiscard]] bool is_virtual() const {
|
[[nodiscard]] bool is_virtual() const {
|
||||||
return func.index() == 1;
|
return func.index() == 1;
|
||||||
}
|
}
|
||||||
@ -111,7 +131,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
// State
|
// State
|
||||||
const bool enabled;
|
const bool enabled;
|
||||||
const char *const name;
|
const std::string name;
|
||||||
|
|
||||||
// Backup Of Original Function Pointer
|
// Backup Of Original Function Pointer
|
||||||
const ptr_type backup;
|
const ptr_type backup;
|
||||||
@ -137,16 +157,6 @@ typedef unsigned char uchar;
|
|||||||
typedef unsigned short ushort;
|
typedef unsigned short ushort;
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
|
|
||||||
// Internal Macros
|
|
||||||
#define __PREVENT_DESTRUCTION(self) \
|
|
||||||
~self() = delete
|
|
||||||
#define __PREVENT_CONSTRUCTION(self) \
|
|
||||||
self() = delete; \
|
|
||||||
__PREVENT_DESTRUCTION(self)
|
|
||||||
#define __PREVENT_COPY(self) \
|
|
||||||
self(const self &) = delete; \
|
|
||||||
self &operator=(const self &) = delete
|
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
{{ forwardDeclarations }}
|
{{ forwardDeclarations }}
|
||||||
|
|
||||||
|
@ -56,13 +56,14 @@ export class Method {
|
|||||||
out += `${type} *const ${this.getName()}`;
|
out += `${type} *const ${this.getName()}`;
|
||||||
if (code) {
|
if (code) {
|
||||||
out += ` = new ${type}(${JSON.stringify(this.getName('::'))}, `;
|
out += ` = new ${type}(${JSON.stringify(this.getName('::'))}, `;
|
||||||
|
out += `${INTERNAL}thunk<&${this.getName()}>, `;
|
||||||
if (isVirtual) {
|
if (isVirtual) {
|
||||||
const parentMethod = parentSelf ? `(void *) ${this.#getVirtualCall(parentSelf)}` : 'nullptr';
|
const parentMethod = parentSelf ? this.#getVirtualCall(parentSelf) : 'nullptr';
|
||||||
out += `&${this.#getVirtualCall()}, ${parentMethod}`;
|
out += `&${this.#getVirtualCall()}, ${parentMethod}`;
|
||||||
} else {
|
} else {
|
||||||
out += `(${this.#getRawType()} *) ${toHex(this.address)}`;
|
out += `(${this.#getRawType()} *) ${toHex(this.address)}`;
|
||||||
}
|
}
|
||||||
out += `, ${INTERNAL}thunk<&${this.getName()}>)`;
|
out += ')';
|
||||||
}
|
}
|
||||||
out += ';\n';
|
out += ';\n';
|
||||||
return out;
|
return out;
|
||||||
|
Loading…
Reference in New Issue
Block a user