ARB prog: Clean up several memory leaks
authorIan Romanick <ian.d.romanick@intel.com>
Mon, 27 Jul 2009 19:21:26 +0000 (12:21 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 27 Jul 2009 19:21:26 +0000 (12:21 -0700)
As far as I am able to determine via code inspection and using
Valgrind, that should be all of the leaks in the parser.

src/mesa/shader/program_parse.tab.c
src/mesa/shader/program_parse.y
src/mesa/shader/program_parser.h

index 945d77656a42b2cca6168774ede3a71641feae47..a49cfeb483c8effdb95a49c118a59232245126a8 100644 (file)
@@ -4700,6 +4700,8 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
       }
 
       _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+      s->next = state->sym;
+      state->sym = s;
    }
 
    return s;
@@ -4900,6 +4902,9 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
    struct asm_instruction *inst;
    unsigned i;
    GLubyte *strz;
+   GLboolean result = GL_FALSE;
+   void *temp;
+   struct asm_symbol *sym;
 
    state->ctx = ctx;
    state->prog->Target = target;
@@ -4961,7 +4966,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
 
 
    if (ctx->Program.ErrorPos != -1) {
-      return GL_FALSE;
+     goto error;
    }
 
    if (! _mesa_layout_parameters(state)) {
@@ -4972,7 +4977,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
       loc.position = len;
 
       yyerror(& loc, state, "invalid PARAM usage");
-      return GL_FALSE;
+      goto error;
    }
 
 
@@ -4986,8 +4991,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
       struct asm_instruction *const temp = inst->next;
 
       state->prog->Instructions[i] = inst->Base;
-      _mesa_free(inst);
-
       inst = temp;
    }
 
@@ -5011,6 +5014,28 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
    state->prog->NumNativeAttributes = state->prog->NumAttributes;
    state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
 
-   return GL_TRUE;
+   result = GL_TRUE;
+
+error:
+   for (inst = state->inst_head; inst != NULL; inst = temp) {
+      temp = inst->next;
+      _mesa_free(inst);
+   }
+
+   state->inst_head = NULL;
+   state->inst_tail = NULL;
+
+   for (sym = state->sym; sym != NULL; sym = temp) {
+      temp = sym->next;
+
+      _mesa_free(sym->name);
+      _mesa_free(sym);
+   }
+   state->sym = NULL;
+
+   _mesa_symbol_table_dtor(state->st);
+   state->st = NULL;
+
+   return result;
 }
 
index 8521a97b4f845311ad2723531868e6edf87bd7e7..92e035997a385de750c4cf34d176b73706c905e5 100644 (file)
@@ -1904,6 +1904,8 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
       }
 
       _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+      s->next = state->sym;
+      state->sym = s;
    }
 
    return s;
@@ -2104,6 +2106,9 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
    struct asm_instruction *inst;
    unsigned i;
    GLubyte *strz;
+   GLboolean result = GL_FALSE;
+   void *temp;
+   struct asm_symbol *sym;
 
    state->ctx = ctx;
    state->prog->Target = target;
@@ -2165,7 +2170,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
 
 
    if (ctx->Program.ErrorPos != -1) {
-      return GL_FALSE;
+      goto error;
    }
 
    if (! _mesa_layout_parameters(state)) {
@@ -2176,7 +2181,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
       loc.position = len;
 
       yyerror(& loc, state, "invalid PARAM usage");
-      return GL_FALSE;
+      goto error;
    }
 
 
@@ -2190,8 +2195,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
       struct asm_instruction *const temp = inst->next;
 
       state->prog->Instructions[i] = inst->Base;
-      _mesa_free(inst);
-
       inst = temp;
    }
 
@@ -2215,5 +2218,27 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
    state->prog->NumNativeAttributes = state->prog->NumAttributes;
    state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
 
-   return GL_TRUE;
+   result = GL_TRUE;
+
+error:
+   for (inst = state->inst_head; inst != NULL; inst = temp) {
+      temp = inst->next;
+      _mesa_free(inst);
+   }
+
+   state->inst_head = NULL;
+   state->inst_tail = NULL;
+
+   for (sym = state->sym; sym != NULL; sym = temp) {
+      temp = sym->next;
+
+      _mesa_free((void *) sym->name);
+      _mesa_free(sym);
+   }
+   state->sym = NULL;
+
+   _mesa_symbol_table_dtor(state->st);
+   state->st = NULL;
+
+   return result;
 }
index b4c24ec92cc4d5e59a1fa0cab6cb369af6ececd6..e17ffd232236e235fe159af620c456d9abacd19c 100644 (file)
@@ -39,6 +39,7 @@ enum asm_type {
 };
 
 struct asm_symbol {
+   struct asm_symbol *next;    /**< List linkage for freeing. */
    const char *name;
    enum asm_type type;
    unsigned attrib_binding;
@@ -134,6 +135,14 @@ struct asm_parser_state {
 
    struct _mesa_symbol_table *st;
 
+   /**
+    * Linked list of symbols
+    *
+    * This list is \b only used when cleaning up compiler state and freeing
+    * memory.
+    */
+   struct asm_symbol *sym;
+
    /**
     * State for the lexer.
     */