Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Cleaned up error position reporting.
  • Loading branch information
icculus committed Nov 11, 2010
1 parent 34ab93c commit 2800d5e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 81 deletions.
62 changes: 24 additions & 38 deletions mojoshader.c
Expand Up @@ -70,10 +70,10 @@ typedef struct Context
MOJOSHADER_malloc malloc;
MOJOSHADER_free free;
void *malloc_data;
int current_position;
const uint32 *orig_tokens;
const uint32 *tokens;
uint32 tokencount;
MOJOSHADER_parsePhase parse_phase;
const MOJOSHADER_swizzle *swizzles;
unsigned int swizzles_count;
Buffer *output;
Expand Down Expand Up @@ -368,36 +368,17 @@ static inline int isfail(const Context *ctx)
} // isfail


// !!! FIXME: move the errpos calculation into Context, and we can move this
// !!! FIXME: to mojoshader_common.c
static void failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
static void failf(Context *ctx, const char *fmt, ...)
{
ctx->isfail = 1;
if (ctx->out_of_memory)
return;

int errpos = 0;
switch (ctx->parse_phase)
{
case MOJOSHADER_PARSEPHASE_NOTSTARTED:
errpos = -2;
break;
case MOJOSHADER_PARSEPHASE_WORKING:
errpos = (ctx->tokens - ctx->orig_tokens) * sizeof (uint32);
break;
case MOJOSHADER_PARSEPHASE_DONE:
errpos = -1;
break;
default:
assert(0 && "Unexpected value");
return;
} // switch

// no filename at this level (we pass a NULL to errorlist_add_va()...)
va_list ap;
va_start(ap, fmt);
errorlist_add_va(ctx->errors, NULL, errpos, fmt, ap);
errorlist_add_va(ctx->errors, NULL, ctx->current_position, fmt, ap);
va_end(ap);
} // failf

Expand Down Expand Up @@ -666,6 +647,13 @@ static int allocate_branch_label(Context *ctx)
return ctx->assigned_branch_labels++;
} // allocate_branch_label

static inline void adjust_token_position(Context *ctx, const int incr)
{
ctx->tokens += incr;
ctx->tokencount -= incr;
ctx->current_position += incr * sizeof (uint32);
} // adjust_token_position


// D3D stuff that's used in more than just the d3d profile...

Expand Down Expand Up @@ -5285,8 +5273,8 @@ static int parse_destination_token(Context *ctx, DestArgInfo *info)
info->regnum += 6144;
} // else if

ctx->tokens++; // swallow token for now, for multiple calls in a row.
ctx->tokencount--; // swallow token for now, for multiple calls in a row.
// swallow token for now, for multiple calls in a row.
adjust_token_position(ctx, 1);

if (reserved1 != 0x0)
fail(ctx, "Reserved bit #1 in destination token must be zero");
Expand Down Expand Up @@ -5517,8 +5505,8 @@ static int parse_source_token(Context *ctx, SourceArgInfo *info)
info->swizzle_z = ((info->swizzle >> 4) & 0x3);
info->swizzle_w = ((info->swizzle >> 6) & 0x3);

ctx->tokens++; // swallow token for now, for multiple calls in a row.
ctx->tokencount--; // swallow token for now, for multiple calls in a row.
// swallow token for now, for multiple calls in a row.
adjust_token_position(ctx, 1);

if (reserved1 != 0x0)
fail(ctx, "Reserved bits #1 in source token must be zero");
Expand All @@ -5538,8 +5526,8 @@ static int parse_source_token(Context *ctx, SourceArgInfo *info)
fail(ctx, "Relative addressing in pixel shader version < 3.0");

const uint32 reltoken = SWAP32(*(ctx->tokens));
ctx->tokens++; // swallow token for now, for multiple calls in a row.
ctx->tokencount--; // swallow token for now, for multiple calls in a row.
// swallow token for now, for multiple calls in a row.
adjust_token_position(ctx, 1);

const int relswiz = (int) ((reltoken >> 16) & 0xFF);
info->relative_regnum = (int) (reltoken & 0x7ff);
Expand Down Expand Up @@ -5756,8 +5744,7 @@ static int parse_args_DCL(Context *ctx)
fail(ctx, "Bit #31 in DCL token must be one");

ctx->centroid_allowed = 1;
ctx->tokens++;
ctx->tokencount--;
adjust_token_position(ctx, 1);
parse_destination_token(ctx, &ctx->dest_arg);
ctx->centroid_allowed = 0;

Expand Down Expand Up @@ -6648,6 +6635,7 @@ static const Instruction instructions[] =
static int parse_instruction_token(Context *ctx)
{
int retval = 0;
const int start_position = ctx->current_position;
const uint32 *start_tokens = ctx->tokens;
const uint32 start_tokencount = ctx->tokencount;
const uint32 token = SWAP32(*(ctx->tokens));
Expand Down Expand Up @@ -6693,8 +6681,7 @@ static int parse_instruction_token(Context *ctx)
ctx->predicated = predicated;

// Update the context with instruction's arguments.
ctx->tokens++;
ctx->tokencount--;
adjust_token_position(ctx, 1);
retval = instruction->parse_args(ctx);

if (predicated)
Expand All @@ -6703,6 +6690,7 @@ static int parse_instruction_token(Context *ctx)
// parse_args() moves these forward for convenience...reset them.
ctx->tokens = start_tokens;
ctx->tokencount = start_tokencount;
ctx->current_position = start_position;

if (instruction->state != NULL)
instruction->state(ctx);
Expand Down Expand Up @@ -6985,7 +6973,7 @@ static Context *build_context(const char *profile,
ctx->endline = ENDLINE_STR;
ctx->endline_len = strlen(ctx->endline);
ctx->last_address_reg_component = -1;
ctx->parse_phase = MOJOSHADER_PARSEPHASE_NOTSTARTED;
ctx->current_position = MOJOSHADER_POSITION_BEFORE;

ctx->errors = errorlist_create(MallocBridge, FreeBridge, ctx);
if (ctx->errors == NULL)
Expand Down Expand Up @@ -7644,7 +7632,7 @@ const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile,
verify_swizzles(ctx);

// Version token always comes first.
ctx->parse_phase = MOJOSHADER_PARSEPHASE_WORKING;
ctx->current_position = 0;
rc = parse_version_token(ctx, profile);

// drop out now if this definitely isn't bytecode. Saves lots of
Expand All @@ -7662,8 +7650,7 @@ const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile,
ctx->tokencount = rc;
} // if

ctx->tokens += rc;
ctx->tokencount -= rc;
adjust_token_position(ctx, rc);

// parse out the rest of the tokens after the version token...
while (ctx->tokencount > 0)
Expand All @@ -7682,11 +7669,10 @@ const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile,
break;
} // if

ctx->tokens += rc;
ctx->tokencount -= rc;
adjust_token_position(ctx, rc);
} // while

ctx->parse_phase = MOJOSHADER_PARSEPHASE_DONE;
ctx->current_position = MOJOSHADER_POSITION_AFTER;

if (!failed)
{
Expand Down
21 changes: 15 additions & 6 deletions mojoshader.h
Expand Up @@ -319,6 +319,13 @@ typedef struct MOJOSHADER_symbol
} MOJOSHADER_symbol;


/*
* These are used with MOJOSHADER_error as special case positions.
*/
#define MOJOSHADER_POSITION_NONE (-3)
#define MOJOSHADER_POSITION_BEFORE (-2)
#define MOJOSHADER_POSITION_AFTER (-1)

typedef struct MOJOSHADER_error
{
/*
Expand All @@ -335,12 +342,14 @@ typedef struct MOJOSHADER_error
const char *filename;

/*
* Position of error, if there is one. Will be -3 if there was no
* error, -2 if there was an error before processing started, and
* -1 if there was an error during final processing. If >= 0,
* MOJOSHADER_parse() sets this to the byte offset (starting at zero) into
* the bytecode you supplied, and MOJOSHADER_assemble() sets this to a
* a line number in the source code you supplied (starting at one).
* Position of error, if there is one. Will be MOJOSHADER_POSITION_NONE if
* there was no error, MOJOSHADER_POSITION_BEFORE if there was an error
* before processing started, and MOJOSHADER_POSITION_AFTER if there was
* an error during final processing. If >= 0, MOJOSHADER_parse() sets
* this to the byte offset (starting at zero) into the bytecode you
* supplied, and MOJOSHADER_assemble(), MOJOSHADER_parseAst(), and
* MOJOSHADER_compile() sets this to a a line number in the source code
* you supplied (starting at one).
*/
int error_position;
} MOJOSHADER_error;
Expand Down
50 changes: 19 additions & 31 deletions mojoshader_assembler.c
Expand Up @@ -40,9 +40,10 @@ typedef struct Context
MOJOSHADER_malloc malloc;
MOJOSHADER_free free;
void *malloc_data;
const char *current_file;
int current_position;
ErrorList *errors;
Preprocessor *preprocessor;
MOJOSHADER_parsePhase parse_phase;
MOJOSHADER_shaderType shader_type;
uint8 major_ver;
uint8 minor_ver;
Expand Down Expand Up @@ -103,39 +104,16 @@ static void FreeBridge(void *ptr, void *data)
} // FreeBridge


// !!! FIXME: move the errpos calculation into Context, and we can move this
// !!! FIXME: to mojoshader_common.c
static void failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
static void failf(Context *ctx, const char *fmt, ...)
{
const char *fname = NULL;
unsigned int linenum = 0;

ctx->isfail = 1;
if (ctx->out_of_memory)
return;

int errpos = 0;
switch (ctx->parse_phase)
{
case MOJOSHADER_PARSEPHASE_NOTSTARTED:
errpos = -2;
break;
case MOJOSHADER_PARSEPHASE_WORKING:
fname = preprocessor_sourcepos(ctx->preprocessor, &linenum);
errpos = (int) linenum;
break;
case MOJOSHADER_PARSEPHASE_DONE:
errpos = -1;
break;
default:
assert(0 && "Unexpected value");
return;
} // switch

va_list ap;
va_start(ap, fmt);
errorlist_add_va(ctx->errors, fname, errpos, fmt, ap);
errorlist_add_va(ctx->errors, ctx->current_file, ctx->current_position, fmt, ap);
va_end(ap);
} // failf

Expand Down Expand Up @@ -197,14 +175,18 @@ static Token nexttoken(Context *ctx)

if (preprocessor_outofmemory(ctx->preprocessor))
{
out_of_memory(ctx);
out_of_memory(ctx); // !!! FIXME: this can go; we're bridged now!
ctx->tokenval = TOKEN_EOI;
ctx->token = NULL;
ctx->tokenlen = 0;
break;
} // if

else if (ctx->tokenval == TOKEN_BAD_CHARS)
unsigned int line;
ctx->current_file = preprocessor_sourcepos(ctx->preprocessor,&line);
ctx->current_position = (int) line;

if (ctx->tokenval == TOKEN_BAD_CHARS)
{
fail(ctx, "Bad characters in source file");
continue;
Expand Down Expand Up @@ -1436,7 +1418,7 @@ static Context *build_context(const char *filename,
ctx->malloc = m;
ctx->free = f;
ctx->malloc_data = d;
ctx->parse_phase = MOJOSHADER_PARSEPHASE_NOTSTARTED;
ctx->current_position = MOJOSHADER_POSITION_BEFORE;

const size_t outblk = sizeof (uint32) * 4 * 64; // 64 4-token instrs.
ctx->output = buffer_create(outblk, MallocBridge, FreeBridge, ctx);
Expand Down Expand Up @@ -1642,7 +1624,10 @@ static void output_comments(Context *ctx, const char **comments,
return;

// make error messages sane if CTAB fails, etc.
ctx->parse_phase = MOJOSHADER_PARSEPHASE_NOTSTARTED;
const char *prev_fname = ctx->current_file;
const int prev_position = ctx->current_position;
ctx->current_file = NULL;
ctx->current_position = MOJOSHADER_POSITION_BEFORE;

const char *creator = "MojoShader revision " MOJOSHADER_CHANGESET;
if (symbol_count > 0)
Expand All @@ -1654,7 +1639,8 @@ static void output_comments(Context *ctx, const char **comments,
for (i = 0; i < comment_count; i++)
output_comment_string(ctx, comments[i]);

ctx->parse_phase = MOJOSHADER_PARSEPHASE_WORKING;
ctx->current_file = prev_fname;
ctx->current_position = prev_position;
} // output_comments


Expand Down Expand Up @@ -1757,7 +1743,6 @@ const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *filename,
return &MOJOSHADER_out_of_mem_data;

// Version token always comes first.
ctx->parse_phase = MOJOSHADER_PARSEPHASE_WORKING;
parse_version_token(ctx);
output_comments(ctx, comments, comment_count, symbols, symbol_count);

Expand All @@ -1766,6 +1751,9 @@ const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *filename,
while ((token = nexttoken(ctx)) != TOKEN_EOI)
parse_token(ctx, token);

ctx->current_file = NULL;
ctx->current_position = MOJOSHADER_POSITION_AFTER;

output_token(ctx, 0x0000FFFF); // end token always 0x0000FFFF.

retval = build_final_assembly(ctx);
Expand Down
6 changes: 0 additions & 6 deletions mojoshader_internal.h
Expand Up @@ -392,12 +392,6 @@ static inline int scalar_register(const MOJOSHADER_shaderType shader_type,
return 0;
} // scalar_register

typedef enum
{
MOJOSHADER_PARSEPHASE_NOTSTARTED,
MOJOSHADER_PARSEPHASE_WORKING,
MOJOSHADER_PARSEPHASE_DONE,
} MOJOSHADER_parsePhase;

extern MOJOSHADER_error MOJOSHADER_out_of_mem_error;
extern MOJOSHADER_parseData MOJOSHADER_out_of_mem_data;
Expand Down

0 comments on commit 2800d5e

Please sign in to comment.