Skip to content

Commit d8974d5

Browse files
committed
Keep value around between states
1 parent 5ecd17f commit d8974d5

File tree

1 file changed

+20
-30
lines changed

1 file changed

+20
-30
lines changed

src/generic/stage2/json_iterator.h

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class json_iterator {
1010
uint32_t *next_structural;
1111
dom_parser_implementation &dom_parser;
1212
uint32_t depth{0};
13+
const uint8_t *value{}; // Used to keep a value around between states
1314

1415
template<bool STREAMING, typename T>
1516
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document(T &visitor) noexcept;
@@ -25,11 +26,9 @@ class json_iterator {
2526
simdjson_really_inline char peek_next_char() {
2627
return buf[*(next_structural)];
2728
}
28-
simdjson_really_inline const uint8_t* advance() {
29-
return &buf[*(next_structural++)];
30-
}
31-
simdjson_really_inline char advance_char() {
32-
return buf[*(next_structural++)];
29+
simdjson_really_inline char advance() {
30+
value = &buf[*(next_structural++)];
31+
return *value;
3332
}
3433
simdjson_really_inline size_t remaining_len() {
3534
return dom_parser.len - *(next_structural-1);
@@ -45,7 +44,7 @@ class json_iterator {
4544
template<typename T>
4645
SIMDJSON_WARN_UNUSED simdjson_really_inline bool empty_object(T &visitor) {
4746
if (peek_next_char() == '}') {
48-
advance_char();
47+
advance();
4948
visitor.empty_object(*this);
5049
return true;
5150
}
@@ -54,7 +53,7 @@ class json_iterator {
5453
template<typename T>
5554
SIMDJSON_WARN_UNUSED simdjson_really_inline bool empty_array(T &visitor) {
5655
if (peek_next_char() == ']') {
57-
advance_char();
56+
advance();
5857
visitor.empty_array(*this);
5958
return true;
6059
}
@@ -86,8 +85,6 @@ class json_iterator {
8685

8786
template<bool STREAMING, typename T>
8887
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_document(T &visitor) noexcept {
89-
const uint8_t *value; // Used to keep a value around between states
90-
9188
logger::log_start();
9289

9390
//
@@ -99,7 +96,7 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
9996
//
10097
// Read first value
10198
//
102-
value = advance();
99+
advance();
103100

104101
// Make sure the outer hash or array is closed before continuing; otherwise, there are ways we
105102
// could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906
@@ -132,35 +129,28 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
132129
if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; }
133130
visitor.start_object(*this);
134131

135-
value = advance();
136-
if (*value != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; }
132+
if (advance() != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; }
137133
visitor.increment_count(*this);
138134
SIMDJSON_TRY( visitor.key(*this, value) );
139135
goto object_field;
140136

141137
object_field:
142-
if (simdjson_unlikely( advance_char() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
143-
switch (*(value = advance())) {
138+
if (simdjson_unlikely( advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
139+
switch (advance()) {
144140
case '{': if (!empty_object(visitor)) { goto object_begin; }; goto object_continue;
145141
case '[': if (!empty_array(visitor)) { goto array_begin; }; goto object_continue;
146142
default: SIMDJSON_TRY( visitor.primitive(*this, value) );
147143
}
148144

149145
object_continue:
150-
switch (advance_char()) {
151-
case ',': {
152-
visitor.increment_count(*this);
153-
value = advance();
154-
if (simdjson_unlikely( *value != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
155-
SIMDJSON_TRY( visitor.key(*this, value) );
156-
goto object_field;
157-
}
158-
case '}':
159-
visitor.end_object(*this);
160-
goto scope_end;
161-
default:
162-
log_error("No comma between object fields");
163-
return TAPE_ERROR;
146+
switch (advance()) {
147+
case ',':
148+
visitor.increment_count(*this);
149+
if (simdjson_unlikely( advance() != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
150+
SIMDJSON_TRY( visitor.key(*this, value) );
151+
goto object_field;
152+
case '}': visitor.end_object(*this); goto scope_end;
153+
default: log_error("No comma between object fields"); return TAPE_ERROR;
164154
}
165155

166156
scope_end:
@@ -179,14 +169,14 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
179169
visitor.increment_count(*this);
180170

181171
array_value:
182-
switch (*(value = advance())) {
172+
switch (advance()) {
183173
case '{': if (!empty_object(visitor)) { goto object_begin; }; goto array_continue;
184174
case '[': if (!empty_array(visitor)) { goto array_begin; }; goto array_continue;
185175
default: SIMDJSON_TRY( visitor.primitive(*this, value) );
186176
}
187177

188178
array_continue:
189-
switch (advance_char()) {
179+
switch (advance()) {
190180
case ',': visitor.increment_count(*this); goto array_value;
191181
case ']': visitor.end_array(*this); goto scope_end;
192182
default: log_error("Missing comma between array values"); return TAPE_ERROR;

0 commit comments

Comments
 (0)