Allow changing recursion depth limit at runtime

This commit is contained in:
ISSOtm
2022-02-05 12:15:32 +01:00
committed by Eldred Habert
parent 6842c831fd
commit 7dd8ba37f1
9 changed files with 80 additions and 12 deletions

View File

@@ -284,8 +284,9 @@ bool yywrap(void)
*/
static void newContext(struct FileStackNode *fileInfo)
{
if (++contextDepth >= maxRecursionDepth)
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
++contextDepth;
fstk_NewRecursionDepth(maxRecursionDepth); // Only checks if the max depth was exceeded
struct Context *context = malloc(sizeof(*context));
if (!context)
@@ -507,6 +508,13 @@ bool fstk_Break(void)
return true;
}
void fstk_NewRecursionDepth(size_t newDepth)
{
if (contextDepth >= newDepth)
fatalerror("Recursion limit (%zu) exceeded\n", newDepth);
maxRecursionDepth = newDepth;
}
void fstk_Init(char const *mainPath, size_t maxDepth)
{
struct LexerState *state = lexer_OpenFile(mainPath);

View File

@@ -668,14 +668,8 @@ static void beginExpansion(char const *str, bool owned, char const *name)
if (!size)
return;
if (name) {
size_t depth = 0;
for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
if (depth++ >= maxRecursionDepth)
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
}
}
if (name)
lexer_CheckRecursionDepth();
struct Expansion *exp = malloc(sizeof(*exp));
@@ -692,6 +686,16 @@ static void beginExpansion(char const *str, bool owned, char const *name)
lexerState->expansions = exp;
}
void lexer_CheckRecursionDepth(void)
{
size_t depth = 0;
for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
if (depth++ >= maxRecursionDepth)
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
}
}
static void freeExpansion(struct Expansion *expansion)
{
free(expansion->name);

View File

@@ -1,3 +1,4 @@
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
@@ -5,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
#include "asm/fstack.h"
#include "asm/lexer.h"
#include "asm/main.h"
#include "asm/section.h"
@@ -17,6 +19,7 @@ struct OptStackEntry {
bool haltnop;
bool optimizeLoads;
bool warningsAreErrors;
size_t maxRecursionDepth;
// Don't be confused: we use the size of the **global variable** `warningStates`!
enum WarningState warningStates[sizeof(warningStates)];
struct OptStackEntry *next;
@@ -39,6 +42,12 @@ void opt_P(uint8_t fill)
fillByte = fill;
}
void opt_R(size_t newDepth)
{
fstk_NewRecursionDepth(newDepth);
lexer_CheckRecursionDepth();
}
void opt_h(bool halt)
{
haltnop = halt;
@@ -86,6 +95,29 @@ void opt_Parse(char *s)
}
break;
case 'r': {
++s; // Skip 'r'
while (isblank(*s))
++s; // Skip leading whitespace
if (s[0] == '\0') {
error("Missing argument to option 'r'\n");
break;
}
char *endptr;
unsigned long newDepth = strtoul(s, &endptr, 10);
if (*endptr != '\0') {
error("Invalid argument to option 'r' (\"%s\")\n", s);
} else if (errno == ERANGE) {
error("Argument to 'r' is out of range (\"%s\")\n", s);
} else {
opt_R(newDepth);
}
break;
}
case 'h':
if (s[1] == '\0')
opt_h(false);

View File

@@ -1993,6 +1993,7 @@ block, all of them but the first one are ignored.
.Ss Changing options while assembling
.Ic OPT
can be used to change some of the options during assembling from within the source, instead of defining them on the command-line.
.Pq See Xr rgbasm 1 .
.Pp
.Ic OPT
takes a comma-separated list of options as its argument:
@@ -2008,8 +2009,10 @@ POPO
LD [$FF88], A ; optimized to use LDH by default
.Ed
.Pp
The options that OPT can modify are currently:
.Cm b , g , p , h , L ,
The options that
.Ic OPT
can modify are currently:
.Cm b , g , p , r , h , L ,
and
.Cm W .
The Boolean flag options