More Sanity Checks And Hexadecimal!
This commit is contained in:
parent
5e2934a399
commit
861a0ab8fe
@ -1,4 +1,5 @@
|
|||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
|
import { isCppAllowed } from './map';
|
||||||
|
|
||||||
export const INDENT = ' ';
|
export const INDENT = ' ';
|
||||||
export const POINTER_SIZE = 4;
|
export const POINTER_SIZE = 4;
|
||||||
@ -50,3 +51,23 @@ export function formatType(type: string) {
|
|||||||
return type;
|
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;
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import { INDENT, MIN_SIZE, toUpperSnakeCase, formatType, STRUCTURE_FILES } from './common';
|
import { INDENT, MIN_SIZE, formatType, STRUCTURE_FILES, toHex, getAssertFunction, assertSize } from './common';
|
||||||
import { isCppAllowed } from './map';
|
|
||||||
import { Method } from './method';
|
import { Method } from './method';
|
||||||
import { Property, StaticProperty } from './property';
|
import { Property, StaticProperty } from './property';
|
||||||
import { VTable } from './vtable';
|
import { VTable } from './vtable';
|
||||||
@ -221,25 +220,21 @@ export class Struct {
|
|||||||
out += `};\n`;
|
out += `};\n`;
|
||||||
|
|
||||||
// Sanity Check Offsets
|
// Sanity Check Offsets
|
||||||
const assertFunction = isCppAllowed() ? 'static_assert' : '_Static_assert';
|
const assertFunction = getAssertFunction();
|
||||||
for (let i = 0; i < this.#properties.length; i++) {
|
for (let i = 0; i < this.#properties.length; i++) {
|
||||||
const property = this.#properties[i]!;
|
const property = this.#properties[i]!;
|
||||||
const name = property.propertyName();
|
const name = property.propertyName();
|
||||||
const offset = property.propertyOffset();
|
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
|
// Sanity Check Size
|
||||||
const size = this.getSize();
|
const size = this.getSize();
|
||||||
out += `#define ${toUpperSnakeCase(this.#name)}_SIZE ${size}\n`;
|
const isSizeDefined = this.#size !== null;
|
||||||
out += `${assertFunction}(sizeof (${this.#name}) == ${toUpperSnakeCase(this.#name)}_SIZE, "Invalid Structure Size");\n`;
|
out += assertSize(this.#name, size, isSizeDefined);
|
||||||
if (this.#size === null) {
|
|
||||||
// Hide Structure Size As The Real Size Is Unknown
|
|
||||||
out += `#undef ${toUpperSnakeCase(this.#name)}_SIZE\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocation Function
|
// Allocation Function
|
||||||
if (this.#size !== null) {
|
if (isSizeDefined) {
|
||||||
out += `${this.#name} *alloc_${this.#name}();\n`;
|
out += `${this.#name} *alloc_${this.#name}();\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,13 +252,13 @@ export class Struct {
|
|||||||
|
|
||||||
// Static Properties
|
// Static Properties
|
||||||
for (const property of this.#staticProperties) {
|
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();
|
declarations += property.generateDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
for (const method of this.#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();
|
declarations += method.generateDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +272,7 @@ export class Struct {
|
|||||||
// Allocation Function
|
// Allocation Function
|
||||||
if (this.#size !== null) {
|
if (this.#size !== null) {
|
||||||
declarations += `${this.#name} *alloc_${this.#name}() {\n`;
|
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';
|
declarations += '}\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { INDENT, POINTER_SIZE } from './common';
|
import { INDENT, POINTER_SIZE, assertSize, toHex } from './common';
|
||||||
import { Method } from './method';
|
import { Method } from './method';
|
||||||
import { Property } from './property';
|
import { Property } from './property';
|
||||||
|
|
||||||
@ -107,6 +107,11 @@ export class VTable implements Property {
|
|||||||
}
|
}
|
||||||
out += `};\n`;
|
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
|
// Pointers
|
||||||
if (this.#address !== null) {
|
if (this.#address !== null) {
|
||||||
// Base
|
// Base
|
||||||
@ -123,7 +128,7 @@ export class VTable implements Property {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Duplication Method
|
// Duplication Method
|
||||||
if (this.#size !== null) {
|
if (isSizeDefined) {
|
||||||
out += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable);\n`;
|
out += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable);\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +147,7 @@ export class VTable implements Property {
|
|||||||
// Pointers
|
// Pointers
|
||||||
if (this.#address !== null) {
|
if (this.#address !== null) {
|
||||||
// Base
|
// 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`;
|
declarations += `${this.#getName()} *${this.#getName()}_base;\n`;
|
||||||
// Methods
|
// Methods
|
||||||
for (let i = 0; i < this.#methods.length; i++) {
|
for (let i = 0; i < this.#methods.length; i++) {
|
||||||
@ -150,7 +155,7 @@ export class VTable implements Property {
|
|||||||
if (info) {
|
if (info) {
|
||||||
const vtableAddress = this.#address + (i * POINTER_SIZE);
|
const vtableAddress = this.#address + (i * POINTER_SIZE);
|
||||||
const type = `${info.getType()} *`;
|
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`;
|
declarations += `${type}${info.getName()}_vtable_addr;\n`;
|
||||||
init += `${INDENT}${info.getName()}_non_virtual = *${info.getName()}_vtable_addr;\n`;
|
init += `${INDENT}${info.getName()}_non_virtual = *${info.getName()}_vtable_addr;\n`;
|
||||||
declarations += info.generateDefinition();
|
declarations += info.generateDefinition();
|
||||||
@ -161,11 +166,11 @@ export class VTable implements Property {
|
|||||||
// Duplication Method
|
// Duplication Method
|
||||||
if (this.#size !== null) {
|
if (this.#size !== null) {
|
||||||
declarations += `${this.#getName()} *dup_${this.#getName()}(${this.#getName()} *vtable) {\n`;
|
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}if (obj == NULL) {\n`;
|
||||||
declarations += `${INDENT}${INDENT}return NULL;\n`;
|
declarations += `${INDENT}${INDENT}return NULL;\n`;
|
||||||
declarations += `${INDENT}}\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 += `${INDENT}return obj;\n`;
|
||||||
declarations += '}\n';
|
declarations += '}\n';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user