Revert "ARB prog parser: Fix epic memory leak in lexer / parser interface"
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.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@
|
|||||||
if (condition) { \
|
if (condition) { \
|
||||||
return token; \
|
return token; \
|
||||||
} else { \
|
} else { \
|
||||||
yylval->string = return_string(yyextra, yytext); \
|
yylval->string = strdup(yytext); \
|
||||||
return IDENTIFIER; \
|
return IDENTIFIER; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
|
yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
|
||||||
return token; \
|
return token; \
|
||||||
} else { \
|
} else { \
|
||||||
yylval->string = return_string(yyextra, yytext); \
|
yylval->string = strdup(yytext); \
|
||||||
return IDENTIFIER; \
|
return IDENTIFIER; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -71,45 +71,6 @@
|
|||||||
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
|
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
|
||||||
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
|
static unsigned
|
||||||
mask_from_char(char c)
|
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); }
|
ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
|
||||||
|
|
||||||
[_a-zA-Z$][_a-zA-Z0-9$]* {
|
[_a-zA-Z$][_a-zA-Z0-9$]* {
|
||||||
yylval->string = return_string(yyextra, yytext);
|
yylval->string = strdup(yytext);
|
||||||
return IDENTIFIER;
|
return IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4565,7 +4565,7 @@ yyreduce:
|
|||||||
"undefined variable binding in ALIAS statement");
|
"undefined variable binding in ALIAS statement");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else {
|
} 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;
|
break;
|
||||||
@@ -4896,14 +4896,10 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
|
|||||||
if (exist != NULL) {
|
if (exist != NULL) {
|
||||||
yyerror(locp, state, "redeclared identifier");
|
yyerror(locp, state, "redeclared identifier");
|
||||||
} else {
|
} else {
|
||||||
const size_t name_len = strlen(name);
|
s = calloc(1, sizeof(struct asm_symbol));
|
||||||
|
s->name = name;
|
||||||
s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
|
|
||||||
s->name = (char *)(s + 1);
|
|
||||||
s->type = t;
|
s->type = t;
|
||||||
|
|
||||||
memcpy((char *) s->name, name, name_len + 1);
|
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case at_temp:
|
case at_temp:
|
||||||
if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
|
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);
|
_mesa_memcpy (strz, str, len);
|
||||||
strz[len] = '\0';
|
strz[len] = '\0';
|
||||||
|
|
||||||
if (state->prog->String != NULL) {
|
|
||||||
_mesa_free(state->prog->String);
|
|
||||||
state->prog->String = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
state->prog->String = strz;
|
state->prog->String = strz;
|
||||||
|
|
||||||
state->st = _mesa_symbol_table_ctor();
|
state->st = _mesa_symbol_table_ctor();
|
||||||
@@ -5245,6 +5236,7 @@ error:
|
|||||||
for (sym = state->sym; sym != NULL; sym = temp) {
|
for (sym = state->sym; sym != NULL; sym = temp) {
|
||||||
temp = sym->next;
|
temp = sym->next;
|
||||||
|
|
||||||
|
_mesa_free((void *) sym->name);
|
||||||
_mesa_free(sym);
|
_mesa_free(sym);
|
||||||
}
|
}
|
||||||
state->sym = NULL;
|
state->sym = NULL;
|
||||||
@@ -5252,11 +5244,6 @@ error:
|
|||||||
_mesa_symbol_table_dtor(state->st);
|
_mesa_symbol_table_dtor(state->st);
|
||||||
state->st = NULL;
|
state->st = NULL;
|
||||||
|
|
||||||
if (state->string_dumpster != NULL) {
|
|
||||||
_mesa_free(state->string_dumpster);
|
|
||||||
state->dumpster_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1919,7 +1919,7 @@ ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
|
|||||||
"undefined variable binding in ALIAS statement");
|
"undefined variable binding in ALIAS statement");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else {
|
} 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) {
|
if (exist != NULL) {
|
||||||
yyerror(locp, state, "redeclared identifier");
|
yyerror(locp, state, "redeclared identifier");
|
||||||
} else {
|
} else {
|
||||||
const size_t name_len = strlen(name);
|
s = calloc(1, sizeof(struct asm_symbol));
|
||||||
|
s->name = name;
|
||||||
s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
|
|
||||||
s->name = (char *)(s + 1);
|
|
||||||
s->type = t;
|
s->type = t;
|
||||||
|
|
||||||
memcpy((char *) s->name, name, name_len + 1);
|
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case at_temp:
|
case at_temp:
|
||||||
if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
|
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) {
|
if (state->prog->String != NULL) {
|
||||||
_mesa_free(state->prog->String);
|
_mesa_free(state->prog->String);
|
||||||
state->prog->String = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->prog->String = strz;
|
state->prog->String = strz;
|
||||||
@@ -2376,6 +2371,7 @@ error:
|
|||||||
for (sym = state->sym; sym != NULL; sym = temp) {
|
for (sym = state->sym; sym != NULL; sym = temp) {
|
||||||
temp = sym->next;
|
temp = sym->next;
|
||||||
|
|
||||||
|
_mesa_free((void *) sym->name);
|
||||||
_mesa_free(sym);
|
_mesa_free(sym);
|
||||||
}
|
}
|
||||||
state->sym = NULL;
|
state->sym = NULL;
|
||||||
@@ -2383,10 +2379,5 @@ error:
|
|||||||
_mesa_symbol_table_dtor(state->st);
|
_mesa_symbol_table_dtor(state->st);
|
||||||
state->st = NULL;
|
state->st = NULL;
|
||||||
|
|
||||||
if (state->string_dumpster != NULL) {
|
|
||||||
_mesa_free(state->string_dumpster);
|
|
||||||
state->dumpster_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -38,13 +38,6 @@ enum asm_type {
|
|||||||
at_output,
|
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 {
|
||||||
struct asm_symbol *next; /**< List linkage for freeing. */
|
struct asm_symbol *next; /**< List linkage for freeing. */
|
||||||
const char *name;
|
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
|
* Selected limits copied from gl_constants
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user