This reverts commit 93dae6761b
.
This change was completely broken when the parser uses multiple
strings in a single production. It would be nice if bug fixes could
initially land somewhere other than the stable branch.
tags/mesa_7_6_1_rc1
@@ -40,7 +40,7 @@ | |||
if (condition) { \ | |||
return token; \ | |||
} else { \ | |||
yylval->string = return_string(yyextra, yytext); \ | |||
yylval->string = strdup(yytext); \ | |||
return IDENTIFIER; \ | |||
} \ | |||
} while (0) | |||
@@ -63,7 +63,7 @@ | |||
yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \ | |||
return token; \ | |||
} else { \ | |||
yylval->string = return_string(yyextra, yytext); \ | |||
yylval->string = strdup(yytext); \ | |||
return IDENTIFIER; \ | |||
} \ | |||
} while (0) | |||
@@ -71,45 +71,6 @@ | |||
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ | |||
SWIZZLE_NIL, SWIZZLE_NIL) | |||
/** | |||
* Send a string to the parser using asm_parser_state::string_dumpster | |||
* | |||
* Sends a string to the parser using asm_parser_state::string_dumpster as a | |||
* temporary storage buffer. Data previously stored in | |||
* asm_parser_state::string_dumpster will be lost. If | |||
* asm_parser_state::string_dumpster is not large enough to hold the new | |||
* string, the buffer size will be increased. The buffer size is \b never | |||
* decreased. | |||
* | |||
* \param state Assembler parser state tracking | |||
* \param str String to be passed to the parser | |||
* | |||
* \return | |||
* A pointer to asm_parser_state::string_dumpster on success or \c NULL on | |||
* failure. Currently the only failure case is \c ENOMEM. | |||
*/ | |||
static char * | |||
return_string(struct asm_parser_state *state, const char *str) | |||
{ | |||
const size_t len = strlen(str); | |||
if (len >= state->dumpster_size) { | |||
char *const dumpster = _mesa_realloc(state->string_dumpster, | |||
state->dumpster_size, | |||
len + 1); | |||
if (dumpster == NULL) { | |||
return NULL; | |||
} | |||
state->string_dumpster = dumpster; | |||
state->dumpster_size = len + 1; | |||
} | |||
memcpy(state->string_dumpster, str, len + 1); | |||
return state->string_dumpster; | |||
} | |||
static unsigned | |||
mask_from_char(char c) | |||
{ | |||
@@ -347,7 +308,7 @@ ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require | |||
ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); } | |||
[_a-zA-Z$][_a-zA-Z0-9$]* { | |||
yylval->string = return_string(yyextra, yytext); | |||
yylval->string = strdup(yytext); | |||
return IDENTIFIER; | |||
} | |||
@@ -4565,7 +4565,7 @@ yyreduce: | |||
"undefined variable binding in ALIAS statement"); | |||
YYERROR; | |||
} else { | |||
_mesa_symbol_table_add_symbol(state->st, 0, strdup((yyvsp[(2) - (4)].string)), target); | |||
_mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target); | |||
} | |||
;} | |||
break; | |||
@@ -4896,14 +4896,10 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, | |||
if (exist != NULL) { | |||
yyerror(locp, state, "redeclared identifier"); | |||
} else { | |||
const size_t name_len = strlen(name); | |||
s = calloc(1, sizeof(struct asm_symbol) + name_len + 1); | |||
s->name = (char *)(s + 1); | |||
s = calloc(1, sizeof(struct asm_symbol)); | |||
s->name = name; | |||
s->type = t; | |||
memcpy((char *) s->name, name, name_len + 1); | |||
switch (t) { | |||
case at_temp: | |||
if (state->prog->NumTemporaries >= state->limits->MaxTemps) { | |||
@@ -5151,11 +5147,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, | |||
_mesa_memcpy (strz, str, len); | |||
strz[len] = '\0'; | |||
if (state->prog->String != NULL) { | |||
_mesa_free(state->prog->String); | |||
state->prog->String = NULL; | |||
} | |||
state->prog->String = strz; | |||
state->st = _mesa_symbol_table_ctor(); | |||
@@ -5245,6 +5236,7 @@ error: | |||
for (sym = state->sym; sym != NULL; sym = temp) { | |||
temp = sym->next; | |||
_mesa_free((void *) sym->name); | |||
_mesa_free(sym); | |||
} | |||
state->sym = NULL; | |||
@@ -5252,11 +5244,6 @@ error: | |||
_mesa_symbol_table_dtor(state->st); | |||
state->st = NULL; | |||
if (state->string_dumpster != NULL) { | |||
_mesa_free(state->string_dumpster); | |||
state->dumpster_size = 0; | |||
} | |||
return result; | |||
} | |||
@@ -1919,7 +1919,7 @@ ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER | |||
"undefined variable binding in ALIAS statement"); | |||
YYERROR; | |||
} else { | |||
_mesa_symbol_table_add_symbol(state->st, 0, strdup($2), target); | |||
_mesa_symbol_table_add_symbol(state->st, 0, $2, target); | |||
} | |||
} | |||
; | |||
@@ -2027,14 +2027,10 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, | |||
if (exist != NULL) { | |||
yyerror(locp, state, "redeclared identifier"); | |||
} else { | |||
const size_t name_len = strlen(name); | |||
s = calloc(1, sizeof(struct asm_symbol) + name_len + 1); | |||
s->name = (char *)(s + 1); | |||
s = calloc(1, sizeof(struct asm_symbol)); | |||
s->name = name; | |||
s->type = t; | |||
memcpy((char *) s->name, name, name_len + 1); | |||
switch (t) { | |||
case at_temp: | |||
if (state->prog->NumTemporaries >= state->limits->MaxTemps) { | |||
@@ -2284,7 +2280,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, | |||
if (state->prog->String != NULL) { | |||
_mesa_free(state->prog->String); | |||
state->prog->String = NULL; | |||
} | |||
state->prog->String = strz; | |||
@@ -2376,6 +2371,7 @@ error: | |||
for (sym = state->sym; sym != NULL; sym = temp) { | |||
temp = sym->next; | |||
_mesa_free((void *) sym->name); | |||
_mesa_free(sym); | |||
} | |||
state->sym = NULL; | |||
@@ -2383,10 +2379,5 @@ error: | |||
_mesa_symbol_table_dtor(state->st); | |||
state->st = NULL; | |||
if (state->string_dumpster != NULL) { | |||
_mesa_free(state->string_dumpster); | |||
state->dumpster_size = 0; | |||
} | |||
return result; | |||
} |
@@ -38,13 +38,6 @@ enum asm_type { | |||
at_output, | |||
}; | |||
/** | |||
* \note | |||
* Objects of this type are allocated as the object plus the name of the | |||
* symbol. That is, malloc(sizeof(struct asm_symbol) + strlen(name) + 1). | |||
* Alternately, asm_symbol::name could be moved to the bottom of the structure | |||
* and declared as 'char name[0];'. | |||
*/ | |||
struct asm_symbol { | |||
struct asm_symbol *next; /**< List linkage for freeing. */ | |||
const char *name; | |||
@@ -164,15 +157,6 @@ struct asm_parser_state { | |||
/*@}*/ | |||
/** | |||
* Buffer to hold strings transfered from the lexer to the parser | |||
*/ | |||
/*@{*/ | |||
char *string_dumpster; /**< String data transfered. */ | |||
size_t dumpster_size; /**< Total size, in bytes, of the buffer. */ | |||
/*@}*/ | |||
/** | |||
* Selected limits copied from gl_constants | |||
* |