prepared parser for direct use of file->buf_ptr - faster comment parsing

This commit is contained in:
bellard 2002-11-22 23:28:06 +00:00
parent cdcfed9737
commit b81d4ba6b3
2 changed files with 76 additions and 33 deletions

106
tcc.c
View file

@ -209,8 +209,8 @@ typedef struct AttributeDef {
#define IO_BUF_SIZE 8192 #define IO_BUF_SIZE 8192
typedef struct BufferedFile { typedef struct BufferedFile {
unsigned char *buf_ptr; uint8_t *buf_ptr;
unsigned char *buf_end; uint8_t *buf_end;
int fd; int fd;
int line_num; /* current line number - here to simply code */ int line_num; /* current line number - here to simply code */
int ifndef_macro; /* #ifndef macro / #endif search */ int ifndef_macro; /* #ifndef macro / #endif search */
@ -1501,7 +1501,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename)
bf->buf_end = bf->buffer; bf->buf_end = bf->buffer;
bf->buffer[0] = CH_EOB; /* put eob symbol */ bf->buffer[0] = CH_EOB; /* put eob symbol */
pstrcpy(bf->filename, sizeof(bf->filename), filename); pstrcpy(bf->filename, sizeof(bf->filename), filename);
bf->line_num = 0; bf->line_num = 1;
bf->ifndef_macro = 0; bf->ifndef_macro = 0;
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
// printf("opening '%s'\n", filename); // printf("opening '%s'\n", filename);
@ -1515,8 +1515,8 @@ void tcc_close(BufferedFile *bf)
tcc_free(bf); tcc_free(bf);
} }
/* fill input buffer and return next char */ /* fill input buffer and peek next char */
int tcc_getc_slow(BufferedFile *bf) static int tcc_peekc_slow(BufferedFile *bf)
{ {
int len; int len;
/* only tries to read if really end of buffer */ /* only tries to read if really end of buffer */
@ -1534,7 +1534,7 @@ int tcc_getc_slow(BufferedFile *bf)
*bf->buf_end = CH_EOB; *bf->buf_end = CH_EOB;
} }
if (bf->buf_ptr < bf->buf_end) { if (bf->buf_ptr < bf->buf_end) {
return *bf->buf_ptr++; return bf->buf_ptr[0];
} else { } else {
bf->buf_ptr = bf->buf_end; bf->buf_ptr = bf->buf_end;
return CH_EOF; return CH_EOF;
@ -1545,15 +1545,15 @@ int tcc_getc_slow(BufferedFile *bf)
void handle_eob(void) void handle_eob(void)
{ {
/* no need to do anything if not at EOB */ /* no need to do anything if not at EOB */
if (file->buf_ptr <= file->buf_end) if (file->buf_ptr < file->buf_end)
return; return;
ch = tcc_getc_slow(file); ch = tcc_peekc_slow(file);
} }
/* read next char from current input file and handle end of input buffer */ /* read next char from current input file and handle end of input buffer */
static inline void inp(void) static inline void inp(void)
{ {
ch = *(file->buf_ptr++); ch = *(++(file->buf_ptr));
/* end of buffer/file handling */ /* end of buffer/file handling */
if (ch == CH_EOB) if (ch == CH_EOB)
handle_eob(); handle_eob();
@ -1596,51 +1596,87 @@ static void parse_line_comment(void)
/* single line C++ comments */ /* single line C++ comments */
/* XXX: accept '\\\n' ? */ /* XXX: accept '\\\n' ? */
inp(); inp();
while (ch != '\n' && ch != TOK_EOF) while (ch != '\n' && ch != CH_EOF)
inp(); inp();
} }
static void parse_comment(void) static void parse_comment(void)
{ {
uint8_t *p;
int c;
/* C comments */ /* C comments */
minp(); minp();
p = file->buf_ptr;
for(;;) { for(;;) {
/* fast skip loop */ /* fast skip loop */
while (ch != '\n' && ch != '*' && ch != TOK_EOF) for(;;) {
inp(); c = *p;
if (c == '\n' || c == '*' || c == '\\')
break;
p++;
c = *p;
if (c == '\n' || c == '*' || c == '\\')
break;
p++;
}
/* now we can handle all the cases */ /* now we can handle all the cases */
if (ch == '\n') { if (c == '\n') {
file->line_num++; file->line_num++;
inp(); p++;
} else if (ch == '*') { } else if (c == '*') {
p++;
for(;;) { for(;;) {
inp(); c = *p;
if (ch == '/') { if (c == '/') {
goto end_of_comment; goto end_of_comment;
} else if (ch == '\\') { } else if (c == '\\') {
inp(); if (p >= file->buf_end) {
if (ch == '\n') { file->buf_ptr = p;
handle_eob();
p = file->buf_ptr;
if (p >= file->buf_end)
goto eof_found;
continue;
}
p++;
c = *p;
if (c == '\n') {
file->line_num++; file->line_num++;
inp(); p++;
} else if (ch == '\r') { } else if (c == '\r') {
inp(); p++;
if (ch != '\n') c = *p;
if (c != '\n')
break; break;
file->line_num++; file->line_num++;
inp(); p++;
} else { } else {
break; break;
} }
} else if (ch != '*') { } else if (c == '*') {
p++;
} else {
break; break;
} }
} }
} else if (p >= file->buf_end) {
file->buf_ptr = p;
handle_eob();
p = file->buf_ptr;
if (p >= file->buf_end) {
eof_found:
error("unexpected end of file in comment");
}
} else { } else {
error("unexpected end of file in comment"); /* stray */
p++;
} }
} }
end_of_comment: end_of_comment:
inp(); p++;
file->buf_ptr = p;
ch = *p;
} }
#define cinp minp #define cinp minp
@ -2127,6 +2163,7 @@ static void preprocess(int is_bof)
} else if (ch == '\"') { } else if (ch == '\"') {
c = ch; c = ch;
read_name: read_name:
/* XXX: better stray handling */
minp(); minp();
q = buf; q = buf;
while (ch != c && ch != '\n' && ch != CH_EOF) { while (ch != c && ch != '\n' && ch != CH_EOF) {
@ -2135,6 +2172,7 @@ static void preprocess(int is_bof)
minp(); minp();
} }
*q = '\0'; *q = '\0';
minp();
#if 0 #if 0
/* eat all spaces and comments after include */ /* eat all spaces and comments after include */
/* XXX: slightly incorrect */ /* XXX: slightly incorrect */
@ -2172,7 +2210,6 @@ static void preprocess(int is_bof)
} }
} }
ch = '\n';
e = search_cached_include(s1, c, buf); e = search_cached_include(s1, c, buf);
if (e && define_find(e->ifndef_macro)) { if (e && define_find(e->ifndef_macro)) {
/* no need to parse the include because the 'ifndef macro' /* no need to parse the include because the 'ifndef macro'
@ -2229,7 +2266,8 @@ static void preprocess(int is_bof)
if (do_debug) { if (do_debug) {
put_stabs(file->filename, N_BINCL, 0, 0, 0); put_stabs(file->filename, N_BINCL, 0, 0, 0);
} }
tok_flags |= TOK_FLAG_BOF; tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
ch = file->buf_ptr[0];
goto the_end; goto the_end;
} }
break; break;
@ -2761,6 +2799,10 @@ static inline void next_nomacro1(void)
goto redo_no_start; goto redo_no_start;
case '\\': case '\\':
/* first look if it is in fact an end of buffer */
handle_eob();
if (ch != '\\')
goto redo_no_start;
handle_stray(); handle_stray();
goto redo_no_start; goto redo_no_start;
@ -7641,7 +7683,7 @@ static int tcc_compile(TCCState *s1)
s1->nb_errors = 0; s1->nb_errors = 0;
s1->error_set_jmp_enabled = 1; s1->error_set_jmp_enabled = 1;
ch = '\n'; /* XXX: suppress that*/ ch = file->buf_ptr[0];
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
next(); next();
decl(VT_CONST); decl(VT_CONST);
@ -7719,7 +7761,7 @@ void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
s1->include_stack_ptr = s1->include_stack; s1->include_stack_ptr = s1->include_stack;
/* parse with define parser */ /* parse with define parser */
ch = '\n'; /* needed to parse correctly first preprocessor command */ ch = file->buf_ptr[0];
next_nomacro(); next_nomacro();
parse_define(); parse_define();
file = NULL; file = NULL;

View file

@ -1890,7 +1890,8 @@ static int tcc_load_ldscript(TCCState *s1)
char filename[1024]; char filename[1024];
int t; int t;
inp(); ch = file->buf_ptr[0];
handle_eob();
for(;;) { for(;;) {
t = ld_next(s1, cmd, sizeof(cmd)); t = ld_next(s1, cmd, sizeof(cmd));
if (t == LD_TOK_EOF) if (t == LD_TOK_EOF)