More Sanity Checks And Hexadecimal!

This commit is contained in:
TheBrokenRail 2024-01-06 03:58:45 -05:00
parent 5e2934a399
commit 861a0ab8fe
3 changed files with 42 additions and 21 deletions

View File

@ -1,4 +1,5 @@
import * as fs from 'node:fs';
import { isCppAllowed } from './map';
export const INDENT = ' ';
export const POINTER_SIZE = 4;
@ -49,4 +50,24 @@ export function formatType(type: string) {
}
return type;
}
export const COMMENT = '//';
export const COMMENT = '//';
export function toHex(x: number) {
return '0x' + x.toString(16);
}
export function getAssertFunction() {
return isCppAllowed() ? 'static_assert' : '_Static_assert';
}
export function assertSize(name: string, size: number, isDefined: boolean) {
let out = '';
// Define Size Macro
const macro = toUpperSnakeCase(name) + '_SIZE';
out += `#define ${macro} ${toHex(size)}\n`;
// Check Size
out += `${getAssertFunction()}(sizeof (${name}) == ${macro}, "Invalid Size");\n`;
// Hide Structure Size Of The Real Size Is Unknown
if (!isDefined) {
out += `#undef ${macro}\n`;
}
// Return
return out;
}

View File

@ -1,5 +1,4 @@
import { INDENT, MIN_SIZE, toUpperSnakeCase, formatType, STRUCTURE_FILES } from './common';
import { isCppAllowed } from './map';
import { INDENT, MIN_SIZE, formatType, STRUCTURE_FILES, toHex, getAssertFunction, assertSize } from './common';
import { Method } from './method';
import { Property, StaticProperty } from './property';
import { VTable } from './vtable';
@ -221,25 +220,21 @@ export class Struct {
out += `};\n`;
// Sanity Check Offsets
const assertFunction = isCppAllowed() ? 'static_assert' : '_Static_assert';
const assertFunction = getAssertFunction();
for (let i = 0; i < this.#properties.length; i++) {
const property = this.#properties[i]!;
const name = property.propertyName();
const offset = property.propertyOffset();
out += `${assertFunction}(offsetof(${this.#name}, ${name}) == ${offset}, "Invalid Offset");\n`;
out += `${assertFunction}(offsetof(${this.#name}, ${name}) == ${toHex(offset)}, "Invalid Offset");\n`;
}
// Sanity Check Size
const size = this.getSize();
out += `#define ${toUpperSnakeCase(this.#name)}_SIZE ${size}\n`;
out += `${assertFunction}(sizeof (${this.#name}) == ${toUpperSnakeCase(this.#name)}_SIZE, "Invalid Structure Size");\n`;
if (this.#size === null) {
// Hide Structure Size As The Real Size Is Unknown
out += `#undef ${toUpperSnakeCase(this.#name)}_SIZE\n`;
}
const isSizeDefined = this.#size !== null;
out += assertSize(this.#name, size, isSizeDefined);
// Allocation Function
if (this.#size !== null) {
if (isSizeDefined) {
out += `${this.#name} *alloc_${this.#name}();\n`;
}
@ -257,13 +252,13 @@ export class Struct {
// Static Properties
for (const property of this.#staticProperties) {
init += `${INDENT}${property.getName()} = (${property.getType()}) ${property.address};\n`;
init += `${INDENT}${property.getName()} = (${property.getType()}) ${toHex(property.address)};\n`;
declarations += property.generateDefinition();
}
// Methods
for (const method of this.#methods) {
init += `${INDENT}${method.getName()} = (${method.getType()}) ${method.address};\n`;
init += `${INDENT}${method.getName()} = (${method.getType()}) ${toHex(method.address)};\n`;
declarations += method.generateDefinition();
}
@ -277,7 +272,7 @@ export class Struct {
// Allocation Function
if (this.#size !== null) {
declarations += `${this.#name} *alloc_${this.#name}() {\n`;
declarations += `${INDENT}return (${this.#name} *) ::operator new(${this.#size});\n`;
declarations += `${INDENT}return new ${this.#name};\n`;
declarations += '}\n';
}

View File

@ -1,4 +1,4 @@
import { INDENT, POINTER_SIZE } from './common';
import { INDENT, POINTER_SIZE, assertSize, toHex } from './common';
import { Method } from './method';
import { Property } from './property';
@ -107,6 +107,11 @@ export class VTable implements Property {
}
out += `};\n`;
// Sanity Check Size
const isSizeDefined = this.#size !== null;
const size = isSizeDefined ? this.#size! : (this.#methods.length * POINTER_SIZE);
out += assertSize(this.#getName(), size, isSizeDefined);
// Pointers
if (this.#address !== null) {
// Base
@ -123,7 +128,7 @@ export class VTable implements Property {
}
// Duplication Method
if (this.#size !== null) {
if (isSizeDefined) {
out += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable);\n`;
}
@ -142,7 +147,7 @@ export class VTable implements Property {
// Pointers
if (this.#address !== null) {
// Base
init += `${INDENT}${this.#getName()}_base = (${this.#getName()} *) ${this.#address};\n`;
init += `${INDENT}${this.#getName()}_base = (${this.#getName()} *) ${toHex(this.#address)};\n`;
declarations += `${this.#getName()} *${this.#getName()}_base;\n`;
// Methods
for (let i = 0; i < this.#methods.length; i++) {
@ -150,7 +155,7 @@ export class VTable implements Property {
if (info) {
const vtableAddress = this.#address + (i * POINTER_SIZE);
const type = `${info.getType()} *`;
init += `${INDENT}${info.getName()}_vtable_addr = (${type}) ${vtableAddress};\n`;
init += `${INDENT}${info.getName()}_vtable_addr = (${type}) ${toHex(vtableAddress)};\n`;
declarations += `${type}${info.getName()}_vtable_addr;\n`;
init += `${INDENT}${info.getName()}_non_virtual = *${info.getName()}_vtable_addr;\n`;
declarations += info.generateDefinition();
@ -161,11 +166,11 @@ export class VTable implements Property {
// Duplication Method
if (this.#size !== null) {
declarations += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable) {\n`;
declarations += `${INDENT}${this.#getName()} *obj = (${this.#getName()} *) malloc(${this.#size});\n`;
declarations += `${INDENT}${this.#getName()} *obj = new ${this.#getName()};\n`;
declarations += `${INDENT}if (obj == NULL) {\n`;
declarations += `${INDENT}${INDENT}return NULL;\n`;
declarations += `${INDENT}}\n`;
declarations += `${INDENT}memcpy((void *) obj, (void *) vtable, ${this.#size});\n`;
declarations += `${INDENT}memcpy((void *) obj, (void *) vtable, sizeof (${this.#getName()});\n`;
declarations += `${INDENT}return obj;\n`;
declarations += '}\n';
}