@@ -12,27 +12,6 @@ namespace { // Make everything here private
12
12
namespace SIMDJSON_IMPLEMENTATION {
13
13
namespace stage2 {
14
14
15
- #ifdef SIMDJSON_USE_COMPUTED_GOTO
16
- #define INIT_ADDRESSES () { &&array_continue, &&finish, &&object_continue }
17
- #define CONTINUE (address ) { goto *(address); }
18
- #else // SIMDJSON_USE_COMPUTED_GOTO
19
- #define INIT_ADDRESSES () { 0 , 1 , 2 };
20
- #define CONTINUE (address ) \
21
- { \
22
- switch (address) { \
23
- case 0 : goto array_continue; \
24
- case 1 : goto finish; \
25
- case 2 : goto object_continue; \
26
- } \
27
- }
28
- #endif // SIMDJSON_USE_COMPUTED_GOTO
29
-
30
- struct unified_machine_addresses {
31
- ret_address_t array_continue;
32
- ret_address_t finish;
33
- ret_address_t object_continue;
34
- };
35
-
36
15
struct structural_parser : structural_iterator {
37
16
/* * Lets you append to the tape */
38
17
tape_writer tape;
@@ -48,30 +27,30 @@ struct structural_parser : structural_iterator {
48
27
current_string_buf_loc{parser.doc ->string_buf .get ()} {
49
28
}
50
29
51
- WARN_UNUSED really_inline bool start_scope (ret_address_t continue_state ) {
30
+ WARN_UNUSED really_inline bool start_scope (bool parent_is_array ) {
52
31
parser.containing_scope [depth].tape_index = next_tape_index ();
53
32
parser.containing_scope [depth].count = 0 ;
54
33
tape.skip (); // We don't actually *write* the start element until the end.
55
- parser.ret_address [depth] = continue_state ;
34
+ parser.is_array [depth] = parent_is_array ;
56
35
depth++;
57
36
bool exceeded_max_depth = depth >= parser.max_depth ();
58
37
if (exceeded_max_depth) { log_error (" Exceeded max depth!" ); }
59
38
return exceeded_max_depth;
60
39
}
61
40
62
- WARN_UNUSED really_inline bool start_document (ret_address_t continue_state ) {
41
+ WARN_UNUSED really_inline bool start_document () {
63
42
log_start_value (" document" );
64
- return start_scope (continue_state );
43
+ return start_scope (false );
65
44
}
66
45
67
- WARN_UNUSED really_inline bool start_object (ret_address_t continue_state ) {
46
+ WARN_UNUSED really_inline bool start_object (bool parent_is_array ) {
68
47
log_start_value (" object" );
69
- return start_scope (continue_state );
48
+ return start_scope (parent_is_array );
70
49
}
71
50
72
- WARN_UNUSED really_inline bool start_array (ret_address_t continue_state ) {
51
+ WARN_UNUSED really_inline bool start_array (bool parent_is_array ) {
73
52
log_start_value (" array" );
74
- return start_scope (continue_state );
53
+ return start_scope (parent_is_array );
75
54
}
76
55
77
56
// this function is responsible for annotating the start of the scope
@@ -277,15 +256,15 @@ struct structural_parser : structural_iterator {
277
256
parser.error = UNINITIALIZED;
278
257
}
279
258
280
- WARN_UNUSED really_inline error_code start (ret_address_t finish_state ) {
259
+ WARN_UNUSED really_inline error_code start () {
281
260
// If there are no structurals left, return EMPTY
282
261
if (at_end (parser.n_structural_indexes )) {
283
262
return parser.error = EMPTY;
284
263
}
285
264
286
265
init ();
287
266
// Push the root scope (there is always at least one scope)
288
- if (start_document (finish_state )) {
267
+ if (start_document ()) {
289
268
return parser.error = DEPTH_ERROR;
290
269
}
291
270
return SUCCESS;
@@ -317,20 +296,19 @@ struct structural_parser : structural_iterator {
317
296
template <bool STREAMING>
318
297
WARN_UNUSED static error_code parse_structurals (dom_parser_implementation &dom_parser, dom::document &doc) noexcept {
319
298
dom_parser.doc = &doc;
320
- static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES ();
321
299
stage2::structural_parser parser (dom_parser, STREAMING ? dom_parser.next_structural_index : 0 );
322
- error_code result = parser.start (addresses. finish );
300
+ error_code result = parser.start ();
323
301
if (result) { return result; }
324
302
325
303
//
326
304
// Read first value
327
305
//
328
306
switch (parser.current_char ()) {
329
307
case ' {' :
330
- if ( parser.start_object (addresses. finish ) ) { goto error; };
308
+ if ( parser.start_object (false ) ) { goto error; };
331
309
goto object_begin;
332
310
case ' [' :
333
- if ( parser.start_array (addresses. finish ) ) { goto error; }
311
+ if ( parser.start_array (false ) ) { goto error; }
334
312
// Make sure the outer array is closed before continuing; otherwise, there are ways we could get
335
313
// into memory corruption. See https://github.com/simdjson/simdjson/issues/906
336
314
if (!STREAMING) {
@@ -377,8 +355,8 @@ WARN_UNUSED static error_code parse_structurals(dom_parser_implementation &dom_p
377
355
object_key_state:
378
356
if (parser.advance_char () != ' :' ) { parser.log_error (" Missing colon after key in object" ); goto error; }
379
357
switch (parser.advance_char ()) {
380
- case ' {' : if ( parser.start_object (addresses. object_continue ) ) { goto error; } else { goto object_begin; }
381
- case ' [' : if ( parser.start_array (addresses. object_continue ) ) { goto error; } else { goto array_begin; }
358
+ case ' {' : if ( parser.start_object (false ) ) { goto error; } else { goto object_begin; }
359
+ case ' [' : if ( parser.start_array (false ) ) { goto error; } else { goto array_begin; }
382
360
case ' "' : if ( parser.parse_string () ) { goto error; }; break ;
383
361
case ' t' : if ( parser.parse_true_atom () ) { goto error; }; break ;
384
362
case ' f' : if ( parser.parse_false_atom () ) { goto error; }; break ;
@@ -408,7 +386,9 @@ WARN_UNUSED static error_code parse_structurals(dom_parser_implementation &dom_p
408
386
}
409
387
410
388
scope_end:
411
- CONTINUE ( parser.parser .ret_address [parser.depth ] );
389
+ if (parser.depth == 1 ) { goto finish; }
390
+ if (parser.parser .is_array [parser.depth ]) { goto array_continue; }
391
+ goto object_continue;
412
392
413
393
//
414
394
// Array parser states
@@ -423,8 +403,8 @@ WARN_UNUSED static error_code parse_structurals(dom_parser_implementation &dom_p
423
403
424
404
main_array_switch:
425
405
switch (parser.advance_char ()) {
426
- case ' {' : if ( parser.start_object (addresses. array_continue ) ) { goto error; } else { goto object_begin; }
427
- case ' [' : if ( parser.start_array (addresses. array_continue ) ) { goto error; } else { goto array_begin; }
406
+ case ' {' : if ( parser.start_object (true ) ) { goto error; } else { goto object_begin; }
407
+ case ' [' : if ( parser.start_array (true ) ) { goto error; } else { goto array_begin; }
428
408
case ' "' : if ( parser.parse_string () ) { goto error; }; break ;
429
409
case ' t' : if ( parser.parse_true_atom () ) { goto error; }; break ;
430
410
case ' f' : if ( parser.parse_false_atom () ) { goto error; }; break ;
0 commit comments