[nasm:master] preproc: don't call do_directive recursively

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Fri Jul 10 01:24:03 PDT 2020


Commit-ID:  1593c1dc60bb145c67b6733ea35f07bfcd6b8d30
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=1593c1dc60bb145c67b6733ea35f07bfcd6b8d30
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Fri, 10 Jul 2020 01:14:32 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Fri, 10 Jul 2020 01:21:44 -0700

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 at zytor.com>


---
 asm/preproc.c | 125 +++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 81 insertions(+), 44 deletions(-)

diff --git a/asm/preproc.c b/asm/preproc.c
index 3dac5aef..b2dea76d 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -3410,6 +3410,61 @@ done:
     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
@@ -3463,7 +3518,12 @@ static int do_directive(Token *tline, Token **output)
     switch (tline->type) {
     case TOK_PREPROC_ID:
         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;
 
         op = pp_token_hash(dname);
@@ -3647,7 +3707,6 @@ static int do_directive(Token *tline, Token **output)
         offset = ArgOffset;
         do {
             const char *arg;
-            char directive[256];
             int size = StackSize;
 
             /* Find the argument name */
@@ -3685,9 +3744,7 @@ static int do_directive(Token *tline, Token **output)
             size = ALIGN(size, StackSize);
 
             /* Now define the macro for the argument */
-            snprintf(directive, sizeof(directive), "%%define %s (%s+%d)",
-                     arg, StackPointer, offset);
-            do_directive(tokenize(directive), output);
+            define_stack_smacro(arg, offset);
             offset += size;
 
             /* Move to the next argument in the list */
@@ -3697,6 +3754,9 @@ static int do_directive(Token *tline, Token **output)
         break;
 
     case PP_LOCAL:
+    {
+        int total_size = 0;
+
         /* TASM like LOCAL directive to define local variables for a
          * function, in the following form:
          *
@@ -3709,7 +3769,6 @@ static int do_directive(Token *tline, Token **output)
         offset = LocalOffset;
         do {
             const char *local;
-	    char directive[256];
             int size = StackSize;
 
             /* Find the argument name */
@@ -3749,21 +3808,24 @@ static int do_directive(Token *tline, Token **output)
             offset += size;     /* Negative offset, increment before */
 
             /* Now define the macro for the argument */
-            snprintf(directive, sizeof(directive), "%%define %s (%s-%d)",
-                     local, StackPointer, offset);
-            do_directive(tokenize(directive), output);
+            define_stack_smacro(local, -offset);
 
-            /* Now define the assign to setup the enter_c macro correctly */
-            snprintf(directive, sizeof(directive),
-                     "%%assign %%$localsize %%$localsize+%d", size);
-            do_directive(tokenize(directive), output);
+            /* How is this different from offset? */
+            total_size += size;
 
             /* Move to the next argument in the list */
             tline = skip_white(tline->next);
         } 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;
         break;
-
+    }
     case PP_CLEAR:
     {
         bool context = false;
@@ -4645,35 +4707,10 @@ issue_error:
             goto done;
 
         last = tline;
-        tline = expand_smacro(tline->next);
+        tline = tline->next;
         last->next = NULL;
-
-        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;
-
-        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;
+        assign_smacro(mname, casesense, tline, dname);
+        goto done;
 
     case PP_ALIASES:
         tline = tline->next;
@@ -4687,8 +4724,8 @@ issue_error:
     }
 
 done:
-        free_tlist(origline);
-        return DIRECTIVE_FOUND;
+    free_tlist(origline);
+    return DIRECTIVE_FOUND;
 }
 
 /*


More information about the Nasm-commits mailing list