This commit is contained in:
parent
b858a2fc1a
commit
e42f46d6cc
@ -1,7 +1,11 @@
|
|||||||
// Get Custom Wrapper From Object
|
// Get Custom Wrapper From Object
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
|
Data **__custom_get(typename Data::__Self *self) {
|
||||||
|
return (Data **) (self + 1);
|
||||||
|
}
|
||||||
|
template <typename Data>
|
||||||
Data *custom_get(typename Data::__Self *self) {
|
Data *custom_get(typename Data::__Self *self) {
|
||||||
return (Data *) (self + 1);
|
return *__custom_get<Data>(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate VTable
|
// Duplicate VTable
|
||||||
@ -32,43 +36,25 @@ struct __CustomBase {
|
|||||||
// Prevent Copying
|
// Prevent Copying
|
||||||
__PREVENT_COPY(__CustomBase);
|
__PREVENT_COPY(__CustomBase);
|
||||||
|
|
||||||
#define get_self(ptr) (((__Self *) ptr) - 1)
|
|
||||||
#ifdef {{ BUILDING_SYMBOLS_GUARD }}
|
#ifdef {{ BUILDING_SYMBOLS_GUARD }}
|
||||||
// Constructor
|
// Constructor
|
||||||
__CustomBase():
|
__CustomBase():
|
||||||
self(get_self(this)) {}
|
self(__Self::allocate(sizeof(this)))
|
||||||
|
{
|
||||||
|
*__custom_get<__CustomBase>(self) = this;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
// Prevent Construction
|
// Prevent Construction
|
||||||
__PREVENT_JUST_CONSTRUCTION(__CustomBase);
|
__PREVENT_JUST_CONSTRUCTION(__CustomBase);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
// Destructor
|
// Destructor
|
||||||
virtual ~__CustomBase() = default;
|
__Self *(*__VTable::*selected_destructor)(__Self *) = &__VTable::destructor_deleting;
|
||||||
|
public:
|
||||||
// Allocation
|
virtual ~__CustomBase() {
|
||||||
void *operator new(const size_t count) {
|
(__VTable::base->*selected_destructor)(self);
|
||||||
const size_t size = sizeof(__Self) + count;
|
|
||||||
__Self *out = (__Self *) ::operator new(size);
|
|
||||||
return (void *) custom_get<__CustomBase>(out);
|
|
||||||
}
|
}
|
||||||
void *operator new[](size_t) = delete;
|
|
||||||
|
|
||||||
// Deallocation
|
|
||||||
void operator delete(__CustomBase *ptr, std::destroying_delete_t) {
|
|
||||||
if (ptr) {
|
|
||||||
__Self *self = ptr->self;
|
|
||||||
// This Calls The Actual Destructor
|
|
||||||
self->vtable->destructor_deleting(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void operator delete(void *ptr) {
|
|
||||||
if (ptr) {
|
|
||||||
// Issue During Construction, Just Free Memory
|
|
||||||
::operator delete(get_self(ptr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef get_self
|
|
||||||
void operator delete[](void *) = delete;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// VTable
|
// VTable
|
||||||
@ -76,8 +62,10 @@ protected:
|
|||||||
// Patch Destructors
|
// Patch Destructors
|
||||||
#define patch(type) \
|
#define patch(type) \
|
||||||
vtable->type = [](__Self *self) { \
|
vtable->type = [](__Self *self) { \
|
||||||
custom_get<__CustomBase>(self)->~__CustomBase(); \
|
__CustomBase *obj = custom_get<__CustomBase>(self); \
|
||||||
return __VTable::base->type(self); \
|
obj->selected_destructor = &__VTable::type; \
|
||||||
|
delete obj; \
|
||||||
|
return self; \
|
||||||
}
|
}
|
||||||
patch(destructor_complete);
|
patch(destructor_complete);
|
||||||
patch(destructor_deleting);
|
patch(destructor_deleting);
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Type Traits
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
// Internal Macros
|
// Internal Macros
|
||||||
|
@ -84,8 +84,15 @@ export class CustomWrapperGenerator {
|
|||||||
let out = '';
|
let out = '';
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
if (!structuresWithVTableAddress.includes(this.#struct.name)) {
|
const checks: { name: string, value: boolean }[] = [
|
||||||
throw new Error('Generating A Custom Wrapper Requires The VTable Address To Be Specified');
|
{name: 'VTable Address', value: structuresWithVTableAddress.includes(this.#struct.name)},
|
||||||
|
{name: 'VTable Size', value: this.#struct.getVTable().hasSize()},
|
||||||
|
{name: 'Structure Size', value: this.#struct.hasSize()}
|
||||||
|
];
|
||||||
|
for (const check of checks) {
|
||||||
|
if (!check.value) {
|
||||||
|
throw new Error('Generating A Custom Wrapper Requires The ' + check.name + ' To Be Specified');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structure
|
// Structure
|
||||||
|
@ -117,6 +117,9 @@ export class Struct {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
hasSize() {
|
||||||
|
return !!this.#size;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate Properties
|
// Generate Properties
|
||||||
#generateProperties() {
|
#generateProperties() {
|
||||||
@ -206,15 +209,15 @@ export class Struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out += '#endif\n';
|
||||||
// Allocation Method
|
// Allocation Method
|
||||||
if (this.#size !== null) {
|
if (this.hasSize()) {
|
||||||
// THIS DOES NOT CONSTRUCT THE OBJECT
|
// THIS DOES NOT CONSTRUCT THE OBJECT
|
||||||
out += `${INDENT}static ${this.name} *allocate() {\n`;
|
out += `${INDENT}static ${this.name} *allocate(const size_t extra = 0) {\n`;
|
||||||
out += `${INDENT}${INDENT}return (${this.name} *) ::operator new(sizeof(${this.name}));\n`;
|
out += `${INDENT}${INDENT}return (${this.name} *) ::operator new(sizeof(${this.name}) + extra);\n`;
|
||||||
out += `${INDENT}}\n`;
|
out += `${INDENT}}\n`;
|
||||||
}
|
}
|
||||||
// Return
|
// Return
|
||||||
out += '#endif\n';
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,9 @@ export class VTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hasSize() {
|
||||||
|
return !!this.#size;
|
||||||
|
}
|
||||||
|
|
||||||
// Get Full Methods Table
|
// Get Full Methods Table
|
||||||
getMethods(includeDestructors = true) {
|
getMethods(includeDestructors = true) {
|
||||||
@ -154,7 +157,7 @@ export class VTable {
|
|||||||
out += `${INDENT}void *${INTERNAL}unknown${i.toString()};\n`;
|
out += `${INDENT}void *${INTERNAL}unknown${i.toString()};\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.#size === null) {
|
if (!this.hasSize()) {
|
||||||
// Prevent Construction
|
// Prevent Construction
|
||||||
out += preventConstruction(this.getName());
|
out += preventConstruction(this.getName());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user