Moved filename caching into the preprocessor.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 13 Feb 2009 18:54:21 -0500
changeset 612 72ccfe69eaf1
parent 611 8c2ee1a97ee1
child 613 f48e56a16437
Moved filename caching into the preprocessor. Now the assembler, compiler and preprocessor can all share it.
mojoshader_assembler.c
mojoshader_internal.h
mojoshader_preprocessor.c
--- a/mojoshader_assembler.c	Fri Feb 13 10:15:36 2009 -0500
+++ b/mojoshader_assembler.c	Fri Feb 13 18:54:21 2009 -0500
@@ -18,15 +18,6 @@
 #endif
 
 
-// Simple linked list to cache source filenames, so we don't have to copy
-//  the same string over and over for each opcode.
-typedef struct FilenameCache
-{
-    char *filename;
-    struct FilenameCache *next;
-} FilenameCache;
-
-
 typedef struct SourcePos
 {
     const char *filename;
@@ -64,7 +55,6 @@
     uint32 ctab_allocation;
     size_t output_len;
     size_t output_allocation;
-    FilenameCache *filename_cache;
 } Context;
 
 
@@ -266,59 +256,12 @@
 } // nexttoken
 
 
-static const char *cache_filename(Context *ctx, const char *fname)
-{
-    if (fname == NULL)
-        return NULL;
-
-    // !!! FIXME: this could be optimized into a hash table, but oh well.
-    FilenameCache *item = ctx->filename_cache;
-    while (item != NULL)
-    {
-        if (strcmp(item->filename, fname) == 0)
-            return item->filename;
-        item = item->next;
-    } // while
-
-    // new cache item.
-    item = (FilenameCache *) Malloc(ctx, sizeof (FilenameCache));
-    if (item == NULL)
-        return NULL;
-
-    item->filename = (char *) Malloc(ctx, strlen(fname) + 1);
-    if (item->filename == NULL)
-    {
-        Free(ctx, item);
-        return NULL;
-    } // if
-
-    strcpy(item->filename, fname);
-    item->next = ctx->filename_cache;
-    ctx->filename_cache = item;
-
-    return item->filename;
-} // cache_filename
-
-
-static void free_filename_cache(Context *ctx)
-{
-    FilenameCache *item = ctx->filename_cache;
-    while (item != NULL)
-    {
-        FilenameCache *next = item->next;
-        Free(ctx, item->filename);
-        Free(ctx, item);
-        item = next;
-    } // while
-} // free_filename_cache
-
-
 static inline void add_token_sourcepos(Context *ctx, const size_t idx)
 {
     unsigned int pos = 0;
     const char *fname = preprocessor_sourcepos(ctx->preprocessor, &pos);
     ctx->token_to_source[idx].line = pos;
-    ctx->token_to_source[idx].filename = cache_filename(ctx, fname);
+    ctx->token_to_source[idx].filename = fname;  // cached in preprocessor!
 } // add_token_sourcepos
 
 
@@ -1516,7 +1459,6 @@
         MOJOSHADER_free f = ((ctx->free != NULL) ? ctx->free : MOJOSHADER_internal_free);
         void *d = ctx->malloc_data;
         free_error_list(f, d, ctx->errors);
-        free_filename_cache(ctx);
         if (ctx->preprocessor != NULL)
             preprocessor_end(ctx->preprocessor);
         if (ctx->output != NULL)
--- a/mojoshader_internal.h	Fri Feb 13 10:15:36 2009 -0500
+++ b/mojoshader_internal.h	Fri Feb 13 18:54:21 2009 -0500
@@ -377,7 +377,7 @@
 
 typedef struct IncludeState
 {
-    char *filename;
+    const char *filename;
     int included;
     const char *source_base;
     const char *source;
--- a/mojoshader_preprocessor.c	Fri Feb 13 10:15:36 2009 -0500
+++ b/mojoshader_preprocessor.c	Fri Feb 13 18:54:21 2009 -0500
@@ -23,6 +23,14 @@
     struct DefineHash *next;
 } DefineHash;
 
+// Simple linked list to cache source filenames, so we don't have to copy
+//  the same string over and over for each opcode.
+typedef struct FilenameCache
+{
+    char *filename;
+    struct FilenameCache *next;
+} FilenameCache;
+
 typedef struct Context
 {
     int isfail;
@@ -30,6 +38,7 @@
     char failstr[256];
     IncludeState *include_stack;
     DefineHash *define_hashtable[256];
+    FilenameCache *filename_cache;
     MOJOSHADER_includeOpen open_callback;
     MOJOSHADER_includeClose close_callback;
     MOJOSHADER_malloc malloc;
@@ -325,6 +334,54 @@
 } // find_define
 
 
+// filename cache stuff...
+
+static const char *cache_filename(Context *ctx, const char *fname)
+{
+    if (fname == NULL)
+        return NULL;
+
+    // !!! FIXME: this could be optimized into a hash table, but oh well.
+    FilenameCache *item = ctx->filename_cache;
+    while (item != NULL)
+    {
+        if (strcmp(item->filename, fname) == 0)
+            return item->filename;
+        item = item->next;
+    } // while
+
+    // new cache item.
+    item = (FilenameCache *) Malloc(ctx, sizeof (FilenameCache));
+    if (item == NULL)
+        return NULL;
+
+    item->filename = StrDup(ctx, fname);
+    if (item->filename == NULL)
+    {
+        Free(ctx, item);
+        return NULL;
+    } // if
+
+    item->next = ctx->filename_cache;
+    ctx->filename_cache = item;
+
+    return item->filename;
+} // cache_filename
+
+
+static void free_filename_cache(Context *ctx)
+{
+    FilenameCache *item = ctx->filename_cache;
+    while (item != NULL)
+    {
+        FilenameCache *next = item->next;
+        Free(ctx, item->filename);
+        Free(ctx, item);
+        item = next;
+    } // while
+} // free_filename_cache
+
+
 static int push_source(Context *ctx, const char *fname, const char *source,
                        unsigned int srclen, int included)
 {
@@ -335,7 +392,7 @@
 
     if (fname != NULL)
     {
-        state->filename = StrDup(ctx, fname);
+        state->filename = cache_filename(ctx, fname);
         if (state->filename == NULL)
         {
             Free(ctx, state);
@@ -369,8 +426,9 @@
                             ctx->free, ctx->malloc_data);
     } // if
 
+    // state->filename is a pointer to the filename cache; don't free it here!
+
     ctx->include_stack = state->next;
-    Free(ctx, state->filename);
     Free(ctx, state);
 } // pop_source
 
@@ -435,6 +493,7 @@
         pop_source(ctx);
 
     free_all_defines(ctx);
+    free_filename_cache(ctx);
 
     Free(ctx, ctx);
 } // preprocessor_end