mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Fix expansions that start from the end of another expansion (#839)
Do not free an expansion until its offset is *past* its size. This means potentially freeing a nested stack of expansions all at once. Fixes #696
This commit is contained in:
@@ -736,7 +736,11 @@ static char const *readMacroArg(char name)
|
|||||||
static int peekInternal(uint8_t distance)
|
static int peekInternal(uint8_t distance)
|
||||||
{
|
{
|
||||||
for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
|
for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
|
||||||
assert(exp->offset < exp->size);
|
/*
|
||||||
|
* An expansion that has reached its end will have `exp->offset` == `exp->size`,
|
||||||
|
* and `peekInternal` will continue with its parent
|
||||||
|
*/
|
||||||
|
assert(exp->offset <= exp->size);
|
||||||
if (distance < exp->size - exp->offset)
|
if (distance < exp->size - exp->offset)
|
||||||
return exp->contents.unowned[exp->offset + distance];
|
return exp->contents.unowned[exp->offset + distance];
|
||||||
distance -= exp->size - exp->offset;
|
distance -= exp->size - exp->offset;
|
||||||
@@ -870,16 +874,21 @@ static void shiftChar(void)
|
|||||||
|
|
||||||
lexerState->macroArgScanDistance--;
|
lexerState->macroArgScanDistance--;
|
||||||
|
|
||||||
|
restart:
|
||||||
if (lexerState->expansions) {
|
if (lexerState->expansions) {
|
||||||
/* Advance within the current expansion */
|
/* Advance within the current expansion */
|
||||||
assert(lexerState->expansions->offset < lexerState->expansions->size);
|
assert(lexerState->expansions->offset <= lexerState->expansions->size);
|
||||||
lexerState->expansions->offset++;
|
lexerState->expansions->offset++;
|
||||||
if (lexerState->expansions->offset == lexerState->expansions->size) {
|
if (lexerState->expansions->offset > lexerState->expansions->size) {
|
||||||
/* When an expansion is done, free it and move up to its parent */
|
/*
|
||||||
|
* When advancing would go past an expansion's end, free it,
|
||||||
|
* move up to its parent, and try again to advance
|
||||||
|
*/
|
||||||
struct Expansion *exp = lexerState->expansions;
|
struct Expansion *exp = lexerState->expansions;
|
||||||
|
|
||||||
lexerState->expansions = lexerState->expansions->parent;
|
lexerState->expansions = lexerState->expansions->parent;
|
||||||
freeExpansion(exp);
|
freeExpansion(exp);
|
||||||
|
goto restart;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Advance within the file contents */
|
/* Advance within the file contents */
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ warning: equs-newline.asm(3): [-Wuser]
|
|||||||
while expanding symbol "ACT"
|
while expanding symbol "ACT"
|
||||||
warning: equs-newline.asm(3): [-Wuser]
|
warning: equs-newline.asm(3): [-Wuser]
|
||||||
Second
|
Second
|
||||||
|
while expanding symbol "ACT"
|
||||||
warning: equs-newline.asm(4): [-Wuser]
|
warning: equs-newline.asm(4): [-Wuser]
|
||||||
Third
|
Third
|
||||||
|
|||||||
@@ -1,6 +1,2 @@
|
|||||||
recurse EQUS "recurse"
|
recurse EQUS "recurse"
|
||||||
recurse
|
recurse
|
||||||
|
|
||||||
; FIXME: also handle the following:
|
|
||||||
; recurse EQUS "recurse"
|
|
||||||
; recurse
|
|
||||||
|
|||||||
@@ -1,6 +1,2 @@
|
|||||||
recurse EQUS "\{recurse\}"
|
recurse EQUS "\{recurse\}"
|
||||||
{recurse}
|
{recurse}
|
||||||
|
|
||||||
; FIXME: also handle the following:
|
|
||||||
; recurse EQUS "\{recurse\}"
|
|
||||||
; {recurse}
|
|
||||||
|
|||||||
@@ -16,12 +16,8 @@ SECTION "calls", ROM0[0]
|
|||||||
|
|
||||||
|
|
||||||
defRST: MACRO
|
defRST: MACRO
|
||||||
; FIXME: This is required, otherwise the lexer does not paste the two tokens
|
SECTION "rst\1", ROM0[$\1]
|
||||||
ADDR equs "$\1"
|
|
||||||
SECTION "rst\1", ROM0[ADDR]
|
|
||||||
|
|
||||||
rst\1:
|
rst\1:
|
||||||
PURGE ADDR
|
|
||||||
ENDM
|
ENDM
|
||||||
defRST 00
|
defRST 00
|
||||||
defRST 08
|
defRST 08
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ EOF
|
|||||||
cat > quote\"file.err <<EOF
|
cat > quote\"file.err <<EOF
|
||||||
warning: quote"file.asm(1): [-Wuser]
|
warning: quote"file.asm(1): [-Wuser]
|
||||||
quote"file.asm
|
quote"file.asm
|
||||||
|
while expanding symbol "__FILE__"
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,27 @@
|
|||||||
warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser]
|
||||||
_u1
|
_u1
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
||||||
_u2
|
_u2
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
||||||
_u3
|
_u3
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
|
||||||
_u1
|
_u1
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser]
|
||||||
_u4
|
_u4
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
||||||
_u5
|
_u5
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
||||||
_u6
|
_u6
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
|
||||||
_u4
|
_u4
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
FATAL: unique-id.asm(15):
|
FATAL: unique-id.asm(15):
|
||||||
Macro argument '\@' not defined
|
Macro argument '\@' not defined
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
|
|||||||
@@ -14,12 +14,8 @@ SECTION "calls", ROM0[0]
|
|||||||
|
|
||||||
|
|
||||||
defRST: MACRO
|
defRST: MACRO
|
||||||
; FIXME: This is required, otherwise the lexer does not paste the two tokens
|
SECTION "rst\1", ROM0[$\1]
|
||||||
ADDR equs "$\1"
|
|
||||||
SECTION "rst\1", ROM0[ADDR]
|
|
||||||
|
|
||||||
rst\1:
|
rst\1:
|
||||||
PURGE ADDR
|
|
||||||
ENDM
|
ENDM
|
||||||
defRST 00
|
defRST 00
|
||||||
defRST 08
|
defRST 08
|
||||||
|
|||||||
Reference in New Issue
Block a user