One weird trick: set a bogus error value in the parser impl
This makes us faster under both gcc and clang somehow.
This commit is contained in:
parent
1aab4752e2
commit
3d22a2d845
|
@ -136,6 +136,9 @@ public:
|
||||||
/** Return address of each open { or [ */
|
/** Return address of each open { or [ */
|
||||||
std::unique_ptr<internal::ret_address[]> ret_address{};
|
std::unique_ptr<internal::ret_address[]> ret_address{};
|
||||||
|
|
||||||
|
/** Error code, used ENTIRELY to make gcc not be slower than before. Not actually consumed. */
|
||||||
|
error_code error{UNINITIALIZED};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The largest document this parser can support without reallocating.
|
* The largest document this parser can support without reallocating.
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct streaming_structural_parser: structural_parser {
|
||||||
advance_char();
|
advance_char();
|
||||||
// Push the root scope (there is always at least one scope)
|
// Push the root scope (there is always at least one scope)
|
||||||
if (start_document(finish_parser)) {
|
if (start_document(finish_parser)) {
|
||||||
return DEPTH_ERROR;
|
return parser.error = DEPTH_ERROR;
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -21,16 +21,16 @@ struct streaming_structural_parser: structural_parser {
|
||||||
WARN_UNUSED really_inline error_code finish() {
|
WARN_UNUSED really_inline error_code finish() {
|
||||||
if ( structurals.past_end(parser.n_structural_indexes) ) {
|
if ( structurals.past_end(parser.n_structural_indexes) ) {
|
||||||
log_error("IMPOSSIBLE: past the end of the JSON!");
|
log_error("IMPOSSIBLE: past the end of the JSON!");
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
end_document();
|
end_document();
|
||||||
if (depth != 0) {
|
if (depth != 0) {
|
||||||
log_error("Unclosed objects or arrays!");
|
log_error("Unclosed objects or arrays!");
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
if (parser.containing_scope[depth].tape_index != 0) {
|
if (parser.containing_scope[depth].tape_index != 0) {
|
||||||
log_error("IMPOSSIBLE: root scope tape index did not start at 0!");
|
log_error("IMPOSSIBLE: root scope tape index did not start at 0!");
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
bool finished = structurals.at_end(parser.n_structural_indexes);
|
bool finished = structurals.at_end(parser.n_structural_indexes);
|
||||||
if (!finished) { log_value("(and has more)"); }
|
if (!finished) { log_value("(and has more)"); }
|
||||||
|
|
|
@ -272,16 +272,16 @@ struct structural_parser {
|
||||||
// the string might not be NULL terminated.
|
// the string might not be NULL terminated.
|
||||||
if ( !structurals.at_end(parser.n_structural_indexes) ) {
|
if ( !structurals.at_end(parser.n_structural_indexes) ) {
|
||||||
log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!");
|
log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!");
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
end_document();
|
end_document();
|
||||||
if (depth != 0) {
|
if (depth != 0) {
|
||||||
log_error("Unclosed objects or arrays!");
|
log_error("Unclosed objects or arrays!");
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
if (parser.containing_scope[depth].tape_index != 0) {
|
if (parser.containing_scope[depth].tape_index != 0) {
|
||||||
log_error("IMPOSSIBLE: root scope tape index did not start at 0!");
|
log_error("IMPOSSIBLE: root scope tape index did not start at 0!");
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -299,11 +299,11 @@ struct structural_parser {
|
||||||
* carefully,
|
* carefully,
|
||||||
* all without any added cost. */
|
* all without any added cost. */
|
||||||
if (depth >= parser.max_depth()) {
|
if (depth >= parser.max_depth()) {
|
||||||
return DEPTH_ERROR;
|
return parser.error = DEPTH_ERROR;
|
||||||
}
|
}
|
||||||
switch (structurals.current_char()) {
|
switch (structurals.current_char()) {
|
||||||
case '"':
|
case '"':
|
||||||
return STRING_ERROR;
|
return parser.error = STRING_ERROR;
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
|
@ -315,34 +315,35 @@ struct structural_parser {
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
case '-':
|
case '-':
|
||||||
return NUMBER_ERROR;
|
return parser.error = NUMBER_ERROR;
|
||||||
case 't':
|
case 't':
|
||||||
return T_ATOM_ERROR;
|
return parser.error = T_ATOM_ERROR;
|
||||||
case 'n':
|
case 'n':
|
||||||
return N_ATOM_ERROR;
|
return parser.error = N_ATOM_ERROR;
|
||||||
case 'f':
|
case 'f':
|
||||||
return F_ATOM_ERROR;
|
return parser.error = F_ATOM_ERROR;
|
||||||
default:
|
default:
|
||||||
return TAPE_ERROR;
|
return parser.error = TAPE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
really_inline void init() {
|
really_inline void init() {
|
||||||
current_string_buf_loc = parser.doc->string_buf.get();
|
current_string_buf_loc = parser.doc->string_buf.get();
|
||||||
parser.current_loc = 0;
|
parser.current_loc = 0;
|
||||||
|
parser.error = UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED really_inline error_code start(size_t len, ret_address finish_state) {
|
WARN_UNUSED really_inline error_code start(size_t len, ret_address finish_state) {
|
||||||
log_start();
|
log_start();
|
||||||
init(); // sets is_valid to false
|
init(); // sets is_valid to false
|
||||||
if (len > parser.capacity()) {
|
if (len > parser.capacity()) {
|
||||||
return CAPACITY;
|
return parser.error = CAPACITY;
|
||||||
}
|
}
|
||||||
// Advance to the first character as soon as possible
|
// Advance to the first character as soon as possible
|
||||||
structurals.advance_char();
|
structurals.advance_char();
|
||||||
// Push the root scope (there is always at least one scope)
|
// Push the root scope (there is always at least one scope)
|
||||||
if (start_document(finish_state)) {
|
if (start_document(finish_state)) {
|
||||||
return DEPTH_ERROR;
|
return parser.error = DEPTH_ERROR;
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue