diff --git a/data/custom.h b/data/custom.h index 0338260..849c503 100644 --- a/data/custom.h +++ b/data/custom.h @@ -1,7 +1,11 @@ // Get Custom Wrapper From Object template +Data **__custom_get(typename Data::__Self *self) { + return (Data **) (self + 1); +} +template Data *custom_get(typename Data::__Self *self) { - return (Data *) (self + 1); + return *__custom_get(self); } // Duplicate VTable @@ -32,43 +36,25 @@ struct __CustomBase { // Prevent Copying __PREVENT_COPY(__CustomBase); -#define get_self(ptr) (((__Self *) ptr) - 1) #ifdef {{ BUILDING_SYMBOLS_GUARD }} // Constructor __CustomBase(): - self(get_self(this)) {} + self(__Self::allocate(sizeof(this))) + { + *__custom_get<__CustomBase>(self) = this; + } #else // Prevent Construction __PREVENT_JUST_CONSTRUCTION(__CustomBase); #endif +private: // Destructor - virtual ~__CustomBase() = default; - - // Allocation - void *operator new(const size_t count) { - const size_t size = sizeof(__Self) + count; - __Self *out = (__Self *) ::operator new(size); - return (void *) custom_get<__CustomBase>(out); + __Self *(*__VTable::*selected_destructor)(__Self *) = &__VTable::destructor_deleting; +public: + virtual ~__CustomBase() { + (__VTable::base->*selected_destructor)(self); } - 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: // VTable @@ -76,8 +62,10 @@ protected: // Patch Destructors #define patch(type) \ vtable->type = [](__Self *self) { \ - custom_get<__CustomBase>(self)->~__CustomBase(); \ - return __VTable::base->type(self); \ + __CustomBase *obj = custom_get<__CustomBase>(self); \ + obj->selected_destructor = &__VTable::type; \ + delete obj; \ + return self; \ } patch(destructor_complete); patch(destructor_deleting); diff --git a/data/out.h b/data/out.h index c287e0b..417edf1 100644 --- a/data/out.h +++ b/data/out.h @@ -1,3 +1,6 @@ +#pragma once + +// Type Traits #include // Internal Macros diff --git a/src/custom.ts b/src/custom.ts index 33295dd..1f5f6b3 100644 --- a/src/custom.ts +++ b/src/custom.ts @@ -84,8 +84,15 @@ export class CustomWrapperGenerator { let out = ''; // Check - if (!structuresWithVTableAddress.includes(this.#struct.name)) { - throw new Error('Generating A Custom Wrapper Requires The VTable Address To Be Specified'); + const checks: { name: string, value: boolean }[] = [ + {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 diff --git a/src/struct.ts b/src/struct.ts index e2387bd..e254aee 100644 --- a/src/struct.ts +++ b/src/struct.ts @@ -117,6 +117,9 @@ export class Struct { } return out; } + hasSize() { + return !!this.#size; + } // Generate Properties #generateProperties() { @@ -206,15 +209,15 @@ export class Struct { } } } + out += '#endif\n'; // Allocation Method - if (this.#size !== null) { + if (this.hasSize()) { // THIS DOES NOT CONSTRUCT THE OBJECT - out += `${INDENT}static ${this.name} *allocate() {\n`; - out += `${INDENT}${INDENT}return (${this.name} *) ::operator new(sizeof(${this.name}));\n`; + out += `${INDENT}static ${this.name} *allocate(const size_t extra = 0) {\n`; + out += `${INDENT}${INDENT}return (${this.name} *) ::operator new(sizeof(${this.name}) + extra);\n`; out += `${INDENT}}\n`; } // Return - out += '#endif\n'; return out; } diff --git a/src/vtable.ts b/src/vtable.ts index dcbb4fa..f1e45d5 100644 --- a/src/vtable.ts +++ b/src/vtable.ts @@ -74,6 +74,9 @@ export class VTable { } } } + hasSize() { + return !!this.#size; + } // Get Full Methods Table getMethods(includeDestructors = true) { @@ -154,7 +157,7 @@ export class VTable { out += `${INDENT}void *${INTERNAL}unknown${i.toString()};\n`; } } - if (this.#size === null) { + if (!this.hasSize()) { // Prevent Construction out += preventConstruction(this.getName()); }