summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/shader')
-rw-r--r--src/mesa/shader/program_parse.tab.c35
-rw-r--r--src/mesa/shader/program_parse.y35
-rw-r--r--src/mesa/shader/program_parser.h9
3 files changed, 69 insertions, 10 deletions
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
index 945d77656a4..a49cfeb483c 100644
--- a/src/mesa/shader/program_parse.tab.c
+++ b/src/mesa/shader/program_parse.tab.c
@@ -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;
}
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index 8521a97b4f8..92e035997a3 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -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;
}
diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h
index b4c24ec92cc..e17ffd23223 100644
--- a/src/mesa/shader/program_parser.h
+++ b/src/mesa/shader/program_parser.h
@@ -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;
@@ -135,6 +136,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.
*/
void *scanner;