Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
b919612b
Commit
b919612b
authored
Jul 02, 2011
by
Pieter Noordhuis
Browse files
Cut down on conditional jumps
parent
dcb783ab
Changes
1
Show whitespace changes
Inline
Side-by-side
parser.c
View file @
b919612b
...
@@ -48,6 +48,18 @@ static const char * strstate[] = {
...
@@ -48,6 +48,18 @@ static const char * strstate[] = {
};
};
#undef _ENUM_GEN
#undef _ENUM_GEN
#define TRANSITION(st) do { \
state = s_##st; \
pos++; nread++; \
if (pos < end) { \
ch = *pos; \
goto l_##st; \
} \
\
/* No more data */
\
goto finalize; \
} while(0)
#ifdef DEBUG
#ifdef DEBUG
#define LOG(fmt, args...) do { \
#define LOG(fmt, args...) do { \
fprintf(stderr, fmt "\n" , ## args); \
fprintf(stderr, fmt "\n" , ## args); \
...
@@ -147,24 +159,19 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -147,24 +159,19 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
switch
(
ch
)
{
switch
(
ch
)
{
case
'$'
:
case
'$'
:
cur
->
type
=
REDIS_STRING_T
;
cur
->
type
=
REDIS_STRING_T
;
state
=
s_integer_sign
;
TRANSITION
(
integer_sign
);
break
;
case
'*'
:
case
'*'
:
cur
->
type
=
REDIS_ARRAY_T
;
cur
->
type
=
REDIS_ARRAY_T
;
state
=
s_integer_sign
;
TRANSITION
(
integer_sign
);
break
;
case
':'
:
case
':'
:
cur
->
type
=
REDIS_INTEGER_T
;
cur
->
type
=
REDIS_INTEGER_T
;
state
=
s_integer_sign
;
TRANSITION
(
integer_sign
);
break
;
case
'+'
:
case
'+'
:
cur
->
type
=
REDIS_STATUS_T
;
cur
->
type
=
REDIS_STATUS_T
;
state
=
s_line
;
assert
(
NULL
);
break
;
case
'-'
:
case
'-'
:
cur
->
type
=
REDIS_ERROR_T
;
cur
->
type
=
REDIS_ERROR_T
;
state
=
s_line
;
assert
(
NULL
);
break
;
default:
default:
goto
error
;
goto
error
;
}
}
...
@@ -172,17 +179,23 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -172,17 +179,23 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
}
}
case
s_integer_sign
:
case
s_integer_sign
:
l_integer_sign:
{
{
i64
.
neg
=
(
ch
==
'-'
);
i64
.
neg
=
(
ch
==
'-'
);
i64
.
ui64
=
0
;
i64
.
ui64
=
0
;
state
=
s_integer_start
;
/* Break when char was consumed */
/* Break when char was consumed */
if
(
ch
==
'-'
||
ch
==
'+'
)
if
(
ch
==
'-'
||
ch
==
'+'
)
{
break
;
TRANSITION
(
integer_start
);
}
/* First integer character */
if
(
ch
>=
'1'
&&
ch
<=
'9'
)
{
i64
.
ui64
=
ch
-
'0'
;
TRANSITION
(
integer_body
);
}
/* Char was not consumed, jump to s_integer_start */
goto
error
;
goto
l_integer_start
;
}
}
case
s_integer_start
:
case
s_integer_start
:
...
@@ -190,14 +203,14 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -190,14 +203,14 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
{
{
if
(
ch
>=
'1'
&&
ch
<=
'9'
)
{
if
(
ch
>=
'1'
&&
ch
<=
'9'
)
{
i64
.
ui64
=
ch
-
'0'
;
i64
.
ui64
=
ch
-
'0'
;
state
=
s_integer_body
;
TRANSITION
(
integer_body
);
}
else
{
goto
error
;
}
}
break
;
goto
error
;
}
}
case
s_integer_body
:
case
s_integer_body
:
l_integer_body:
{
{
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
{
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
{
if
(
i64
.
ui64
>
(
UINT64_MAX
/
10
))
/* Overflow */
if
(
i64
.
ui64
>
(
UINT64_MAX
/
10
))
/* Overflow */
...
@@ -206,6 +219,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -206,6 +219,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
if
(
i64
.
ui64
>
(
UINT64_MAX
-
(
ch
-
'0'
)))
/* Overflow */
if
(
i64
.
ui64
>
(
UINT64_MAX
-
(
ch
-
'0'
)))
/* Overflow */
goto
error
;
goto
error
;
i64
.
ui64
+=
ch
-
'0'
;
i64
.
ui64
+=
ch
-
'0'
;
TRANSITION
(
integer_body
);
}
else
if
(
ch
==
'\r'
)
{
}
else
if
(
ch
==
'\r'
)
{
/* Check if the uint64_t can be safely casted to int64_t */
/* Check if the uint64_t can be safely casted to int64_t */
if
(
i64
.
neg
)
{
if
(
i64
.
neg
)
{
...
@@ -217,15 +231,14 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -217,15 +231,14 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
goto
error
;
goto
error
;
i64
.
i64
=
i64
.
ui64
;
i64
.
i64
=
i64
.
ui64
;
}
}
TRANSITION
(
integer_lf
);
}
state
=
s_integer_lf
;
}
else
{
goto
error
;
goto
error
;
}
}
break
;
}
case
s_integer_lf
:
case
s_integer_lf
:
l_integer_lf:
{
{
if
(
ch
!=
'\n'
)
{
if
(
ch
!=
'\n'
)
{
goto
error
;
goto
error
;
...
@@ -241,7 +254,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -241,7 +254,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
case
REDIS_ARRAY_T
:
goto
l_integer_lf_array_t
;
case
REDIS_ARRAY_T
:
goto
l_integer_lf_array_t
;
case
REDIS_INTEGER_T
:
goto
l_integer_lf_integer_t
;
case
REDIS_INTEGER_T
:
goto
l_integer_lf_integer_t
;
default:
default:
assert
(
NULL
);
assert
(
NULL
&&
"unexpected object type in s_integer_lf"
);
goto
error
;
goto
error
;
}
}
...
@@ -284,6 +297,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -284,6 +297,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
}
}
case
s_bulk
:
case
s_bulk
:
l_bulk:
{
{
size_t
len
=
cur
->
remaining
;
size_t
len
=
cur
->
remaining
;
...
@@ -300,11 +314,11 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
...
@@ -300,11 +314,11 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
goto
error
;
goto
error
;
}
}
state
=
s_bulk_lf
;
TRANSITION
(
bulk_lf
);
break
;
}
}
case
s_bulk_lf
:
case
s_bulk_lf
:
l_bulk_lf:
{
{
if
(
ch
!=
'\n'
)
{
if
(
ch
!=
'\n'
)
{
goto
error
;
goto
error
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment