From 5a3c3134ec63957ab85e40dd3e9a54d1fd90145a Mon Sep 17 00:00:00 2001 From: John Keiser Date: Thu, 6 Aug 2020 16:46:11 -0700 Subject: [PATCH] Move value into common place to be shared across states --- src/generic/stage2/structural_parser.h | 104 ++++++++++--------------- 1 file changed, 42 insertions(+), 62 deletions(-) diff --git a/src/generic/stage2/structural_parser.h b/src/generic/stage2/structural_parser.h index 1fe89612..72dd1cf8 100644 --- a/src/generic/stage2/structural_parser.h +++ b/src/generic/stage2/structural_parser.h @@ -68,6 +68,8 @@ struct structural_parser : structural_iterator { template SIMDJSON_WARN_UNUSED simdjson_really_inline error_code structural_parser::walk_document(T &visitor) noexcept { + const uint8_t *value; + logger::log_start(); // @@ -79,69 +81,61 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code structural_parser::walk_d // // Read first value // - { - const uint8_t *value = advance(); - - // Make sure the outer hash or array is closed before continuing; otherwise, there are ways we - // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 - if (!STREAMING) { - switch (*value) { - case '{': - if (last_structural() != '}') { - return TAPE_ERROR; - } - break; - case '[': - if (last_structural() != ']') { - return TAPE_ERROR; - } - break; - } - } + value = advance(); + // Make sure the outer hash or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { switch (*value) { - case '{': if (!empty_object(visitor)) { goto object_begin; }; break; - case '[': if (!empty_array(visitor)) { goto array_begin; }; break; - default: SIMDJSON_TRY( visitor.parse_root_primitive(*this, value) ); + case '{': + if (last_structural() != '}') { + return TAPE_ERROR; + } + break; + case '[': + if (last_structural() != ']') { + return TAPE_ERROR; + } + break; } - goto document_end; } + switch (*value) { + case '{': if (!empty_object(visitor)) { goto object_begin; }; break; + case '[': if (!empty_array(visitor)) { goto array_begin; }; break; + default: SIMDJSON_TRY( visitor.parse_root_primitive(*this, value) ); + } + goto document_end; + // // Object parser states // -object_begin: { +object_begin: depth++; if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } visitor.start_object(*this); - const uint8_t *key = advance(); - if (*key != '"') { - log_error("Object does not start with a key"); - return TAPE_ERROR; - } + value = advance(); + if (*value != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } visitor.increment_count(*this); - SIMDJSON_TRY( visitor.parse_key(*this, key) ); + SIMDJSON_TRY( visitor.parse_key(*this, value) ); goto object_field; -} // object_begin: -object_field: { +object_field: if (simdjson_unlikely( advance_char() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } - const uint8_t *value = advance(); - switch (*value) { + switch (*(value = advance())) { case '{': if (!empty_object(visitor)) { goto object_begin; }; break; case '[': if (!empty_array(visitor)) { goto array_begin; }; break; default: SIMDJSON_TRY( visitor.parse_primitive(*this, value) ); } -} // object_field: -object_continue: { +object_continue: switch (advance_char()) { case ',': { visitor.increment_count(*this); - const uint8_t *key = advance(); - if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } - SIMDJSON_TRY( visitor.parse_key(*this, key) ); + value = advance(); + if (simdjson_unlikely( *value != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.parse_key(*this, value) ); goto object_field; } case '}': @@ -151,50 +145,37 @@ object_continue: { log_error("No comma between object fields"); return TAPE_ERROR; } -} // object_continue: -scope_end: { +scope_end: depth--; if (depth == 0) { goto document_end; } if (dom_parser.is_array[depth]) { goto array_continue; } goto object_continue; -} // scope_end: // // Array parser states // -array_begin: { +array_begin: depth++; if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } visitor.start_array(*this); - visitor.increment_count(*this); -} // array_begin: -array_value: { - const uint8_t *value = advance(); - switch (*value) { +array_value: + switch (*(value = advance())) { case '{': if (!empty_object(visitor)) { goto object_begin; }; break; case '[': if (!empty_array(visitor)) { goto array_begin; }; break; default: SIMDJSON_TRY( visitor.parse_primitive(*this, value) ); } -} // array_value: -array_continue: { +array_continue: switch (advance_char()) { - case ',': - visitor.increment_count(*this); - goto array_value; - case ']': - visitor.end_array(*this); - goto scope_end; - default: - log_error("Missing comma between array values"); - return TAPE_ERROR; + case ',': visitor.increment_count(*this); goto array_value; + case ']': visitor.end_array(*this); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; } -} // array_continue: -document_end: { +document_end: visitor.end_document(*this); dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); @@ -211,7 +192,6 @@ document_end: { } return SUCCESS; -} // document_end: } // parse_structurals()