From fbb9b6d6da1a9dfa9290d420d1b2c34f91026111 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Fri, 17 May 2024 02:52:31 -0400 Subject: [PATCH] Better Static Properties --- src/common.ts | 9 +-------- src/index.ts | 20 ++++---------------- src/method.ts | 2 +- src/property.ts | 19 ++++++++++--------- src/struct.ts | 27 ++++++++++++--------------- src/vtable.ts | 40 ++++++++++++++++++---------------------- 6 files changed, 46 insertions(+), 71 deletions(-) diff --git a/src/common.ts b/src/common.ts index f9bb23a..ccbd661 100644 --- a/src/common.ts +++ b/src/common.ts @@ -66,14 +66,7 @@ export function toHex(x: number) { return '0x' + x.toString(16); } export function assertSize(name: string, size: number) { - let out = ''; - // Define Size Macro - const macro = toUpperSnakeCase(name) + '_SIZE'; - out += `#define ${macro} ${toHex(size)}\n`; - // Check Size - out += `static_assert(sizeof(${name}) == ${macro}, "Invalid Size");\n`; - // Return - return out; + return `static_assert(sizeof(${name}) == ${toHex(size)}, "Invalid Size");\n`; } export function safeParseInt(str: string) { const x = parseInt(str); diff --git a/src/index.ts b/src/index.ts index f3ff06a..f585705 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import * as fs from 'node:fs'; -import { STRUCTURE_FILES, EXTENSION, INDENT } from './common'; +import { STRUCTURE_FILES, EXTENSION } from './common'; import { getStructure } from './map'; import { Struct } from './struct'; @@ -130,11 +130,7 @@ function makeHeaderPart() { } // Return - let result = ''; - result += '// Init\n'; - result += 'void init_symbols();\n\n'; - result += structures; - return result; + return structures; } // Create Main Header @@ -180,7 +176,6 @@ function makeCompiledCode(output: string) { // Generate let declarations = ''; - let init = ''; let isFirst = true; for (const structure of structureObjects) { const name = structure.getName(); @@ -188,14 +183,11 @@ function makeCompiledCode(output: string) { isFirst = false; } else { declarations += '\n'; - init += '\n'; } declarations += `// ${name}\n`; - init += `${INDENT}// ${name}\n`; try { const code = structure.generateCode(); - declarations += code.functions; - init += code.init; + declarations += code; } catch (e) { console.log(`Error Generating Code: ${name}: ${e instanceof Error ? e.stack : e}`); process.exit(1); @@ -205,11 +197,7 @@ function makeCompiledCode(output: string) { // Write let result = ''; result += `#include "${fs.realpathSync(headerOutput)}"\n`; - result += '\n#include \n'; - result += '\n// Init\n'; - result += 'void init_symbols() {\n'; - result += init; - result += '}\n\n'; + result += '\n#include \n\n'; result += declarations; fs.writeFileSync(output, result); } diff --git a/src/method.ts b/src/method.ts index 8f7eda6..7adf953 100644 --- a/src/method.ts +++ b/src/method.ts @@ -56,7 +56,7 @@ export class Method { // Generate Variable Definition generateDefinition(nameSuffix?: string) { - return `${this.getType()} ${this.getName()}${nameSuffix !== undefined ? nameSuffix : ''};\n`; + return `${this.getType()} ${this.getName()}${nameSuffix !== undefined ? nameSuffix : ''}`; } // Generate "New Method" Test diff --git a/src/property.ts b/src/property.ts index 2798495..e3a3136 100644 --- a/src/property.ts +++ b/src/property.ts @@ -34,8 +34,14 @@ export class Property { } return name; } + #fullName(separator: string) { + return this.#self + separator + this.name(); + } fullName() { - return `${this.#self}_${this.name()}`; + return this.#fullName('_'); + } + prettyName() { + return this.#fullName('::'); } rawType() { return this.#type; @@ -48,13 +54,8 @@ export class StaticProperty extends Property { super(address, type, name, self); } - // Generate Variable Definition - globalPointerDefinition() { - return `${this.type()} *${this.fullName()}_pointer;\n`; - } - - // Generate Macro - macro() { - return `#define ${this.fullName()} (*${this.fullName()}_pointer)\n`; + // Reference + referenceDefinition(addSelf: boolean) { + return `${this.type()} &${addSelf ? this.prettyName() : this.name()}`; } } \ No newline at end of file diff --git a/src/struct.ts b/src/struct.ts index 0d0f692..1086f91 100644 --- a/src/struct.ts +++ b/src/struct.ts @@ -193,16 +193,14 @@ export class Struct { // Static Properties for (const property of this.#staticProperties) { out += property.typedef(); - out += `extern ${property.globalPointerDefinition()}`; - out += property.macro(); } // Methods for (const method of this.#methods) { if (!method.isInherited) { out += method.generateTypedef(); - out += `extern ${method.generateDefinition()}`; - out += `extern ${method.generateDefinition(ORIGINAL_SUFFIX)}`; + out += `extern ${method.generateDefinition()};\n`; + out += `extern ${method.generateDefinition(ORIGINAL_SUFFIX)};\n`; } } @@ -220,6 +218,10 @@ export class Struct { out += `struct ${this.#name} {\n`; out += this.#generateProperties(); out += this.#generateMethods(); + for (const property of this.#staticProperties) { + // Static Property References + out += `${INDENT}static ${property.referenceDefinition(false)};\n`; + } if (this.#size === null) { // Prevent Manually Copying/Allocating Structure With Undefined out += `${INDENT}${this.#name}() = delete;\n`; @@ -247,34 +249,29 @@ export class Struct { // Generate Compiled Code generateCode() { - let declarations = ''; - let init = ''; + let out = ''; // Static Properties for (const property of this.#staticProperties) { - init += `${INDENT}${property.fullName()}_pointer = (${property.type()} *) ${toHex(property.offset)};\n`; - declarations += property.globalPointerDefinition(); + out += `${property.referenceDefinition(true)} = *(${property.type()} *) ${toHex(property.offset)};\n`; } // Methods for (const method of this.#methods) { if (!method.isInherited) { - init += `${INDENT}${method.getName()} = (${method.getType()}) ${toHex(method.address)};\n`; - declarations += method.generateDefinition(); - init += `${INDENT}${method.getName()}${ORIGINAL_SUFFIX} = ${method.getName()};\n`; - declarations += method.generateDefinition(ORIGINAL_SUFFIX); + out += `${method.generateDefinition()} = (${method.getType()}) ${toHex(method.address)};\n`; + out += `${method.generateDefinition(ORIGINAL_SUFFIX)} = ${method.getName()};\n`; } } // VTable if (this.#vtable !== null) { const vtable = this.#vtable.generateCode(); - declarations += vtable.declarations; - init += vtable.init; + out += vtable; } // Return - return {functions: declarations, init}; + return out; } // Set Direct Parent (Used For "New Method" Testing) diff --git a/src/vtable.ts b/src/vtable.ts index 365e6bf..15f9596 100644 --- a/src/vtable.ts +++ b/src/vtable.ts @@ -133,7 +133,7 @@ export class VTable { const pointerType = `${type} *`; out += `extern ${pointerType}${name}_vtable_addr;\n`; out += info.generateNewMethodTest(directParent, '*', '_vtable_addr'); - out += `extern ${info.generateDefinition(ORIGINAL_SUFFIX)}`; + out += `extern ${info.generateDefinition(ORIGINAL_SUFFIX)};\n`; } } } @@ -149,8 +149,7 @@ export class VTable { // Generate Compiled Code generateCode() { - let declarations = ''; - let init = ''; + let out = ''; // Check this.#check(); @@ -158,8 +157,7 @@ export class VTable { // Pointers if (this.#address !== null) { // Base - init += `${INDENT}${this.#getName()}_base = (${this.#getName()} *) ${toHex(this.#address)};\n`; - declarations += `${this.#getName()} *${this.#getName()}_base;\n`; + out += `${this.#getName()} *${this.#getName()}_base = (${this.#getName()} *) ${toHex(this.#address)};\n`; // Methods const methods = this.getMethods(); for (let i = 0; i < methods.length; i++) { @@ -169,31 +167,29 @@ export class VTable { const name = info.getName(); const type = info.getType(); const pointerType = `${type} *`; - init += `${INDENT}${name}_vtable_addr = (${pointerType}) ${toHex(vtableAddress)};\n`; - declarations += `${pointerType}${name}_vtable_addr;\n`; - init += `${INDENT}${name}${ORIGINAL_SUFFIX} = *${name}_vtable_addr;\n`; - declarations += info.generateDefinition(ORIGINAL_SUFFIX); + out += `${pointerType}${name}_vtable_addr = (${pointerType}) ${toHex(vtableAddress)};\n`; + out += `${info.generateDefinition(ORIGINAL_SUFFIX)} = *${name}_vtable_addr;\n`; } } } // Duplication Method if (this.#size !== null) { - declarations += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable) {\n`; - declarations += `${INDENT}uchar *real_vtable = (uchar *) vtable;\n`; - declarations += `${INDENT}real_vtable -= ${RTTI_SIZE};\n`; - declarations += `${INDENT}size_t real_vtable_size = sizeof(${this.#getName()}) + ${RTTI_SIZE};\n`; - declarations += `${INDENT}uchar *new_vtable = (uchar *) ::operator new(real_vtable_size);\n`; - declarations += `${INDENT}if (new_vtable == NULL) {\n`; - declarations += `${INDENT}${INDENT}return NULL;\n`; - declarations += `${INDENT}}\n`; - declarations += `${INDENT}memcpy((void *) new_vtable, (void *) real_vtable, real_vtable_size);\n`; - declarations += `${INDENT}new_vtable += ${RTTI_SIZE};\n`; - declarations += `${INDENT}return (${this.#getName()} *) new_vtable;\n`; - declarations += '}\n'; + out += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable) {\n`; + out += `${INDENT}uchar *real_vtable = (uchar *) vtable;\n`; + out += `${INDENT}real_vtable -= ${RTTI_SIZE};\n`; + out += `${INDENT}size_t real_vtable_size = sizeof(${this.#getName()}) + ${RTTI_SIZE};\n`; + out += `${INDENT}uchar *new_vtable = (uchar *) ::operator new(real_vtable_size);\n`; + out += `${INDENT}if (new_vtable == NULL) {\n`; + out += `${INDENT}${INDENT}return NULL;\n`; + out += `${INDENT}}\n`; + out += `${INDENT}memcpy((void *) new_vtable, (void *) real_vtable, real_vtable_size);\n`; + out += `${INDENT}new_vtable += ${RTTI_SIZE};\n`; + out += `${INDENT}return (${this.#getName()} *) new_vtable;\n`; + out += '}\n'; } // Return - return {declarations, init}; + return out; } } \ No newline at end of file