- Create a dummy program to keep from segfaulting when parsing

fails
	- Change to grammar .emit to fix single LOCAL/ENV param usage
This commit is contained in:
Karl Rasche 2003-11-23 17:54:39 +00:00
parent 15955f1c5e
commit 4eebfa14e7
4 changed files with 95 additions and 53 deletions

View file

@ -189,24 +189,6 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
retval = _mesa_parse_arb_program(ctx, str, len, &ap);
/* XXX: Parse error. Cleanup things and return */
if (retval)
{
return;
}
/* XXX: Eh.. we parsed something that wasn't a fragment program. doh! */
if (ap.type != GL_FRAGMENT_PROGRAM_ARB)
{
return;
}
#if DEBUG_FP
debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions);
#else
(void) debug_fp_inst;
#endif
/* copy the relvant contents of the arb_program struct into the
* fragment_program struct
*/
@ -216,7 +198,6 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
program->Base.NumAttributes = ap.Base.NumAttributes;
program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
program->Instructions = ap.FPInstructions;
program->InputsRead = ap.InputsRead;
program->OutputsWritten = ap.OutputsWritten;
for (retval=0; retval<MAX_TEXTURE_IMAGE_UNITS; retval++)
@ -225,4 +206,32 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
program->NumTexInstructions = ap.NumTexInstructions;
program->NumTexIndirections = ap.NumTexIndirections;
program->Parameters = ap.Parameters;
/* XXX: Parse error. Cleanup things and return */
if (retval)
{
program->Instructions = (struct fp_instruction *) _mesa_malloc (
sizeof(struct fp_instruction) );
program->Instructions[0].Opcode = FP_OPCODE_END;
return;
}
/* XXX: Eh.. we parsed something that wasn't a fragment program. doh! */
if (ap.type != GL_FRAGMENT_PROGRAM_ARB)
{
program->Instructions = (struct fp_instruction *) _mesa_malloc (
sizeof(struct fp_instruction) );
program->Instructions[0].Opcode = FP_OPCODE_END;
_mesa_error (ctx, GL_INVALID_OPERATION, "Parsed a non-fragment program as a fragment program");
return;
}
#if DEBUG_FP
debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions);
#else
(void) debug_fp_inst;
#endif
program->Instructions = ap.FPInstructions;
}

View file

@ -87,7 +87,7 @@
*
* Cosmetic Stuff
* -----------------------------------------------------
* - fix compiler warnings
* - fix compiler warnings
* - remove any leftover unused grammer.c stuff (dict_ ?)
* - fix grammer.c error handling so its not static
* - #ifdef around stuff pertaining to extentions
@ -107,6 +107,21 @@
* " exponent .or .true .emit '1' .emit 0x00 .emit $;\n"
*
* - XXX: need to recognize "1" as a valid float ?
* - XXX: this fails:
* "MUL result.color.xyz, R0, program.local[35] ;"
* but this works:
* "MUL result.color.primary.xyz, R0, program.local[35] ;"
* -> see progs/tests/arbvptorus.c
*
* - changed "progLocalParam\n" changed from:
* " \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum
* .and rbracket;\n"
* to:
* " \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum
* .and rbracket .emit 0x00;\n"
* so we can distinguish between the progLocalParam and progLocalParams rules
*
* - made the same change as above to the progEnvParam rule
*/
typedef GLubyte *production;
@ -3437,6 +3452,7 @@ parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
case PROGRAM_PARAM_ENV:
state_tokens[1] = STATE_ENV;
state_tokens[2] = parse_integer (inst, Program);
/* Check state_tokens[2] against the number of ENV parameters available */
if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
(state_tokens[2] >= ctx->Const.MaxFragmentProgramEnvParams))
@ -3456,6 +3472,7 @@ parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
case PROGRAM_PARAM_LOCAL:
state_tokens[1] = STATE_LOCAL;
state_tokens[2] = parse_integer (inst, Program);
/* Check state_tokens[2] against the number of LOCAL parameters available */
if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
(state_tokens[2] >= ctx->Const.MaxFragmentProgramLocalParams))
@ -3764,6 +3781,7 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
switch (*(*inst)++) {
case PARAM_STATE_ELEMENT:
if (parse_state_single_item (ctx, inst, Program, state_tokens))
return 1;
@ -3799,6 +3817,7 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
break;
case PARAM_PROGRAM_ELEMENT:
if (parse_program_single_item (ctx, inst, Program, state_tokens))
return 1;
idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
@ -3847,6 +3866,10 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
Program->Base.NumParameters++;
}
}
else
{
(*(*inst)++);
}
break;
case PARAM_CONSTANT:
@ -3983,7 +4006,6 @@ parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
*/
param_var->param_binding_type = PROGRAM_STATE_VAR;
var_cache_append (vc_head, param_var);
/* Then fill it with juicy parameter goodness */
@ -4257,8 +4279,8 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
/* If the name has never been added to our symbol table, we're hosed */
if (!result) {
_mesa_set_program_error (ctx, Program->Position,
"Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
"0: Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",
dst->name);
return 1;
}
@ -4329,10 +4351,10 @@ parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
dst = parse_string (inst, vc_head, Program, &result);
Program->Position = parse_position (inst);
/* If the name has never been added to our symbol table, we're hosed */
/* If the name has never been added to our symbol table, we're hosed */
if (!result) {
_mesa_set_program_error (ctx, Program->Position, "Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
_mesa_set_program_error (ctx, Program->Position, "1: Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION, "1: Undefined variable: %s",
dst->name);
return 1;
}
@ -4470,7 +4492,6 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
break;
case REGISTER_PARAM:
switch (**inst) {
case PARAM_ARRAY_ELEMENT:
*(*inst)++;
@ -4479,9 +4500,9 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
if (!found) {
_mesa_set_program_error (ctx, Program->Position,
"Undefined variable");
"2: Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION,
"Undefined variable: %s", src->name);
"2: Undefined variable: %s", src->name);
return 1;
}
@ -4511,6 +4532,7 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
break;
default:
if (parse_param_use (ctx, inst, vc_head, Program, &src))
return 1;
@ -4521,14 +4543,15 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
break;
case REGISTER_ESTABLISHED_NAME:
src = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
/* If the name has never been added to our symbol table, we're hosed */
if (!found) {
_mesa_set_program_error (ctx, Program->Position,
"Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
"3: Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",
src->name);
return 1;
}
@ -4589,7 +4612,7 @@ parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
/* finally, the swizzle */
parse_swizzle_mask (inst, Swizzle, 4);
return 0;
}

View file

@ -966,7 +966,7 @@ static char arb_grammar_text[] = ".syntax program;\n"
"progEnvParamNums_2\n"
" progEnvParamNum .and .true .emit 0x00;\n"
"progEnvParam\n"
" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket;\n"
" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n"
"progLocalParams\n"
" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n"
"progLocalParamNums\n"
@ -976,7 +976,7 @@ static char arb_grammar_text[] = ".syntax program;\n"
"progLocalParamNums_2\n"
" progLocalParamNum .and .true .emit 0x00;\n"
"progLocalParam\n"
" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket;\n"
" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n"
"progEnvParamNum\n"
" integer;\n"
"progLocalParamNum\n"

View file

@ -178,24 +178,6 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
retval = _mesa_parse_arb_program(ctx, str, len, &ap);
/* XXX: Parse error. Cleanup things and return */
if (retval)
{
return;
}
/* XXX: Eh.. we parsed something that wasn't a vertex program. doh! */
if (ap.type != GL_VERTEX_PROGRAM_ARB)
{
return;
}
#if DEBUG_VP
debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
#else
(void) debug_vp_inst;
#endif
/* copy the relvant contents of the arb_program struct into the
* fragment_program struct
*/
@ -205,9 +187,37 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
program->Base.NumAttributes = ap.Base.NumAttributes;
program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
program->Instructions = ap.VPInstructions;
program->IsPositionInvariant = ap.HintPositionInvariant;
program->InputsRead = ap.InputsRead;
program->OutputsWritten = ap.OutputsWritten;
program->Parameters = ap.Parameters;
/* Parse error. Allocate a dummy program and return */
if (retval)
{
program->Instructions = (struct vp_instruction *) _mesa_malloc (
sizeof(struct vp_instruction) );
program->Instructions[0].Opcode = VP_OPCODE_END;
return;
}
/* Eh.. we parsed something that wasn't a vertex program. doh! */
if (ap.type != GL_VERTEX_PROGRAM_ARB)
{
program->Instructions = (struct vp_instruction *) _mesa_malloc (
sizeof(struct vp_instruction) );
program->Instructions[0].Opcode = VP_OPCODE_END;
_mesa_error (ctx, GL_INVALID_OPERATION, "Parsed a non-vertex program as a vertex program");
return;
}
program->Instructions = ap.VPInstructions;
#if DEBUG_VP
debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
#else
(void) debug_vp_inst;
#endif
}