Remove computed GOTO
This commit is contained in:
parent
2f67dab2b6
commit
8e69103822
|
@ -20,8 +20,8 @@ class dom_parser_implementation final : public internal::dom_parser_implementati
|
|||
public:
|
||||
/** Tape location of each open { or [ */
|
||||
std::unique_ptr<scope_descriptor[]> containing_scope{};
|
||||
/** Return address of each open { or [ */
|
||||
std::unique_ptr<ret_address_t[]> ret_address{};
|
||||
/** Whether each open container is a [ or { */
|
||||
std::unique_ptr<bool[]> is_array{};
|
||||
/** Buffer passed to stage 1 */
|
||||
const uint8_t *buf{};
|
||||
/** Length passed to stage 1 */
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace allocate {
|
|||
//
|
||||
really_inline error_code set_max_depth(dom_parser_implementation &parser, size_t max_depth) {
|
||||
parser.containing_scope.reset(new (std::nothrow) scope_descriptor[max_depth]);
|
||||
parser.ret_address.reset(new (std::nothrow) ret_address_t[max_depth]);
|
||||
parser.is_array.reset(new (std::nothrow) bool[max_depth]);
|
||||
|
||||
if (!parser.ret_address || !parser.containing_scope) {
|
||||
if (!parser.is_array || !parser.containing_scope) {
|
||||
return MEMALLOC;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
|
|
@ -12,27 +12,6 @@ namespace { // Make everything here private
|
|||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace stage2 {
|
||||
|
||||
#ifdef SIMDJSON_USE_COMPUTED_GOTO
|
||||
#define INIT_ADDRESSES() { &&array_continue, &&finish, &&object_continue }
|
||||
#define CONTINUE(address) { goto *(address); }
|
||||
#else // SIMDJSON_USE_COMPUTED_GOTO
|
||||
#define INIT_ADDRESSES() { 0, 1, 2 };
|
||||
#define CONTINUE(address) \
|
||||
{ \
|
||||
switch(address) { \
|
||||
case 0: goto array_continue; \
|
||||
case 1: goto finish; \
|
||||
case 2: goto object_continue; \
|
||||
} \
|
||||
}
|
||||
#endif // SIMDJSON_USE_COMPUTED_GOTO
|
||||
|
||||
struct unified_machine_addresses {
|
||||
ret_address_t array_continue;
|
||||
ret_address_t finish;
|
||||
ret_address_t object_continue;
|
||||
};
|
||||
|
||||
struct structural_parser : structural_iterator {
|
||||
/** Lets you append to the tape */
|
||||
tape_writer tape;
|
||||
|
@ -48,30 +27,30 @@ struct structural_parser : structural_iterator {
|
|||
current_string_buf_loc{parser.doc->string_buf.get()} {
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline bool start_scope(ret_address_t continue_state) {
|
||||
WARN_UNUSED really_inline bool start_scope(bool parent_is_array) {
|
||||
parser.containing_scope[depth].tape_index = next_tape_index();
|
||||
parser.containing_scope[depth].count = 0;
|
||||
tape.skip(); // We don't actually *write* the start element until the end.
|
||||
parser.ret_address[depth] = continue_state;
|
||||
parser.is_array[depth] = parent_is_array;
|
||||
depth++;
|
||||
bool exceeded_max_depth = depth >= parser.max_depth();
|
||||
if (exceeded_max_depth) { log_error("Exceeded max depth!"); }
|
||||
return exceeded_max_depth;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline bool start_document(ret_address_t continue_state) {
|
||||
WARN_UNUSED really_inline bool start_document() {
|
||||
log_start_value("document");
|
||||
return start_scope(continue_state);
|
||||
return start_scope(false);
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline bool start_object(ret_address_t continue_state) {
|
||||
WARN_UNUSED really_inline bool start_object(bool parent_is_array) {
|
||||
log_start_value("object");
|
||||
return start_scope(continue_state);
|
||||
return start_scope(parent_is_array);
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline bool start_array(ret_address_t continue_state) {
|
||||
WARN_UNUSED really_inline bool start_array(bool parent_is_array) {
|
||||
log_start_value("array");
|
||||
return start_scope(continue_state);
|
||||
return start_scope(parent_is_array);
|
||||
}
|
||||
|
||||
// this function is responsible for annotating the start of the scope
|
||||
|
@ -277,7 +256,7 @@ struct structural_parser : structural_iterator {
|
|||
parser.error = UNINITIALIZED;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code start(ret_address_t finish_state) {
|
||||
WARN_UNUSED really_inline error_code start() {
|
||||
// If there are no structurals left, return EMPTY
|
||||
if (at_end(parser.n_structural_indexes)) {
|
||||
return parser.error = EMPTY;
|
||||
|
@ -285,7 +264,7 @@ struct structural_parser : structural_iterator {
|
|||
|
||||
init();
|
||||
// Push the root scope (there is always at least one scope)
|
||||
if (start_document(finish_state)) {
|
||||
if (start_document()) {
|
||||
return parser.error = DEPTH_ERROR;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
@ -317,9 +296,8 @@ struct structural_parser : structural_iterator {
|
|||
template<bool STREAMING>
|
||||
WARN_UNUSED static error_code parse_structurals(dom_parser_implementation &dom_parser, dom::document &doc) noexcept {
|
||||
dom_parser.doc = &doc;
|
||||
static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES();
|
||||
stage2::structural_parser parser(dom_parser, STREAMING ? dom_parser.next_structural_index : 0);
|
||||
error_code result = parser.start(addresses.finish);
|
||||
error_code result = parser.start();
|
||||
if (result) { return result; }
|
||||
|
||||
//
|
||||
|
@ -327,10 +305,10 @@ WARN_UNUSED static error_code parse_structurals(dom_parser_implementation &dom_p
|
|||
//
|
||||
switch (parser.current_char()) {
|
||||
case '{':
|
||||
if ( parser.start_object(addresses.finish) ) { goto error; };
|
||||
if ( parser.start_object(false) ) { goto error; };
|
||||
goto object_begin;
|
||||
case '[':
|
||||
if ( parser.start_array(addresses.finish) ) { goto error; }
|
||||
if ( parser.start_array(false) ) { goto error; }
|
||||
// Make sure the outer 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) {
|
||||
|
@ -377,8 +355,8 @@ object_begin:
|
|||
object_key_state:
|
||||
if (parser.advance_char() != ':' ) { parser.log_error("Missing colon after key in object"); goto error; }
|
||||
switch (parser.advance_char()) {
|
||||
case '{': if ( parser.start_object(addresses.object_continue) ) { goto error; } else { goto object_begin; }
|
||||
case '[': if ( parser.start_array(addresses.object_continue) ) { goto error; } else { goto array_begin; }
|
||||
case '{': if ( parser.start_object(false) ) { goto error; } else { goto object_begin; }
|
||||
case '[': if ( parser.start_array(false) ) { goto error; } else { goto array_begin; }
|
||||
case '"': if ( parser.parse_string() ) { goto error; }; break;
|
||||
case 't': if ( parser.parse_true_atom() ) { goto error; }; break;
|
||||
case 'f': if ( parser.parse_false_atom() ) { goto error; }; break;
|
||||
|
@ -408,7 +386,9 @@ object_continue:
|
|||
}
|
||||
|
||||
scope_end:
|
||||
CONTINUE( parser.parser.ret_address[parser.depth] );
|
||||
if (parser.depth == 1) { goto finish; }
|
||||
if (parser.parser.is_array[parser.depth]) { goto array_continue; }
|
||||
goto object_continue;
|
||||
|
||||
//
|
||||
// Array parser states
|
||||
|
@ -423,8 +403,8 @@ array_begin:
|
|||
|
||||
main_array_switch:
|
||||
switch (parser.advance_char()) {
|
||||
case '{': if ( parser.start_object(addresses.array_continue) ) { goto error; } else { goto object_begin; }
|
||||
case '[': if ( parser.start_array(addresses.array_continue) ) { goto error; } else { goto array_begin; }
|
||||
case '{': if ( parser.start_object(true) ) { goto error; } else { goto object_begin; }
|
||||
case '[': if ( parser.start_array(true) ) { goto error; } else { goto array_begin; }
|
||||
case '"': if ( parser.parse_string() ) { goto error; }; break;
|
||||
case 't': if ( parser.parse_true_atom() ) { goto error; }; break;
|
||||
case 'f': if ( parser.parse_false_atom() ) { goto error; }; break;
|
||||
|
|
Loading…
Reference in New Issue