mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-07-24 10:25:42 -04:00
preproc: don't call do_directive recursively
The hacky %arg and %local directives build directives as strings which they then tokenize and call do_directive() recursively with. Factor these out and remove the recursion. It is too bad that %arg and %local didn't include the [] brackets in the created macros; if so it would have been possible to do something sane with 64-bit register operands. Sigh. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
parent
72a555972f
commit
1593c1dc60
119
asm/preproc.c
119
asm/preproc.c
@ -3410,6 +3410,61 @@ done:
|
|||||||
return DIRECTIVE_FOUND;
|
return DIRECTIVE_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used for the %arg and %local directives
|
||||||
|
*/
|
||||||
|
static void define_stack_smacro(const char *name, int offset)
|
||||||
|
{
|
||||||
|
Token *tt;
|
||||||
|
|
||||||
|
tt = make_tok_char(NULL, ')');
|
||||||
|
tt = make_tok_num(tt, offset);
|
||||||
|
if (!tok_is(tt, '-'))
|
||||||
|
tt = make_tok_char(tt, '+');
|
||||||
|
tt = new_Token(tt, TOK_ID, StackPointer, 0);
|
||||||
|
tt = make_tok_char(tt, '(');
|
||||||
|
|
||||||
|
define_smacro(name, true, tt, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This implements the %assign directive: expand an smacro expression,
|
||||||
|
* then evaluate it, and assign the corresponding number to an smacro.
|
||||||
|
*/
|
||||||
|
static void assign_smacro(const char *mname, bool casesense,
|
||||||
|
Token *tline, const char *dname)
|
||||||
|
{
|
||||||
|
struct ppscan pps;
|
||||||
|
expr *evalresult;
|
||||||
|
struct tokenval tokval;
|
||||||
|
|
||||||
|
tline = expand_smacro(tline);
|
||||||
|
|
||||||
|
pps.tptr = tline;
|
||||||
|
pps.ntokens = -1;
|
||||||
|
tokval.t_type = TOKEN_INVALID;
|
||||||
|
evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL);
|
||||||
|
free_tlist(tline);
|
||||||
|
if (!evalresult)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tokval.t_type)
|
||||||
|
nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
|
||||||
|
|
||||||
|
if (!is_simple(evalresult)) {
|
||||||
|
nasm_nonfatal("non-constant value given to `%s'", dname);
|
||||||
|
} else {
|
||||||
|
tline = make_tok_num(NULL, reloc_value(evalresult));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We now have a macro name, an implicit parameter count of
|
||||||
|
* zero, and a numeric token to use as an expansion. Create
|
||||||
|
* and store an SMacro.
|
||||||
|
*/
|
||||||
|
define_smacro(mname, casesense, tline, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find and process preprocessor directive in passed line
|
* find and process preprocessor directive in passed line
|
||||||
@ -3463,7 +3518,12 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
switch (tline->type) {
|
switch (tline->type) {
|
||||||
case TOK_PREPROC_ID:
|
case TOK_PREPROC_ID:
|
||||||
dname = tok_text(tline);
|
dname = tok_text(tline);
|
||||||
if (dname[1] == '%' || dname[1] == '$')
|
/*
|
||||||
|
* For it to be a directive, the second character has to be an
|
||||||
|
* ASCII letter; this is a very quick and dirty test for that;
|
||||||
|
* all other cases will get rejected by the token hash.
|
||||||
|
*/
|
||||||
|
if ((uint8_t)(dname[1] - 'A') > (uint8_t)('z' - 'A'))
|
||||||
return NO_DIRECTIVE_FOUND;
|
return NO_DIRECTIVE_FOUND;
|
||||||
|
|
||||||
op = pp_token_hash(dname);
|
op = pp_token_hash(dname);
|
||||||
@ -3647,7 +3707,6 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
offset = ArgOffset;
|
offset = ArgOffset;
|
||||||
do {
|
do {
|
||||||
const char *arg;
|
const char *arg;
|
||||||
char directive[256];
|
|
||||||
int size = StackSize;
|
int size = StackSize;
|
||||||
|
|
||||||
/* Find the argument name */
|
/* Find the argument name */
|
||||||
@ -3685,9 +3744,7 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
size = ALIGN(size, StackSize);
|
size = ALIGN(size, StackSize);
|
||||||
|
|
||||||
/* Now define the macro for the argument */
|
/* Now define the macro for the argument */
|
||||||
snprintf(directive, sizeof(directive), "%%define %s (%s+%d)",
|
define_stack_smacro(arg, offset);
|
||||||
arg, StackPointer, offset);
|
|
||||||
do_directive(tokenize(directive), output);
|
|
||||||
offset += size;
|
offset += size;
|
||||||
|
|
||||||
/* Move to the next argument in the list */
|
/* Move to the next argument in the list */
|
||||||
@ -3697,6 +3754,9 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PP_LOCAL:
|
case PP_LOCAL:
|
||||||
|
{
|
||||||
|
int total_size = 0;
|
||||||
|
|
||||||
/* TASM like LOCAL directive to define local variables for a
|
/* TASM like LOCAL directive to define local variables for a
|
||||||
* function, in the following form:
|
* function, in the following form:
|
||||||
*
|
*
|
||||||
@ -3709,7 +3769,6 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
offset = LocalOffset;
|
offset = LocalOffset;
|
||||||
do {
|
do {
|
||||||
const char *local;
|
const char *local;
|
||||||
char directive[256];
|
|
||||||
int size = StackSize;
|
int size = StackSize;
|
||||||
|
|
||||||
/* Find the argument name */
|
/* Find the argument name */
|
||||||
@ -3749,21 +3808,24 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
offset += size; /* Negative offset, increment before */
|
offset += size; /* Negative offset, increment before */
|
||||||
|
|
||||||
/* Now define the macro for the argument */
|
/* Now define the macro for the argument */
|
||||||
snprintf(directive, sizeof(directive), "%%define %s (%s-%d)",
|
define_stack_smacro(local, -offset);
|
||||||
local, StackPointer, offset);
|
|
||||||
do_directive(tokenize(directive), output);
|
|
||||||
|
|
||||||
/* Now define the assign to setup the enter_c macro correctly */
|
/* How is this different from offset? */
|
||||||
snprintf(directive, sizeof(directive),
|
total_size += size;
|
||||||
"%%assign %%$localsize %%$localsize+%d", size);
|
|
||||||
do_directive(tokenize(directive), output);
|
|
||||||
|
|
||||||
/* Move to the next argument in the list */
|
/* Move to the next argument in the list */
|
||||||
tline = skip_white(tline->next);
|
tline = skip_white(tline->next);
|
||||||
} while (tok_is(tline, ','));
|
} while (tok_is(tline, ','));
|
||||||
|
|
||||||
|
/* Now define the assign to setup the enter_c macro correctly */
|
||||||
|
tt = make_tok_num(NULL, total_size);
|
||||||
|
tt = make_tok_char(tt, '+');
|
||||||
|
tt = new_Token(tt, TOK_LOCAL_MACRO, "%$localsize", 11);
|
||||||
|
assign_smacro("%$localsize", true, tt, dname);
|
||||||
|
|
||||||
LocalOffset = offset;
|
LocalOffset = offset;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PP_CLEAR:
|
case PP_CLEAR:
|
||||||
{
|
{
|
||||||
bool context = false;
|
bool context = false;
|
||||||
@ -4645,36 +4707,11 @@ issue_error:
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
last = tline;
|
last = tline;
|
||||||
tline = expand_smacro(tline->next);
|
tline = tline->next;
|
||||||
last->next = NULL;
|
last->next = NULL;
|
||||||
|
assign_smacro(mname, casesense, tline, dname);
|
||||||
pps.tptr = tline;
|
|
||||||
pps.ntokens = -1;
|
|
||||||
tokval.t_type = TOKEN_INVALID;
|
|
||||||
evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL);
|
|
||||||
free_tlist(tline);
|
|
||||||
if (!evalresult)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (tokval.t_type)
|
|
||||||
nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
|
|
||||||
|
|
||||||
if (!is_simple(evalresult)) {
|
|
||||||
nasm_nonfatal("non-constant value given to `%s'", dname);
|
|
||||||
free_tlist(origline);
|
|
||||||
return DIRECTIVE_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_start = make_tok_num(NULL, reloc_value(evalresult));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We now have a macro name, an implicit parameter count of
|
|
||||||
* zero, and a numeric token to use as an expansion. Create
|
|
||||||
* and store an SMacro.
|
|
||||||
*/
|
|
||||||
define_smacro(mname, casesense, macro_start, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PP_ALIASES:
|
case PP_ALIASES:
|
||||||
tline = tline->next;
|
tline = tline->next;
|
||||||
tline = expand_smacro(tline);
|
tline = expand_smacro(tline);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user