mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use new hashmap implementation for symbols
This commit is contained in:
@@ -34,7 +34,6 @@ extern uint32_t unionStart[MAXUNIONS];
|
|||||||
extern uint32_t unionSize[MAXUNIONS];
|
extern uint32_t unionSize[MAXUNIONS];
|
||||||
extern char tzCurrentFileName[_MAX_PATH + 1];
|
extern char tzCurrentFileName[_MAX_PATH + 1];
|
||||||
extern struct Section *pCurrentSection;
|
extern struct Section *pCurrentSection;
|
||||||
extern struct sSymbol *tHashedSymbols[HASHSIZE];
|
|
||||||
extern struct sSymbol *pPCSymbol;
|
extern struct sSymbol *pPCSymbol;
|
||||||
extern bool oDontExpandStrings;
|
extern bool oDontExpandStrings;
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ struct sSymbol {
|
|||||||
enum SymbolType type;
|
enum SymbolType type;
|
||||||
bool isExported; /* Whether the symbol is to be exported */
|
bool isExported; /* Whether the symbol is to be exported */
|
||||||
bool isBuiltin; /* Whether the symbol is a built-in */
|
bool isBuiltin; /* Whether the symbol is a built-in */
|
||||||
bool isReferenced; /* Whether the symbol is referenced in a RPN expr */
|
|
||||||
struct sSymbol *pScope;
|
struct sSymbol *pScope;
|
||||||
struct sSymbol *pNext;
|
|
||||||
struct Section *pSection;
|
struct Section *pSection;
|
||||||
int32_t nValue;
|
int32_t nValue;
|
||||||
uint32_t ulMacroSize;
|
uint32_t ulMacroSize;
|
||||||
@@ -44,6 +42,9 @@ struct sSymbol {
|
|||||||
int32_t (*Callback)(struct sSymbol const *self);
|
int32_t (*Callback)(struct sSymbol const *self);
|
||||||
char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */
|
char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */
|
||||||
uint32_t nFileLine; /* Line where the symbol was defined. */
|
uint32_t nFileLine; /* Line where the symbol was defined. */
|
||||||
|
|
||||||
|
uint32_t ID; /* ID of the symbol in the object file (-1 if none) */
|
||||||
|
struct sSymbol *next; /* Next object to output in the object file */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool sym_IsDefined(struct sSymbol const *sym)
|
static inline bool sym_IsDefined(struct sSymbol const *sym)
|
||||||
@@ -87,8 +88,9 @@ static inline char *sym_GetStringValue(struct sSymbol const *sym)
|
|||||||
return sym->pMacro;
|
return sym->pMacro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sym_ForEach(void (*func)(struct sSymbol *, void *), void *arg);
|
||||||
|
|
||||||
int32_t sym_GetValue(struct sSymbol const *sym);
|
int32_t sym_GetValue(struct sSymbol const *sym);
|
||||||
uint32_t sym_CalcHash(const char *s);
|
|
||||||
void sym_SetExportAll(bool set);
|
void sym_SetExportAll(bool set);
|
||||||
struct sSymbol *sym_AddLocalReloc(char const *tzSym);
|
struct sSymbol *sym_AddLocalReloc(char const *tzSym);
|
||||||
struct sSymbol *sym_AddReloc(char const *tzSym);
|
struct sSymbol *sym_AddReloc(char const *tzSym);
|
||||||
|
|||||||
174
src/asm/output.c
174
src/asm/output.c
@@ -40,13 +40,6 @@ struct Patch {
|
|||||||
struct Patch *pNext;
|
struct Patch *pNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatchSymbol {
|
|
||||||
uint32_t ID;
|
|
||||||
struct sSymbol const *pSymbol;
|
|
||||||
struct PatchSymbol *pNext;
|
|
||||||
struct PatchSymbol *pBucketNext; /* next symbol in hash table bucket */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Assertion {
|
struct Assertion {
|
||||||
struct Patch *patch;
|
struct Patch *patch;
|
||||||
struct Section *section;
|
struct Section *section;
|
||||||
@@ -54,29 +47,17 @@ struct Assertion {
|
|||||||
struct Assertion *next;
|
struct Assertion *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
|
|
||||||
struct Section *pSectionList, *pCurrentSection;
|
|
||||||
struct PatchSymbol *pPatchSymbols;
|
|
||||||
struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols;
|
|
||||||
struct Assertion *assertions = NULL;
|
|
||||||
char *tzObjectname;
|
char *tzObjectname;
|
||||||
|
|
||||||
/*
|
/* TODO: shouldn't `pCurrentSection` be somewhere else? */
|
||||||
* Count the number of symbols used in this object
|
struct Section *pSectionList, *pCurrentSection;
|
||||||
*/
|
|
||||||
static uint32_t countsymbols(void)
|
|
||||||
{
|
|
||||||
struct PatchSymbol *pSym;
|
|
||||||
uint32_t count = 0;
|
|
||||||
|
|
||||||
pSym = pPatchSymbols;
|
/* Linked list of symbols to put in the object file */
|
||||||
while (pSym) {
|
static struct sSymbol *objectSymbols = NULL;
|
||||||
count++;
|
static struct sSymbol **objectSymbolsTail = &objectSymbols;
|
||||||
pSym = pSym->pNext;
|
static uint32_t nbSymbols = 0; /* Length of the above list */
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
static struct Assertion *assertions = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count the number of sections used in this object
|
* Count the number of sections used in this object
|
||||||
@@ -236,10 +217,8 @@ static void writesymbol(struct sSymbol const *pSym, FILE *f)
|
|||||||
break;
|
break;
|
||||||
case SYMTYPE_EXPORT:
|
case SYMTYPE_EXPORT:
|
||||||
offset = pSym->nValue;
|
offset = pSym->nValue;
|
||||||
if (pSym->type != SYM_LABEL)
|
sectid = pSym->type == SYM_LABEL ? getsectid(pSym->pSection)
|
||||||
sectid = -1;
|
: -1;
|
||||||
else
|
|
||||||
sectid = getsectid(pSym->pSection);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,58 +235,18 @@ static void writesymbol(struct sSymbol const *pSym, FILE *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a symbol to the object
|
* Returns a symbol's ID within the object file
|
||||||
|
* If the symbol does not have one, one is assigned by registering the symbol
|
||||||
*/
|
*/
|
||||||
static uint32_t nextID;
|
static uint32_t getSymbolID(struct sSymbol *sym)
|
||||||
|
|
||||||
static uint32_t addsymbol(struct sSymbol const *pSym)
|
|
||||||
{
|
{
|
||||||
struct PatchSymbol *pPSym, **ppPSym;
|
if (sym->ID == -1) {
|
||||||
uint32_t hash;
|
sym->ID = nbSymbols++;
|
||||||
|
|
||||||
hash = sym_CalcHash(pSym->tzName);
|
*objectSymbolsTail = sym;
|
||||||
ppPSym = &(tHashedPatchSymbols[hash]);
|
objectSymbolsTail = &sym->next;
|
||||||
|
|
||||||
while ((*ppPSym) != NULL) {
|
|
||||||
if (pSym == (*ppPSym)->pSymbol)
|
|
||||||
return (*ppPSym)->ID;
|
|
||||||
ppPSym = &((*ppPSym)->pBucketNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
pPSym = malloc(sizeof(struct PatchSymbol));
|
|
||||||
*ppPSym = pPSym;
|
|
||||||
|
|
||||||
if (pPSym == NULL)
|
|
||||||
fatalerror("No memory for patchsymbol");
|
|
||||||
|
|
||||||
pPSym->pNext = NULL;
|
|
||||||
pPSym->pBucketNext = NULL;
|
|
||||||
pPSym->pSymbol = pSym;
|
|
||||||
pPSym->ID = nextID++;
|
|
||||||
|
|
||||||
*ppPatchSymbolsTail = pPSym;
|
|
||||||
ppPatchSymbolsTail = &(pPSym->pNext);
|
|
||||||
|
|
||||||
return pPSym->ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add all exported symbols to the object
|
|
||||||
*/
|
|
||||||
static void addexports(void)
|
|
||||||
{
|
|
||||||
int32_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < HASHSIZE; i++) {
|
|
||||||
struct sSymbol *pSym;
|
|
||||||
|
|
||||||
pSym = tHashedSymbols[i];
|
|
||||||
while (pSym) {
|
|
||||||
if (pSym->isExported)
|
|
||||||
addsymbol(pSym);
|
|
||||||
pSym = pSym->pNext;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return sym->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
||||||
@@ -330,63 +269,46 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
|||||||
break;
|
break;
|
||||||
case RPN_SYM:
|
case RPN_SYM:
|
||||||
{
|
{
|
||||||
uint32_t symptr = 0;
|
for (unsigned int i = -1; (tzSym[++i] = popbyte()); )
|
||||||
|
|
||||||
while ((tzSym[symptr++] = popbyte()) != 0)
|
|
||||||
;
|
;
|
||||||
|
struct sSymbol *sym = sym_FindSymbol(tzSym);
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
struct sSymbol const *sym = sym_FindSymbol(tzSym);
|
if (sym_IsConstant(sym)) {
|
||||||
|
|
||||||
if (!sym) {
|
|
||||||
break; // TODO: wtf?
|
|
||||||
} else if (sym_IsConstant(sym)) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
value = sym_GetConstantValue(tzSym);
|
|
||||||
writebyte(RPN_CONST);
|
writebyte(RPN_CONST);
|
||||||
writebyte(value & 0xFF);
|
value = sym_GetConstantValue(tzSym);
|
||||||
writebyte(value >> 8);
|
|
||||||
writebyte(value >> 16);
|
|
||||||
writebyte(value >> 24);
|
|
||||||
} else {
|
} else {
|
||||||
symptr = addsymbol(sym);
|
|
||||||
writebyte(RPN_SYM);
|
writebyte(RPN_SYM);
|
||||||
writebyte(symptr & 0xFF);
|
value = getSymbolID(sym);
|
||||||
writebyte(symptr >> 8);
|
|
||||||
writebyte(symptr >> 16);
|
|
||||||
writebyte(symptr >> 24);
|
|
||||||
}
|
}
|
||||||
|
writebyte(value & 0xFF);
|
||||||
|
writebyte(value >> 8);
|
||||||
|
writebyte(value >> 16);
|
||||||
|
writebyte(value >> 24);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RPN_BANK_SYM:
|
case RPN_BANK_SYM:
|
||||||
{
|
{
|
||||||
struct sSymbol *sym;
|
for (unsigned int i = -1; (tzSym[++i] = popbyte()); )
|
||||||
uint32_t symptr = 0;
|
|
||||||
|
|
||||||
while ((tzSym[symptr++] = popbyte()) != 0)
|
|
||||||
;
|
;
|
||||||
|
struct sSymbol *sym = sym_FindSymbol(tzSym);
|
||||||
|
uint32_t value = getSymbolID(sym);
|
||||||
|
|
||||||
sym = sym_FindSymbol(tzSym);
|
|
||||||
if (sym == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
symptr = addsymbol(sym);
|
|
||||||
writebyte(RPN_BANK_SYM);
|
writebyte(RPN_BANK_SYM);
|
||||||
writebyte(symptr & 0xFF);
|
writebyte(value & 0xFF);
|
||||||
writebyte(symptr >> 8);
|
writebyte(value >> 8);
|
||||||
writebyte(symptr >> 16);
|
writebyte(value >> 16);
|
||||||
writebyte(symptr >> 24);
|
writebyte(value >> 24);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RPN_BANK_SECT:
|
case RPN_BANK_SECT:
|
||||||
{
|
{
|
||||||
uint16_t b;
|
uint8_t b;
|
||||||
|
|
||||||
writebyte(RPN_BANK_SECT);
|
writebyte(RPN_BANK_SECT);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
b = popbyte();
|
b = popbyte();
|
||||||
writebyte(b & 0xFF);
|
writebyte(b);
|
||||||
} while (b != 0);
|
} while (b != 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -471,32 +393,40 @@ static void writeassert(struct Assertion *assert, FILE *f)
|
|||||||
fputstring(assert->message, f);
|
fputstring(assert->message, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void registerExportedSymbol(struct sSymbol *symbol, void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
if (symbol->isExported && symbol->ID == -1) {
|
||||||
|
*objectSymbolsTail = symbol;
|
||||||
|
objectSymbolsTail = &symbol->next;
|
||||||
|
nbSymbols++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write an objectfile
|
* Write an objectfile
|
||||||
*/
|
*/
|
||||||
void out_WriteObject(void)
|
void out_WriteObject(void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
struct PatchSymbol *pSym;
|
|
||||||
struct Section *pSect;
|
struct Section *pSect;
|
||||||
struct Assertion *assert = assertions;
|
struct Assertion *assert = assertions;
|
||||||
|
|
||||||
addexports();
|
|
||||||
|
|
||||||
f = fopen(tzObjectname, "wb");
|
f = fopen(tzObjectname, "wb");
|
||||||
if (!f)
|
if (!f)
|
||||||
err(1, "Couldn't write file '%s'", tzObjectname);
|
err(1, "Couldn't write file '%s'", tzObjectname);
|
||||||
|
|
||||||
|
/* Also write exported symbols that weren't written above */
|
||||||
|
sym_ForEach(registerExportedSymbol, NULL);
|
||||||
|
|
||||||
fprintf(f, RGBDS_OBJECT_VERSION_STRING, RGBDS_OBJECT_VERSION_NUMBER);
|
fprintf(f, RGBDS_OBJECT_VERSION_STRING, RGBDS_OBJECT_VERSION_NUMBER);
|
||||||
fputlong(RGBDS_OBJECT_REV, f);
|
fputlong(RGBDS_OBJECT_REV, f);
|
||||||
|
|
||||||
fputlong(countsymbols(), f);
|
fputlong(nbSymbols, f);
|
||||||
fputlong(countsections(), f);
|
fputlong(countsections(), f);
|
||||||
|
|
||||||
pSym = pPatchSymbols;
|
for (struct sSymbol const *sym = objectSymbols; sym; sym = sym->next) {
|
||||||
while (pSym) {
|
writesymbol(sym, f);
|
||||||
writesymbol(pSym->pSymbol, f);
|
|
||||||
pSym = pSym->pNext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pSect = pSectionList;
|
pSect = pSectionList;
|
||||||
|
|||||||
151
src/asm/symbol.c
151
src/asm/symbol.c
@@ -11,6 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -28,10 +29,12 @@
|
|||||||
|
|
||||||
#include "extern/err.h"
|
#include "extern/err.h"
|
||||||
|
|
||||||
|
#include "hashmap.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
struct sSymbol *tHashedSymbols[HASHSIZE];
|
HashMap symbols;
|
||||||
|
|
||||||
static struct sSymbol *pScope; /* Current section symbol scope */
|
static struct sSymbol *pScope; /* Current section symbol scope */
|
||||||
struct sSymbol *pPCSymbol;
|
struct sSymbol *pPCSymbol;
|
||||||
static struct sSymbol *p_NARGSymbol;
|
static struct sSymbol *p_NARGSymbol;
|
||||||
@@ -48,6 +51,26 @@ static char SavedMINUTE[3];
|
|||||||
static char SavedSECOND[3];
|
static char SavedSECOND[3];
|
||||||
static bool exportall;
|
static bool exportall;
|
||||||
|
|
||||||
|
struct ForEachArgs {
|
||||||
|
void (*func)(struct sSymbol *, void *);
|
||||||
|
void *arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void forEachWrapper(void *_symbol, void *_argWrapper)
|
||||||
|
{
|
||||||
|
struct ForEachArgs *argWrapper = _argWrapper;
|
||||||
|
struct sSymbol *symbol = _symbol;
|
||||||
|
|
||||||
|
argWrapper->func(symbol, argWrapper->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sym_ForEach(void (*func)(struct sSymbol *, void *), void *arg)
|
||||||
|
{
|
||||||
|
struct ForEachArgs argWrapper = { .func = func, .arg = arg };
|
||||||
|
|
||||||
|
hash_ForEach(symbols, forEachWrapper, &argWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t Callback_NARG(struct sSymbol const *self)
|
static int32_t Callback_NARG(struct sSymbol const *self)
|
||||||
{
|
{
|
||||||
(void)self;
|
(void)self;
|
||||||
@@ -79,14 +102,6 @@ int32_t sym_GetValue(struct sSymbol const *sym)
|
|||||||
return sym->nValue;
|
return sym->nValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate the hash value for a symbol name
|
|
||||||
*/
|
|
||||||
uint32_t sym_CalcHash(const char *s)
|
|
||||||
{
|
|
||||||
return calchash(s) % HASHSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update a symbol's definition filename and line
|
* Update a symbol's definition filename and line
|
||||||
*/
|
*/
|
||||||
@@ -105,36 +120,28 @@ static void updateSymbolFilename(struct sSymbol *nsym)
|
|||||||
*/
|
*/
|
||||||
static struct sSymbol *createsymbol(char const *s)
|
static struct sSymbol *createsymbol(char const *s)
|
||||||
{
|
{
|
||||||
struct sSymbol **ppsym;
|
struct sSymbol *symbol = malloc(sizeof(*symbol));
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
hash = sym_CalcHash(s);
|
if (!symbol)
|
||||||
ppsym = &(tHashedSymbols[hash]);
|
fatalerror("Failed to create symbol: %s", strerror(errno));
|
||||||
|
|
||||||
while ((*ppsym) != NULL)
|
if (snprintf(symbol->tzName, MAXSYMLEN + 1, "%s", s) > MAXSYMLEN)
|
||||||
ppsym = &((*ppsym)->pNext);
|
|
||||||
|
|
||||||
(*ppsym) = malloc(sizeof(struct sSymbol));
|
|
||||||
|
|
||||||
if ((*ppsym) == NULL) {
|
|
||||||
fatalerror("No memory for symbol");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snprintf((*ppsym)->tzName, MAXSYMLEN + 1, "%s", s) > MAXSYMLEN)
|
|
||||||
warning(WARNING_LONG_STR, "Symbol name is too long: '%s'", s);
|
warning(WARNING_LONG_STR, "Symbol name is too long: '%s'", s);
|
||||||
|
|
||||||
(*ppsym)->isExported = false;
|
hash_AddElement(symbols, symbol->tzName, symbol);
|
||||||
(*ppsym)->isBuiltin = false;
|
|
||||||
(*ppsym)->isReferenced = false;
|
symbol->isExported = false;
|
||||||
(*ppsym)->pScope = NULL;
|
symbol->isBuiltin = false;
|
||||||
(*ppsym)->pNext = NULL;
|
symbol->pScope = NULL;
|
||||||
(*ppsym)->pSection = NULL;
|
symbol->pSection = NULL;
|
||||||
(*ppsym)->nValue = 0;
|
symbol->nValue = 0; /* TODO: is this necessary? */
|
||||||
(*ppsym)->pMacro = NULL;
|
symbol->pMacro = NULL;
|
||||||
(*ppsym)->Callback = NULL;
|
symbol->Callback = NULL;
|
||||||
updateSymbolFilename(*ppsym);
|
|
||||||
return *ppsym;
|
symbol->ID = -1;
|
||||||
|
symbol->next = NULL;
|
||||||
|
updateSymbolFilename(symbol);
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -153,12 +160,10 @@ static void fullSymbolName(char *output, size_t outputSize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the pointer to a symbol by name and scope
|
* Find a symbol by name and scope
|
||||||
*/
|
*/
|
||||||
static struct sSymbol **findpsymbol(char const *s, struct sSymbol const *scope)
|
static struct sSymbol *findsymbol(char const *s, struct sSymbol const *scope)
|
||||||
{
|
{
|
||||||
struct sSymbol **ppsym;
|
|
||||||
int32_t hash;
|
|
||||||
char fullname[MAXSYMLEN + 1];
|
char fullname[MAXSYMLEN + 1];
|
||||||
|
|
||||||
if (s[0] == '.' && scope) {
|
if (s[0] == '.' && scope) {
|
||||||
@@ -168,32 +173,11 @@ static struct sSymbol **findpsymbol(char const *s, struct sSymbol const *scope)
|
|||||||
|
|
||||||
char const *separator = strchr(s, '.');
|
char const *separator = strchr(s, '.');
|
||||||
|
|
||||||
if (separator) {
|
if (separator && strchr(separator + 1, '.'))
|
||||||
if (strchr(separator + 1, '.'))
|
fatalerror("'%s' is a nonsensical reference to a nested local symbol",
|
||||||
fatalerror("'%s' is a nonsensical reference to a nested local symbol",
|
s);
|
||||||
s);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash = sym_CalcHash(s);
|
return hash_GetElement(symbols, s);
|
||||||
ppsym = &(tHashedSymbols[hash]);
|
|
||||||
|
|
||||||
while ((*ppsym) != NULL) {
|
|
||||||
if ((strcmp(s, (*ppsym)->tzName) == 0))
|
|
||||||
return ppsym;
|
|
||||||
|
|
||||||
ppsym = &((*ppsym)->pNext);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find a symbol by name and scope
|
|
||||||
*/
|
|
||||||
static struct sSymbol *findsymbol(char const *s, struct sSymbol const *scope)
|
|
||||||
{
|
|
||||||
struct sSymbol **ppsym = findpsymbol(s, scope);
|
|
||||||
|
|
||||||
return ppsym ? *ppsym : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -213,7 +197,7 @@ struct sSymbol *sym_FindSymbol(char const *tzName)
|
|||||||
|
|
||||||
static inline bool isReferenced(struct sSymbol const *sym)
|
static inline bool isReferenced(struct sSymbol const *sym)
|
||||||
{
|
{
|
||||||
return sym->isReferenced;
|
return sym->ID != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -221,33 +205,20 @@ static inline bool isReferenced(struct sSymbol const *sym)
|
|||||||
*/
|
*/
|
||||||
void sym_Purge(char const *tzName)
|
void sym_Purge(char const *tzName)
|
||||||
{
|
{
|
||||||
struct sSymbol **ppSym;
|
struct sSymbol *scope = tzName[0] == '.' ? pScope : NULL;
|
||||||
struct sSymbol *pscope;
|
struct sSymbol *symbol = findsymbol(tzName, scope);
|
||||||
|
|
||||||
if (*tzName == '.')
|
if (!symbol) {
|
||||||
pscope = pScope;
|
|
||||||
else
|
|
||||||
pscope = NULL;
|
|
||||||
|
|
||||||
ppSym = findpsymbol(tzName, pscope);
|
|
||||||
|
|
||||||
if (!ppSym) {
|
|
||||||
yyerror("'%s' not defined", tzName);
|
yyerror("'%s' not defined", tzName);
|
||||||
} else if ((*ppSym)->isBuiltin) {
|
} else if (symbol->isBuiltin) {
|
||||||
yyerror("Built-in symbol '%s' cannot be purged", tzName);
|
yyerror("Built-in symbol '%s' cannot be purged", tzName);
|
||||||
} else if (isReferenced(*ppSym)) {
|
} else if (isReferenced(symbol)) {
|
||||||
yyerror("Symbol \"%s\" is referenced and thus cannot be purged",
|
yyerror("Symbol \"%s\" is referenced and thus cannot be purged",
|
||||||
tzName);
|
tzName);
|
||||||
} else {
|
} else {
|
||||||
struct sSymbol *pSym;
|
hash_RemoveElement(symbols, tzName);
|
||||||
|
free(symbol->pMacro);
|
||||||
pSym = *ppSym;
|
free(symbol);
|
||||||
*ppSym = pSym->pNext;
|
|
||||||
|
|
||||||
if (pSym->pMacro)
|
|
||||||
free(pSym->pMacro);
|
|
||||||
|
|
||||||
free(pSym);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,10 +474,8 @@ void sym_Export(char const *tzSym)
|
|||||||
struct sSymbol *nsym = sym_FindSymbol(tzSym);
|
struct sSymbol *nsym = sym_FindSymbol(tzSym);
|
||||||
|
|
||||||
/* If the symbol doesn't exist, create a ref that can be purged */
|
/* If the symbol doesn't exist, create a ref that can be purged */
|
||||||
if (!nsym) {
|
if (!nsym)
|
||||||
nsym = sym_Ref(tzSym);
|
nsym = sym_Ref(tzSym);
|
||||||
nsym->isReferenced = false;
|
|
||||||
}
|
|
||||||
nsym->isExported = true;
|
nsym->isExported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,7 +523,6 @@ struct sSymbol *sym_Ref(char const *tzSym)
|
|||||||
nsym = createsymbol(tzSym);
|
nsym = createsymbol(tzSym);
|
||||||
nsym->type = SYM_REF;
|
nsym->type = SYM_REF;
|
||||||
}
|
}
|
||||||
nsym->isReferenced = true;
|
|
||||||
|
|
||||||
return nsym;
|
return nsym;
|
||||||
}
|
}
|
||||||
@@ -583,9 +551,6 @@ static inline char const *removeLeadingZeros(char const *ptr)
|
|||||||
*/
|
*/
|
||||||
void sym_Init(void)
|
void sym_Init(void)
|
||||||
{
|
{
|
||||||
for (int32_t i = 0; i < HASHSIZE; i++)
|
|
||||||
tHashedSymbols[i] = NULL;
|
|
||||||
|
|
||||||
pPCSymbol = sym_AddReloc("@");
|
pPCSymbol = sym_AddReloc("@");
|
||||||
pPCSymbol->Callback = CallbackPC;
|
pPCSymbol->Callback = CallbackPC;
|
||||||
pPCSymbol->isBuiltin = true;
|
pPCSymbol->isBuiltin = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user