Merge branch 'mesa_7_6_branch'
This should fix the memory leaks in the assembly parser without the regressions. The conflicts in program_lexer.l were related to changes in returning strings between the branches (always return IDENTIFIER vs. returing either IDENTIFIER or USED_IDENTIFIER). The conflicts in program_parse.y were related to two changes in master One change prints a variable name in an error message. The other change adds outputVarSize to the OUTPUT_statement rule. The cause the position of the IDENTIFIER to change from $2 to $3. Conflicts: src/mesa/shader/lex.yy.c src/mesa/shader/program_lexer.l src/mesa/shader/program_parse.tab.c src/mesa/shader/program_parse.y
This commit is contained in:
@@ -3773,7 +3773,7 @@ static void put_values_ci_ximage( PUT_VALUES_ARGS )
|
|||||||
* else return number of pixels to skip in the destination array.
|
* else return number of pixels to skip in the destination array.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
clip_for_xgetimage(GLcontext *ctx, GLuint *n, GLint *x, GLint *y)
|
clip_for_xgetimage(GLcontext *ctx, XMesaPixmap pixmap, GLuint *n, GLint *x, GLint *y)
|
||||||
{
|
{
|
||||||
XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
||||||
XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
|
XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
|
||||||
@@ -3783,7 +3783,7 @@ clip_for_xgetimage(GLcontext *ctx, GLuint *n, GLint *x, GLint *y)
|
|||||||
GLint dx, dy;
|
GLint dx, dy;
|
||||||
if (source->type == PBUFFER || source->type == PIXMAP)
|
if (source->type == PBUFFER || source->type == PIXMAP)
|
||||||
return 0;
|
return 0;
|
||||||
XTranslateCoordinates(xmesa->display, source->frontxrb->pixmap, rootWin,
|
XTranslateCoordinates(xmesa->display, pixmap, rootWin,
|
||||||
*x, *y, &dx, &dy, &child);
|
*x, *y, &dx, &dy, &child);
|
||||||
if (dx >= screenWidth) {
|
if (dx >= screenWidth) {
|
||||||
/* totally clipped on right */
|
/* totally clipped on right */
|
||||||
@@ -3827,7 +3827,7 @@ get_row_ci(GLcontext *ctx, struct gl_renderbuffer *rb,
|
|||||||
#ifndef XFree86Server
|
#ifndef XFree86Server
|
||||||
XMesaImage *span = NULL;
|
XMesaImage *span = NULL;
|
||||||
int error;
|
int error;
|
||||||
int k = clip_for_xgetimage(ctx, &n, &x, &y);
|
int k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return;
|
return;
|
||||||
index += k;
|
index += k;
|
||||||
@@ -3892,7 +3892,7 @@ get_row_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
|
|||||||
#else
|
#else
|
||||||
int k;
|
int k;
|
||||||
y = YFLIP(xrb, y);
|
y = YFLIP(xrb, y);
|
||||||
k = clip_for_xgetimage(ctx, &n, &x, &y);
|
k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return;
|
return;
|
||||||
rgba += k;
|
rgba += k;
|
||||||
|
@@ -190,7 +190,7 @@ pack_histogram( GLcontext *ctx,
|
|||||||
/* temporarily store as GLuints */
|
/* temporarily store as GLuints */
|
||||||
GLuint temp[4*HISTOGRAM_TABLE_SIZE];
|
GLuint temp[4*HISTOGRAM_TABLE_SIZE];
|
||||||
GLuint *dst = temp;
|
GLuint *dst = temp;
|
||||||
GLhalfARB *half = destination;
|
GLhalfARB *half = (GLhalfARB *) destination;
|
||||||
GLuint i;
|
GLuint i;
|
||||||
/* get GLuint values */
|
/* get GLuint values */
|
||||||
PACK_MACRO(GLuint);
|
PACK_MACRO(GLuint);
|
||||||
|
@@ -87,6 +87,9 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (program->Base.String != NULL)
|
||||||
|
_mesa_free(program->Base.String);
|
||||||
|
|
||||||
/* Copy the relevant contents of the arb_program struct into the
|
/* Copy the relevant contents of the arb_program struct into the
|
||||||
* fragment_program struct.
|
* fragment_program struct.
|
||||||
*/
|
*/
|
||||||
@@ -178,6 +181,9 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (program->Base.String != NULL)
|
||||||
|
_mesa_free(program->Base.String);
|
||||||
|
|
||||||
/* Copy the relevant contents of the arb_program struct into the
|
/* Copy the relevant contents of the arb_program struct into the
|
||||||
* vertex_program struct.
|
* vertex_program struct.
|
||||||
*/
|
*/
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -77,45 +77,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)
|
||||||
{
|
{
|
||||||
@@ -161,7 +122,7 @@ swiz_from_char(char c)
|
|||||||
static int
|
static int
|
||||||
handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
|
handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
|
||||||
{
|
{
|
||||||
lval->string = return_string(state, text);
|
lval->string = strdup(text);
|
||||||
|
|
||||||
return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
|
return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
|
||||||
? IDENTIFIER : USED_IDENTIFIER;
|
? IDENTIFIER : USED_IDENTIFIER;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -309,6 +309,8 @@ option: OPTION string ';'
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
free($2);
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
const char *const err_str = (state->mode == ARB_vertex)
|
const char *const err_str = (state->mode == ARB_vertex)
|
||||||
? "invalid ARB vertex program option"
|
? "invalid ARB vertex program option"
|
||||||
@@ -710,12 +712,17 @@ extSwizSel: INTEGER
|
|||||||
}
|
}
|
||||||
| string
|
| string
|
||||||
{
|
{
|
||||||
|
char s;
|
||||||
|
|
||||||
if (strlen($1) > 1) {
|
if (strlen($1) > 1) {
|
||||||
yyerror(& @1, state, "invalid extended swizzle selector");
|
yyerror(& @1, state, "invalid extended swizzle selector");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($1[0]) {
|
s = $1[0];
|
||||||
|
free($1);
|
||||||
|
|
||||||
|
switch (s) {
|
||||||
case 'x':
|
case 'x':
|
||||||
$$.swz = SWIZZLE_X;
|
$$.swz = SWIZZLE_X;
|
||||||
$$.xyzw_valid = 1;
|
$$.xyzw_valid = 1;
|
||||||
@@ -763,6 +770,8 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
|
|||||||
struct asm_symbol *const s = (struct asm_symbol *)
|
struct asm_symbol *const s = (struct asm_symbol *)
|
||||||
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
||||||
|
|
||||||
|
free($1);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
yyerror(& @1, state, "invalid operand variable");
|
yyerror(& @1, state, "invalid operand variable");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
@@ -845,6 +854,8 @@ dstReg: resultBinding
|
|||||||
struct asm_symbol *const s = (struct asm_symbol *)
|
struct asm_symbol *const s = (struct asm_symbol *)
|
||||||
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
||||||
|
|
||||||
|
free($1);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
yyerror(& @1, state, "invalid operand variable");
|
yyerror(& @1, state, "invalid operand variable");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
@@ -872,6 +883,8 @@ progParamArray: USED_IDENTIFIER
|
|||||||
struct asm_symbol *const s = (struct asm_symbol *)
|
struct asm_symbol *const s = (struct asm_symbol *)
|
||||||
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
||||||
|
|
||||||
|
free($1);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
yyerror(& @1, state, "invalid operand variable");
|
yyerror(& @1, state, "invalid operand variable");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
@@ -943,6 +956,8 @@ addrReg: USED_IDENTIFIER
|
|||||||
struct asm_symbol *const s = (struct asm_symbol *)
|
struct asm_symbol *const s = (struct asm_symbol *)
|
||||||
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
_mesa_symbol_table_find_symbol(state->st, 0, $1);
|
||||||
|
|
||||||
|
free($1);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
yyerror(& @1, state, "invalid array member");
|
yyerror(& @1, state, "invalid array member");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
@@ -1081,6 +1096,7 @@ ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
|
|||||||
declare_variable(state, $2, at_attrib, & @2);
|
declare_variable(state, $2, at_attrib, & @2);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
|
free($2);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else {
|
} else {
|
||||||
s->attrib_binding = $4;
|
s->attrib_binding = $4;
|
||||||
@@ -1188,6 +1204,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
|
|||||||
declare_variable(state, $2, at_param, & @2);
|
declare_variable(state, $2, at_param, & @2);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
|
free($2);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else {
|
} else {
|
||||||
s->param_binding_type = $3.param_binding_type;
|
s->param_binding_type = $3.param_binding_type;
|
||||||
@@ -1201,6 +1218,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
|
|||||||
PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
|
PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
|
||||||
{
|
{
|
||||||
if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
|
if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
|
||||||
|
free($2);
|
||||||
yyerror(& @4, state,
|
yyerror(& @4, state,
|
||||||
"parameter array size and number of bindings must match");
|
"parameter array size and number of bindings must match");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
@@ -1209,6 +1227,7 @@ PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
|
|||||||
declare_variable(state, $2, $6.type, & @2);
|
declare_variable(state, $2, $6.type, & @2);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
|
free($2);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else {
|
} else {
|
||||||
s->param_binding_type = $6.param_binding_type;
|
s->param_binding_type = $6.param_binding_type;
|
||||||
@@ -1943,12 +1962,14 @@ ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
|
|||||||
varNameList: varNameList ',' IDENTIFIER
|
varNameList: varNameList ',' IDENTIFIER
|
||||||
{
|
{
|
||||||
if (!declare_variable(state, $3, $<integer>0, & @3)) {
|
if (!declare_variable(state, $3, $<integer>0, & @3)) {
|
||||||
|
free($3);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{
|
{
|
||||||
if (!declare_variable(state, $1, $<integer>0, & @1)) {
|
if (!declare_variable(state, $1, $<integer>0, & @1)) {
|
||||||
|
free($1);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1960,6 +1981,7 @@ OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
|
|||||||
declare_variable(state, $3, at_output, & @3);
|
declare_variable(state, $3, at_output, & @3);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
|
free($3);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else {
|
} else {
|
||||||
s->output_binding = $5;
|
s->output_binding = $5;
|
||||||
@@ -2136,17 +2158,21 @@ ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
|
|||||||
struct asm_symbol *target = (struct asm_symbol *)
|
struct asm_symbol *target = (struct asm_symbol *)
|
||||||
_mesa_symbol_table_find_symbol(state->st, 0, $4);
|
_mesa_symbol_table_find_symbol(state->st, 0, $4);
|
||||||
|
|
||||||
|
free($4);
|
||||||
|
|
||||||
if (exist != NULL) {
|
if (exist != NULL) {
|
||||||
char m[1000];
|
char m[1000];
|
||||||
_mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
|
_mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
|
||||||
|
free($2);
|
||||||
yyerror(& @2, state, m);
|
yyerror(& @2, state, m);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
} else if (target == NULL) {
|
} else if (target == NULL) {
|
||||||
|
free($2);
|
||||||
yyerror(& @4, state,
|
yyerror(& @4, state,
|
||||||
"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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -2337,14 +2363,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) {
|
||||||
@@ -2592,11 +2614,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();
|
||||||
@@ -2686,6 +2703,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;
|
||||||
@@ -2693,10 +2711,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