Use std::vector for RPN expressions

This commit is contained in:
Rangi42
2024-02-24 12:12:19 -05:00
committed by Sylvie
parent d792ee4b61
commit 5075ac8887
4 changed files with 39 additions and 65 deletions

View File

@@ -23,8 +23,7 @@ struct Patch {
uint32_t pcSectionID; uint32_t pcSectionID;
uint32_t pcOffset; uint32_t pcOffset;
enum PatchType type; enum PatchType type;
uint32_t rpnSize; std::vector<uint8_t> rpnExpression;
uint8_t *rpnExpression;
struct Section const *pcSection; struct Section const *pcSection;
}; };

View File

@@ -248,7 +248,7 @@ static void readSymbol(FILE *file, struct Symbol *symbol,
static void readPatch(FILE *file, struct Patch *patch, char const *fileName, char const *sectName, static void readPatch(FILE *file, struct Patch *patch, char const *fileName, char const *sectName,
uint32_t i, struct FileStackNode fileNodes[]) uint32_t i, struct FileStackNode fileNodes[])
{ {
uint32_t nodeID; uint32_t nodeID, rpnSize;
enum PatchType type; enum PatchType type;
tryReadlong(nodeID, file, tryReadlong(nodeID, file,
@@ -271,18 +271,15 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s", "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s",
fileName, sectName, i); fileName, sectName, i);
patch->type = type; patch->type = type;
tryReadlong(patch->rpnSize, file, tryReadlong(rpnSize, file,
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s RPN size: %s", "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s RPN size: %s",
fileName, sectName, i); fileName, sectName, i);
patch->rpnExpression = (uint8_t *)malloc(sizeof(*patch->rpnExpression) * patch->rpnSize); patch->rpnExpression.resize(rpnSize);
if (!patch->rpnExpression) size_t nbElementsRead = fread(&patch->rpnExpression[0], sizeof(patch->rpnExpression[0]),
err("%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression", rpnSize, file);
fileName, sectName, i);
size_t nbElementsRead = fread(patch->rpnExpression, sizeof(*patch->rpnExpression),
patch->rpnSize, file);
if (nbElementsRead != patch->rpnSize) if (nbElementsRead != rpnSize)
errx("%s: Cannot read \"%s\"'s patch #%" PRIu32 "'s RPN expression: %s", errx("%s: Cannot read \"%s\"'s patch #%" PRIu32 "'s RPN expression: %s",
fileName, sectName, i, fileName, sectName, i,
feof(file) ? "Unexpected end of file" : strerror(errno)); feof(file) ? "Unexpected end of file" : strerror(errno));
@@ -668,8 +665,6 @@ static void freeSection(struct Section *section)
free(section->name); free(section->name);
if (sect_HasData(section->type)) { if (sect_HasData(section->type)) {
free(section->data); free(section->data);
for (struct Patch &patch : *section->patches)
free(patch.rpnExpression);
delete section->patches; delete section->patches;
} }
free(section->symbols); free(section->symbols);
@@ -706,8 +701,6 @@ void obj_Cleanup(void)
free(list.symbolList); free(list.symbolList);
} }
for (struct Assertion &assert : assertions) { for (struct Assertion &assert : assertions)
free(assert.patch.rpnExpression);
free(assert.message); free(assert.message);
} }
}

View File

@@ -83,8 +83,8 @@ static int32_t computeRPNExpr(struct Patch const *patch,
// Small shortcut to avoid a lot of repetition // Small shortcut to avoid a lot of repetition
#define popRPN() popRPN(patch->src, patch->lineNo) #define popRPN() popRPN(patch->src, patch->lineNo)
uint8_t const *expression = patch->rpnExpression; uint8_t const *expression = &patch->rpnExpression[0];
int32_t size = patch->rpnSize; int32_t size = (int32_t)patch->rpnExpression.size();
rpnStack.clear(); rpnStack.clear();

View File

@@ -598,14 +598,6 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
for (uint8_t i = 0; i < nbBaseBytes; ++i) for (uint8_t i = 0; i < nbBaseBytes; ++i)
baseValue = baseValue | data[offset + i] << (8 * i); baseValue = baseValue | data[offset + i] << (8 * i);
// Extra size that must be reserved for additional operators
#define RPN_EXTRA_SIZE (5 + 1 + 5 + 1 + 5 + 1) // >> 8 & $FF, then + <baseValue>
#define allocPatch(size) do { \
patch.rpnSize = (size); \
patch.rpnExpression = (uint8_t *)malloc(patch.rpnSize + RPN_EXTRA_SIZE); \
if (!patch.rpnExpression) \
fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno)); \
} while (0)
// Bit 4 specifies signedness, but I don't think that matters? // Bit 4 specifies signedness, but I don't think that matters?
// Generate a RPN expression from the info and flags // Generate a RPN expression from the info and flags
if (flags & 1 << RELOC_ISSYM) { if (flags & 1 << RELOC_ISSYM) {
@@ -626,22 +618,22 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
if (idx == nbSymbols) if (idx == nbSymbols)
fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"", fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"",
sym->name, &sym->name[1]); sym->name, &sym->name[1]);
allocPatch(5); patch.rpnExpression.resize(5);
patch.rpnExpression[0] = RPN_BANK_SYM; patch.rpnExpression[0] = RPN_BANK_SYM;
patch.rpnExpression[1] = idx; patch.rpnExpression[1] = idx;
patch.rpnExpression[2] = idx >> 8; patch.rpnExpression[2] = idx >> 8;
patch.rpnExpression[3] = idx >> 16; patch.rpnExpression[3] = idx >> 16;
patch.rpnExpression[4] = idx >> 24; patch.rpnExpression[4] = idx >> 24;
} else if (sym->name[0] == 'l' && sym->name[1] == '_') { } else if (sym->name[0] == 'l' && sym->name[1] == '_') {
allocPatch(1 + strlen(&sym->name[2]) + 1); patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1);
patch.rpnExpression[0] = RPN_SIZEOF_SECT; patch.rpnExpression[0] = RPN_SIZEOF_SECT;
strcpy((char *)&patch.rpnExpression[1], &sym->name[2]); strcpy((char *)&patch.rpnExpression[1], &sym->name[2]);
} else if (sym->name[0] == 's' && sym->name[1] == '_') { } else if (sym->name[0] == 's' && sym->name[1] == '_') {
allocPatch(1 + strlen(&sym->name[2]) + 1); patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1);
patch.rpnExpression[0] = RPN_STARTOF_SECT; patch.rpnExpression[0] = RPN_STARTOF_SECT;
strcpy((char *)&patch.rpnExpression[1], &sym->name[2]); strcpy((char *)&patch.rpnExpression[1], &sym->name[2]);
} else { } else {
allocPatch(5); patch.rpnExpression.resize(5);
patch.rpnExpression[0] = RPN_SYM; patch.rpnExpression[0] = RPN_SYM;
patch.rpnExpression[1] = idx; patch.rpnExpression[1] = idx;
patch.rpnExpression[2] = idx >> 8; patch.rpnExpression[2] = idx >> 8;
@@ -674,25 +666,18 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
// current size. // current size.
if (other) if (other)
baseValue += other->size; baseValue += other->size;
allocPatch(1 + strlen(name) + 1); patch.rpnExpression.resize(1 + strlen(name) + 1);
patch.rpnSize = 1 + strlen(name) + 1;
patch.rpnExpression = (uint8_t *)malloc(patch.rpnSize + RPN_EXTRA_SIZE);
if (!patch.rpnExpression)
fatal(where, lineNo, "Failed to alloc RPN expression: %s",
strerror(errno));
patch.rpnExpression[0] = RPN_STARTOF_SECT; patch.rpnExpression[0] = RPN_STARTOF_SECT;
// The cast is fine, it's just different signedness // The cast is fine, it's just different signedness
strcpy((char *)&patch.rpnExpression[1], name); strcpy((char *)&patch.rpnExpression[1], name);
} }
#undef allocPatch
patch.rpnExpression[patch.rpnSize] = RPN_CONST; patch.rpnExpression.push_back(RPN_CONST);
patch.rpnExpression[patch.rpnSize + 1] = baseValue; patch.rpnExpression.push_back(baseValue);
patch.rpnExpression[patch.rpnSize + 2] = baseValue >> 8; patch.rpnExpression.push_back(baseValue >> 8);
patch.rpnExpression[patch.rpnSize + 3] = baseValue >> 16; patch.rpnExpression.push_back(baseValue >> 16);
patch.rpnExpression[patch.rpnSize + 4] = baseValue >> 24; patch.rpnExpression.push_back(baseValue >> 24);
patch.rpnExpression[patch.rpnSize + 5] = RPN_ADD; patch.rpnExpression.push_back(RPN_ADD);
patch.rpnSize += 5 + 1;
if (patch.type == PATCHTYPE_BYTE) { if (patch.type == PATCHTYPE_BYTE) {
// Despite the flag's name, as soon as it is set, 3 bytes // Despite the flag's name, as soon as it is set, 3 bytes
@@ -713,30 +698,27 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
patch.type = PATCHTYPE_JR; patch.type = PATCHTYPE_JR;
// TODO: check the other flags? // TODO: check the other flags?
} else if (flags & 1 << RELOC_EXPR24 && flags & 1 << RELOC_BANKBYTE) { } else if (flags & 1 << RELOC_EXPR24 && flags & 1 << RELOC_BANKBYTE) {
patch.rpnExpression[patch.rpnSize] = RPN_CONST; patch.rpnExpression.push_back(RPN_CONST);
patch.rpnExpression[patch.rpnSize + 1] = 16; patch.rpnExpression.push_back(16);
patch.rpnExpression[patch.rpnSize + 2] = 16 >> 8; patch.rpnExpression.push_back(16 >> 8);
patch.rpnExpression[patch.rpnSize + 3] = 16 >> 16; patch.rpnExpression.push_back(16 >> 16);
patch.rpnExpression[patch.rpnSize + 4] = 16 >> 24; patch.rpnExpression.push_back(16 >> 24);
patch.rpnExpression[patch.rpnSize + 5] = (flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR; patch.rpnExpression.push_back((flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR);
patch.rpnSize += 5 + 1;
} else { } else {
if (flags & 1 << RELOC_EXPR16 && flags & 1 << RELOC_WHICHBYTE) { if (flags & 1 << RELOC_EXPR16 && flags & 1 << RELOC_WHICHBYTE) {
patch.rpnExpression[patch.rpnSize] = RPN_CONST; patch.rpnExpression.push_back(RPN_CONST);
patch.rpnExpression[patch.rpnSize + 1] = 8; patch.rpnExpression.push_back(8);
patch.rpnExpression[patch.rpnSize + 2] = 8 >> 8; patch.rpnExpression.push_back(8 >> 8);
patch.rpnExpression[patch.rpnSize + 3] = 8 >> 16; patch.rpnExpression.push_back(8 >> 16);
patch.rpnExpression[patch.rpnSize + 4] = 8 >> 24; patch.rpnExpression.push_back(8 >> 24);
patch.rpnExpression[patch.rpnSize + 5] = (flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR; patch.rpnExpression.push_back((flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR);
patch.rpnSize += 5 + 1;
} }
patch.rpnExpression[patch.rpnSize] = RPN_CONST; patch.rpnExpression.push_back(RPN_CONST);
patch.rpnExpression[patch.rpnSize + 1] = 0xFF; patch.rpnExpression.push_back(0xFF);
patch.rpnExpression[patch.rpnSize + 2] = 0xFF >> 8; patch.rpnExpression.push_back(0xFF >> 8);
patch.rpnExpression[patch.rpnSize + 3] = 0xFF >> 16; patch.rpnExpression.push_back(0xFF >> 16);
patch.rpnExpression[patch.rpnSize + 4] = 0xFF >> 24; patch.rpnExpression.push_back(0xFF >> 24);
patch.rpnExpression[patch.rpnSize + 5] = RPN_AND; patch.rpnExpression.push_back(RPN_AND);
patch.rpnSize += 5 + 1;
} }
} else if (flags & 1 << RELOC_ISPCREL) { } else if (flags & 1 << RELOC_ISPCREL) {
assert(patch.type == PATCHTYPE_WORD); assert(patch.type == PATCHTYPE_WORD);