[Nasm-commits] [nasm:loops] preproc: make the handling of openers and closers better
nasm-bot for H. Peter Anvin
hpa at zytor.com
Thu Jun 4 19:56:53 PDT 2020
Commit-ID: 1f82dffba7c35056b500051999076fdd1ee53ab0
Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=1f82dffba7c35056b500051999076fdd1ee53ab0
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Tue, 8 Oct 2019 02:45:17 -0700
Committer: H. Peter Anvin <hpa at zytor.com>
CommitDate: Tue, 8 Oct 2019 02:45:17 -0700
preproc: make the handling of openers and closers better
Make a stack of openers and closers. The special handling of
%rep...%endrep is really entirely bogus: we should be able to throw
an immediate error when defining a macro which ends up having
unbalanced %rep ... %endrep.
Signed-off-by: H. Peter Anvin <hpa at zytor.com>
---
asm/preproc.c | 85 +++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 57 insertions(+), 28 deletions(-)
diff --git a/asm/preproc.c b/asm/preproc.c
index a6323912..c1c0cf86 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -592,8 +592,15 @@ static struct hash_table smacros;
*/
static MMacro *defining;
-static uint64_t nested_mac_count;
-static uint64_t nested_rep_count;
+/*
+ * When skipping directives inside macro definitions and nesting blocks, keep track of what
+ * we expect on the other side...
+ */
+struct nested_def {
+ struct nested_def *next;
+ enum preproc_token closer;
+};
+static struct nested_def *nested_def;
/*
* The number of macro parameters to allocate space for at a time.
@@ -3238,6 +3245,7 @@ static bool loop_end_rep(MMacro *m, bool emitting)
* @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
*
*/
+
static int do_directive(Token *tline, Token **output)
{
enum preproc_token i;
@@ -3298,36 +3306,58 @@ static int do_directive(Token *tline, Token **output)
/*
* If we're defining a macro or reading a %rep block, we should
- * ignore all directives except for %macro/%imacro (which nest),
+ * ignore all directives except for ones %macro/%imacro (which nest),
* %endm/%endmacro, and (only if we're in a %rep block) %endrep.
* If we're in a %rep block, another %rep nests, so should be let through.
*/
- if (defining && i != PP_MACRO && i != PP_RMACRO &&
- i != PP_ENDMACRO && i != PP_ENDM &&
- (defining->name || (i != PP_ENDREP && i != PP_REP))) {
- return NO_DIRECTIVE_FOUND;
- }
-
if (defining) {
- if (i == PP_MACRO || i == PP_RMACRO) {
- nested_mac_count++;
- return NO_DIRECTIVE_FOUND;
- } else if (nested_mac_count > 0) {
- if (i == PP_ENDMACRO) {
- nested_mac_count--;
+ struct nested_def *nd;
+ enum preproc_token ii = i;
+ enum preproc_token closer;
+
+ switch (i) {
+ case PP_MACRO:
+ case PP_RMACRO:
+ closer = PP_ENDMACRO;
+ goto is_opener;
+
+ case PP_REP:
+ if (defining->name)
return NO_DIRECTIVE_FOUND;
- }
- }
- if (!defining->name) {
- if (i == PP_REP) {
- nested_rep_count++;
+
+ closer = PP_ENDREP;
+ goto is_opener;
+
+ is_opener:
+ nasm_new(nd);
+ nd->next = nested_def;
+ nd->closer = closer;
+ nested_def = nd;
+ break;
+
+ case PP_ENDREP:
+ if (defining->name)
return NO_DIRECTIVE_FOUND;
- } else if (nested_rep_count > 0) {
- if (i == PP_ENDREP) {
- nested_rep_count--;
- return NO_DIRECTIVE_FOUND;
- }
- }
+ goto is_closer;
+
+ case PP_ENDM:
+ ii = PP_ENDMACRO;
+ goto is_closer;
+
+ case PP_ENDMACRO:
+ goto is_closer;
+
+ is_closer:
+ nd = nested_def;
+ if (!nd || nd->closer != ii)
+ break;
+
+ nested_def = nd->next;
+ nasm_free(nd);
+ break;
+
+ default:
+ return NO_DIRECTIVE_FOUND;
}
}
@@ -6101,8 +6131,7 @@ pp_reset(const char *file, enum preproc_mode mode, struct strlist *dep_list)
cstk = NULL;
defining = NULL;
- nested_mac_count = 0;
- nested_rep_count = 0;
+ nested_def = NULL;
init_macros();
unique = 0;
deplist = dep_list;
More information about the Nasm-commits
mailing list