66namespace stage2 {
77namespace { // Make everything here private
88
9+ #include " generic/stage2/tape_writer.h"
10+
911#ifdef SIMDJSON_USE_COMPUTED_GOTO
1012#define INIT_ADDRESSES () { &&array_begin, &&array_continue, &&error, &&finish, &&object_begin, &&object_continue }
1113#define GOTO (address ) { goto *(address); }
@@ -46,45 +48,25 @@ struct unified_machine_addresses {
4648#undef FAIL_IF
4749#define FAIL_IF (EXPR ) { if (EXPR) { return addresses.error ; } }
4850
49- struct number_writer {
50- dom_parser_implementation &parser;
51-
52- really_inline void write_s64 (int64_t value) noexcept {
53- append_tape (0 , internal::tape_type::INT64);
54- std::memcpy (&parser.doc ->tape [parser.current_loc ], &value, sizeof (value));
55- ++parser.current_loc ;
56- }
57- really_inline void write_u64 (uint64_t value) noexcept {
58- append_tape (0 , internal::tape_type::UINT64);
59- parser.doc ->tape [parser.current_loc ++] = value;
60- }
61- really_inline void write_double (double value) noexcept {
62- append_tape (0 , internal::tape_type::DOUBLE);
63- static_assert (sizeof (value) == sizeof (parser.doc ->tape [parser.current_loc ]), " mismatch size" );
64- memcpy (&parser.doc ->tape [parser.current_loc ++], &value, sizeof (double ));
65- // doc->tape[doc->current_loc++] = *((uint64_t *)&d);
66- }
67- really_inline void append_tape (uint64_t val, internal::tape_type t) noexcept {
68- parser.doc ->tape [parser.current_loc ++] = val | ((uint64_t (char (t))) << 56 );
69- }
70- }; // struct number_writer
71-
7251struct structural_parser : structural_iterator {
52+ /* * Lets you append to the tape */
53+ tape_writer tape;
7354 /* * Next write location in the string buf for stage 2 parsing */
74- uint8_t *current_string_buf_loc{} ;
55+ uint8_t *current_string_buf_loc;
7556 /* * Current depth (nested objects and arrays) */
76- uint32_t depth;
57+ uint32_t depth{ 0 } ;
7758
7859 // For non-streaming, to pass an explicit 0 as next_structural, which enables optimizations
7960 really_inline structural_parser (dom_parser_implementation &_parser, uint32_t start_structural_index)
8061 : structural_iterator(_parser, start_structural_index),
81- depth{0 } {
62+ tape{parser.doc ->tape .get ()},
63+ current_string_buf_loc{parser.doc ->string_buf .get ()} {
8264 }
8365
8466 WARN_UNUSED really_inline bool start_scope (ret_address_t continue_state) {
85- parser.containing_scope [depth].tape_index = parser. current_loc ;
67+ parser.containing_scope [depth].tape_index = next_tape_index () ;
8668 parser.containing_scope [depth].count = 0 ;
87- parser. current_loc ++ ; // We don't actually *write* the start element until the end.
69+ tape. skip () ; // We don't actually *write* the start element until the end.
8870 parser.ret_address [depth] = continue_state;
8971 depth++;
9072 bool exceeded_max_depth = depth >= parser.max_depth ();
@@ -112,14 +94,18 @@ struct structural_parser : structural_iterator {
11294 depth--;
11395 // write our doc->tape location to the header scope
11496 // The root scope gets written *at* the previous location.
115- append_tape (parser.containing_scope [depth].tape_index , end);
97+ tape. append (parser.containing_scope [depth].tape_index , end);
11698 // count can overflow if it exceeds 24 bits... so we saturate
11799 // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff).
118100 const uint32_t start_tape_index = parser.containing_scope [depth].tape_index ;
119101 const uint32_t count = parser.containing_scope [depth].count ;
120102 const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count;
121103 // This is a load and an OR. It would be possible to just write once at doc->tape[d.tape_index]
122- write_tape (start_tape_index, parser.current_loc | (uint64_t (cntsat) << 32 ), start);
104+ tape_writer::write (parser.doc ->tape [start_tape_index], next_tape_index () | (uint64_t (cntsat) << 32 ), start);
105+ }
106+
107+ really_inline uint32_t next_tape_index () {
108+ return uint32_t (tape.next_tape_loc - parser.doc ->tape .get ());
123109 }
124110
125111 really_inline void end_object () {
@@ -135,14 +121,6 @@ struct structural_parser : structural_iterator {
135121 end_scope (internal::tape_type::ROOT, internal::tape_type::ROOT);
136122 }
137123
138- really_inline void append_tape (uint64_t val, internal::tape_type t) noexcept {
139- parser.doc ->tape [parser.current_loc ++] = val | ((uint64_t (char (t))) << 56 );
140- }
141-
142- really_inline void write_tape (uint32_t loc, uint64_t val, internal::tape_type t) noexcept {
143- parser.doc ->tape [loc] = val | ((uint64_t (char (t))) << 56 );
144- }
145-
146124 // increment_count increments the count of keys in an object or values in an array.
147125 // Note that if you are at the level of the values or elements, the count
148126 // must be increment in the preceding depth (depth-1) where the array or
@@ -153,7 +131,7 @@ struct structural_parser : structural_iterator {
153131
154132 really_inline uint8_t *on_start_string () noexcept {
155133 // we advance the point, accounting for the fact that we have a NULL termination
156- append_tape (current_string_buf_loc - parser.doc ->string_buf .get (), internal::tape_type::STRING);
134+ tape. append (current_string_buf_loc - parser.doc ->string_buf .get (), internal::tape_type::STRING);
157135 return current_string_buf_loc + sizeof (uint32_t );
158136 }
159137
@@ -183,8 +161,7 @@ struct structural_parser : structural_iterator {
183161
184162 WARN_UNUSED really_inline bool parse_number (const uint8_t *src, bool found_minus) {
185163 log_value (" number" );
186- number_writer writer{parser};
187- bool succeeded = numberparsing::parse_number (src, found_minus, writer);
164+ bool succeeded = numberparsing::parse_number (src, found_minus, tape);
188165 if (!succeeded) { log_error (" Invalid number" ); }
189166 return !succeeded;
190167 }
@@ -200,17 +177,17 @@ struct structural_parser : structural_iterator {
200177 case ' t' :
201178 log_value (" true" );
202179 FAIL_IF ( !atomparsing::is_valid_true_atom (current ()) );
203- append_tape (0 , internal::tape_type::TRUE_VALUE);
180+ tape. append (0 , internal::tape_type::TRUE_VALUE);
204181 return continue_state;
205182 case ' f' :
206183 log_value (" false" );
207184 FAIL_IF ( !atomparsing::is_valid_false_atom (current ()) );
208- append_tape (0 , internal::tape_type::FALSE_VALUE);
185+ tape. append (0 , internal::tape_type::FALSE_VALUE);
209186 return continue_state;
210187 case ' n' :
211188 log_value (" null" );
212189 FAIL_IF ( !atomparsing::is_valid_null_atom (current ()) );
213- append_tape (0 , internal::tape_type::NULL_VALUE);
190+ tape. append (0 , internal::tape_type::NULL_VALUE);
214191 return continue_state;
215192 case ' 0' : case ' 1' : case ' 2' : case ' 3' : case ' 4' :
216193 case ' 5' : case ' 6' : case ' 7' : case ' 8' : case ' 9' :
@@ -285,8 +262,6 @@ struct structural_parser : structural_iterator {
285262
286263 really_inline void init () {
287264 log_start ();
288- current_string_buf_loc = parser.doc ->string_buf .get ();
289- parser.current_loc = 0 ;
290265 parser.error = UNINITIALIZED;
291266 }
292267
@@ -362,17 +337,17 @@ WARN_UNUSED static error_code parse_structurals(dom_parser_implementation &dom_p
362337 case ' t' :
363338 parser.log_value (" true" );
364339 FAIL_IF ( !atomparsing::is_valid_true_atom (parser.current (), parser.remaining_len ()) );
365- parser.append_tape (0 , internal::tape_type::TRUE_VALUE);
340+ parser.tape . append (0 , internal::tape_type::TRUE_VALUE);
366341 goto finish;
367342 case ' f' :
368343 parser.log_value (" false" );
369344 FAIL_IF ( !atomparsing::is_valid_false_atom (parser.current (), parser.remaining_len ()) );
370- parser.append_tape (0 , internal::tape_type::FALSE_VALUE);
345+ parser.tape . append (0 , internal::tape_type::FALSE_VALUE);
371346 goto finish;
372347 case ' n' :
373348 parser.log_value (" null" );
374349 FAIL_IF ( !atomparsing::is_valid_null_atom (parser.current (), parser.remaining_len ()) );
375- parser.append_tape (0 , internal::tape_type::NULL_VALUE);
350+ parser.tape . append (0 , internal::tape_type::NULL_VALUE);
376351 goto finish;
377352 case ' 0' : case ' 1' : case ' 2' : case ' 3' : case ' 4' :
378353 case ' 5' : case ' 6' : case ' 7' : case ' 8' : case ' 9' :
0 commit comments