mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Refactor to avoid redundant obj_CheckAssertions function
This commit is contained in:
@@ -10,11 +10,6 @@
|
|||||||
*/
|
*/
|
||||||
void obj_ReadFile(char const *fileName, unsigned int i);
|
void obj_ReadFile(char const *fileName, unsigned int i);
|
||||||
|
|
||||||
/*
|
|
||||||
* Evaluate all assertions
|
|
||||||
*/
|
|
||||||
void obj_CheckAssertions();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets up object file reading
|
* Sets up object file reading
|
||||||
* @param nbFiles The number of object files that will be read
|
* @param nbFiles The number of object files that will be read
|
||||||
|
|||||||
@@ -3,26 +3,11 @@
|
|||||||
#ifndef RGBDS_LINK_PATCH_H
|
#ifndef RGBDS_LINK_PATCH_H
|
||||||
#define RGBDS_LINK_PATCH_H
|
#define RGBDS_LINK_PATCH_H
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
|
|
||||||
#include "link/section.hpp"
|
|
||||||
|
|
||||||
struct Assertion {
|
|
||||||
Patch patch; // Also used for its `.type`
|
|
||||||
std::string message;
|
|
||||||
// This would be redundant with `.section->fileSymbols`, but `section` is sometimes `nullptr`!
|
|
||||||
std::vector<Symbol> *fileSymbols;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checks all assertions
|
* Checks all assertions
|
||||||
* @return true if assertion failed
|
* @return true if assertion failed
|
||||||
*/
|
*/
|
||||||
void patch_CheckAssertions(std::deque<Assertion> &assertions);
|
void patch_CheckAssertions();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Applies all SECTIONs' patches to them
|
* Applies all SECTIONs' patches to them
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
// GUIDELINE: external code MUST NOT BE AWARE of the data structure used!
|
// GUIDELINE: external code MUST NOT BE AWARE of the data structure used!
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
#include "linkdefs.hpp"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
#include "link/main.hpp"
|
#include "link/main.hpp"
|
||||||
|
#include "link/patch.hpp"
|
||||||
|
|
||||||
struct FileStackNode;
|
struct FileStackNode;
|
||||||
struct Section;
|
struct Section;
|
||||||
@@ -53,6 +55,15 @@ struct Section {
|
|||||||
std::unique_ptr<Section> nextu; // The next "component" of this unionized sect
|
std::unique_ptr<Section> nextu; // The next "component" of this unionized sect
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Assertion {
|
||||||
|
Patch patch; // Also used for its `.type`
|
||||||
|
std::string message;
|
||||||
|
// This would be redundant with `.section->fileSymbols`, but `section` is sometimes `nullptr`!
|
||||||
|
std::vector<Symbol> *fileSymbols;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::deque<Assertion> assertions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute a callback for each section currently registered.
|
* Execute a callback for each section currently registered.
|
||||||
* This is to avoid exposing the data structure in which sections are stored.
|
* This is to avoid exposing the data structure in which sections are stored.
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (nbErrors != 0)
|
if (nbErrors != 0)
|
||||||
reportErrors();
|
reportErrors();
|
||||||
assign_AssignSections();
|
assign_AssignSections();
|
||||||
obj_CheckAssertions();
|
patch_CheckAssertions();
|
||||||
|
|
||||||
// and finally output the result.
|
// and finally output the result.
|
||||||
patch_ApplyPatches();
|
patch_ApplyPatches();
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
static std::deque<std::vector<Symbol>> symbolLists;
|
static std::deque<std::vector<Symbol>> symbolLists;
|
||||||
static std::vector<std::vector<FileStackNode>> nodes;
|
static std::vector<std::vector<FileStackNode>> nodes;
|
||||||
static std::deque<Assertion> assertions;
|
|
||||||
|
|
||||||
// Helper functions for reading object files
|
// Helper functions for reading object files
|
||||||
|
|
||||||
@@ -632,10 +631,6 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void obj_CheckAssertions() {
|
|
||||||
patch_CheckAssertions(assertions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void obj_Setup(unsigned int nbFiles) {
|
void obj_Setup(unsigned int nbFiles) {
|
||||||
nodes.resize(nbFiles);
|
nodes.resize(nbFiles);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,20 +3,29 @@
|
|||||||
#include "link/patch.hpp"
|
#include "link/patch.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <deque>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "opmath.hpp"
|
#include "opmath.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
|
||||||
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
|
#include "link/main.hpp"
|
||||||
#include "link/object.hpp"
|
#include "link/object.hpp"
|
||||||
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.hpp"
|
#include "link/symbol.hpp"
|
||||||
|
|
||||||
|
std::deque<Assertion> assertions;
|
||||||
|
|
||||||
struct RPNStackEntry {
|
struct RPNStackEntry {
|
||||||
int32_t value;
|
int32_t value;
|
||||||
bool errorFlag; // Whether the value is a placeholder inserted for error recovery
|
bool errorFlag; // Whether the value is a placeholder inserted for error recovery
|
||||||
@@ -88,10 +97,6 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
// So, if there are two `popRPN` in the same expression, make
|
// So, if there are two `popRPN` in the same expression, make
|
||||||
// sure the operation is commutative.
|
// sure the operation is commutative.
|
||||||
switch (command) {
|
switch (command) {
|
||||||
Symbol const *symbol;
|
|
||||||
char const *name;
|
|
||||||
Section const *sect;
|
|
||||||
|
|
||||||
case RPN_ADD:
|
case RPN_ADD:
|
||||||
value = popRPN(patch) + popRPN(patch);
|
value = popRPN(patch) + popRPN(patch);
|
||||||
break;
|
break;
|
||||||
@@ -207,9 +212,8 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
value = 0;
|
value = 0;
|
||||||
for (uint8_t shift = 0; shift < 32; shift += 8)
|
for (uint8_t shift = 0; shift < 32; shift += 8)
|
||||||
value |= getRPNByte(expression, size, patch) << shift;
|
value |= getRPNByte(expression, size, patch) << shift;
|
||||||
symbol = getSymbol(fileSymbols, value);
|
|
||||||
|
|
||||||
if (!symbol) {
|
if (Symbol const *symbol = getSymbol(fileSymbols, value); !symbol) {
|
||||||
error(
|
error(
|
||||||
patch.src,
|
patch.src,
|
||||||
patch.lineNo,
|
patch.lineNo,
|
||||||
@@ -232,16 +236,14 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RPN_BANK_SECT:
|
case RPN_BANK_SECT: {
|
||||||
// `expression` is not guaranteed to be '\0'-terminated. If it is not,
|
// `expression` is not guaranteed to be '\0'-terminated. If it is not,
|
||||||
// `getRPNByte` will have a fatal internal error.
|
// `getRPNByte` will have a fatal internal error.
|
||||||
name = (char const *)expression;
|
char const *name = (char const *)expression;
|
||||||
while (getRPNByte(expression, size, patch))
|
while (getRPNByte(expression, size, patch))
|
||||||
;
|
;
|
||||||
|
|
||||||
sect = sect_GetSection(name);
|
if (Section const *sect = sect_GetSection(name); !sect) {
|
||||||
|
|
||||||
if (!sect) {
|
|
||||||
error(
|
error(
|
||||||
patch.src,
|
patch.src,
|
||||||
patch.lineNo,
|
patch.lineNo,
|
||||||
@@ -254,6 +256,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
value = sect->bank;
|
value = sect->bank;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RPN_BANK_SELF:
|
case RPN_BANK_SELF:
|
||||||
if (!patch.pcSection) {
|
if (!patch.pcSection) {
|
||||||
@@ -265,15 +268,13 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RPN_SIZEOF_SECT:
|
case RPN_SIZEOF_SECT: {
|
||||||
// This has assumptions commented in the `RPN_BANK_SECT` case above.
|
// This has assumptions commented in the `RPN_BANK_SECT` case above.
|
||||||
name = (char const *)expression;
|
char const *name = (char const *)expression;
|
||||||
while (getRPNByte(expression, size, patch))
|
while (getRPNByte(expression, size, patch))
|
||||||
;
|
;
|
||||||
|
|
||||||
sect = sect_GetSection(name);
|
if (Section const *sect = sect_GetSection(name); !sect) {
|
||||||
|
|
||||||
if (!sect) {
|
|
||||||
error(
|
error(
|
||||||
patch.src,
|
patch.src,
|
||||||
patch.lineNo,
|
patch.lineNo,
|
||||||
@@ -286,17 +287,15 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
value = sect->size;
|
value = sect->size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RPN_STARTOF_SECT:
|
case RPN_STARTOF_SECT: {
|
||||||
// This has assumptions commented in the `RPN_BANK_SECT` case above.
|
// This has assumptions commented in the `RPN_BANK_SECT` case above.
|
||||||
name = (char const *)expression;
|
char const *name = (char const *)expression;
|
||||||
while (getRPNByte(expression, size, patch))
|
while (getRPNByte(expression, size, patch))
|
||||||
;
|
;
|
||||||
|
|
||||||
sect = sect_GetSection(name);
|
if (Section const *sect = sect_GetSection(name); !sect) {
|
||||||
assert(sect->offset == 0);
|
|
||||||
|
|
||||||
if (!sect) {
|
|
||||||
error(
|
error(
|
||||||
patch.src,
|
patch.src,
|
||||||
patch.lineNo,
|
patch.lineNo,
|
||||||
@@ -306,9 +305,11 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
isError = true;
|
isError = true;
|
||||||
value = 1;
|
value = 1;
|
||||||
} else {
|
} else {
|
||||||
|
assert(sect->offset == 0);
|
||||||
value = sect->org;
|
value = sect->org;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RPN_SIZEOF_SECTTYPE:
|
case RPN_SIZEOF_SECTTYPE:
|
||||||
value = getRPNByte(expression, size, patch);
|
value = getRPNByte(expression, size, patch);
|
||||||
@@ -373,9 +374,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
value = patch.pcOffset + patch.pcSection->org;
|
value = patch.pcOffset + patch.pcSection->org;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
symbol = getSymbol(fileSymbols, value);
|
if (Symbol const *symbol = getSymbol(fileSymbols, value); !symbol) {
|
||||||
|
|
||||||
if (!symbol) {
|
|
||||||
error(
|
error(
|
||||||
patch.src,
|
patch.src,
|
||||||
patch.lineNo,
|
patch.lineNo,
|
||||||
@@ -403,7 +402,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
return popRPN(patch);
|
return popRPN(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_CheckAssertions(std::deque<Assertion> &assertions) {
|
void patch_CheckAssertions() {
|
||||||
verbosePrint("Checking assertions...\n");
|
verbosePrint("Checking assertions...\n");
|
||||||
|
|
||||||
for (Assertion &assert : assertions) {
|
for (Assertion &assert : assertions) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "link/section.hpp"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <deque>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user