yeptris 0.6.18.2-arm-linux-eabihf → 0.6.20.1-arm-linux-eabihf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/build_windows_native.rb +31 -12
- data/lib/yeptris/3.4/native.so +0 -0
- data/lib/yeptris/materializer.rb +12 -11
- data/lib/yeptris/psych/handler.rb +5 -0
- data/lib/yeptris/psych/parser.rb +8 -3
- data/lib/yeptris/psych/tree_builder.rb +119 -0
- data/lib/yeptris/psych.rb +4 -0
- data/lib/yeptris.rb +15 -11
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +1 -1
- data/vendor/libyeptris/src/CMakeLists.txt +1 -0
- data/vendor/libyeptris/src/include/yeptris/events.h +8 -1
- data/vendor/libyeptris/src/yeptris/cbor/decode.c +1 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.h +47 -13
- data/vendor/libyeptris/src/yeptris/common/simd_text_avx2.c +86 -8
- data/vendor/libyeptris/src/yeptris/common/simd_text_neon.c +82 -8
- data/vendor/libyeptris/src/yeptris/common/simd_text_scalar.c +10 -6
- data/vendor/libyeptris/src/yeptris/doc.h +8 -4
- data/vendor/libyeptris/src/yeptris/dom/ytape.c +640 -0
- data/vendor/libyeptris/src/yeptris/dom/ytape.h +77 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.c +7 -2
- data/vendor/libyeptris/src/yeptris/events/capture.c +5 -1
- data/vendor/libyeptris/src/yeptris/parse/engine.c +150 -3
- data/vendor/libyeptris/src/yeptris/parse/events.h +6 -0
- data/vendor/libyeptris/src/yeptris/parse.c +144 -42
- data/vendor/libyeptris/src/yeptris/scan/json.c +43 -5
- data/vendor/libyeptris/src/yeptris/scan/json.h +9 -2
- data/vendor/libyeptris/src/yeptris/tape.c +539 -163
- data/vendor/libyeptris/src/yeptris/tape_in.h +12 -0
- metadata +5 -2
- data/lib/yeptris/native-3.4.so +0 -0
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include "common/simd_text.h"
|
|
6
6
|
#include "doc.h"
|
|
7
7
|
#include "dom/dom.h"
|
|
8
|
+
#include "dom/ytape.h"
|
|
8
9
|
#include "encoding/encoding.h"
|
|
9
10
|
#include "memory/allocator.h"
|
|
10
11
|
#include "memory/pool.h"
|
|
@@ -33,7 +34,7 @@ YEPTRIS_API const char* yeptris_last_error(uint32_t* line, uint32_t* col) {
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
static YeptrisDocument parse_impl(const char* buf, size_t len, const YeptrisParseOptions* opts,
|
|
36
|
-
int json_mode, YeptrisStatus* status);
|
|
37
|
+
int json_mode, int lazy, YeptrisStatus* status);
|
|
37
38
|
|
|
38
39
|
YEPTRIS_API YeptrisDocument yeptris_parse(const char* buf, size_t len, YeptrisStatus* status) {
|
|
39
40
|
return yeptris_parse_ex(buf, len, NULL, status);
|
|
@@ -47,6 +48,31 @@ yep_dom* yep_doc_dom(yeptris_document* doc) {
|
|
|
47
48
|
if (doc == NULL) {
|
|
48
49
|
return NULL;
|
|
49
50
|
}
|
|
51
|
+
if (doc->dom == NULL && doc->lazy_tape != NULL && doc->lazy_kind == 1) {
|
|
52
|
+
/* #378: the YAML record tape — replay through the eager
|
|
53
|
+
* builders; the finish pool (whose spans the records carry)
|
|
54
|
+
* dies once the builders copied what must outlive it */
|
|
55
|
+
yep_ytape* t = (yep_ytape*)doc->lazy_tape;
|
|
56
|
+
yep_dom* dom = yep_dom_create(doc->sys);
|
|
57
|
+
if (dom != NULL) {
|
|
58
|
+
dom->resolver = (doc->schema == YEPTRIS_SCHEMA_11_COMPAT) ? yep_resolver_compat11()
|
|
59
|
+
: yep_resolver_core12();
|
|
60
|
+
}
|
|
61
|
+
if (dom != NULL && dom_from_ytape(dom, t) == 0) {
|
|
62
|
+
doc->dom = dom;
|
|
63
|
+
ytap_free(t);
|
|
64
|
+
yep_free(doc->sys, t);
|
|
65
|
+
doc->lazy_tape = NULL;
|
|
66
|
+
yep_pool_destroy((yep_pool*)doc->finish_pool);
|
|
67
|
+
doc->finish_pool = NULL;
|
|
68
|
+
} else {
|
|
69
|
+
yep_dom_destroy(dom);
|
|
70
|
+
dom = NULL; /* the tape stays: a later access retries, or
|
|
71
|
+
* free drops it (replay fails only on
|
|
72
|
+
* allocation/depth, as the builders do) */
|
|
73
|
+
}
|
|
74
|
+
return dom;
|
|
75
|
+
}
|
|
50
76
|
if (doc->dom == NULL && doc->lazy_tape != NULL) {
|
|
51
77
|
yeptris_json_tape* t = (yeptris_json_tape*)doc->lazy_tape;
|
|
52
78
|
yep_dom* dom = yep_dom_create(doc->sys);
|
|
@@ -83,6 +109,21 @@ static int lazy_nums_settled(const yeptris_json_tape* t) {
|
|
|
83
109
|
}
|
|
84
110
|
uint32_t len = (uint32_t)((r >> 8) & 0x7FFFFFu);
|
|
85
111
|
uint32_t off = (uint32_t)(r >> 32);
|
|
112
|
+
{ /* the pure-integer fast path: all digits (optional '-'), no
|
|
113
|
+
* leading zero unless a lone digit — number_shape would
|
|
114
|
+
* consume the whole span and answer float-less; skip it */
|
|
115
|
+
const char* q = p + off;
|
|
116
|
+
size_t d = (*q == '-') ? 1 : 0;
|
|
117
|
+
size_t w = d;
|
|
118
|
+
for (; w < len; w++) {
|
|
119
|
+
if ((unsigned)(unsigned char)q[w] - '0' > 9u) {
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (w == len && len > d && (len - d == 1 || q[d] != '0')) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
86
127
|
size_t adv = 0;
|
|
87
128
|
int flt = 0;
|
|
88
129
|
if (yep_json_number_shape(p + off, len, &adv, &flt) == 0 || adv != (size_t)len) {
|
|
@@ -107,6 +148,7 @@ static YeptrisDocument yep_json_doc_wrap(yep_dom* dom, const char* buf, size_t l
|
|
|
107
148
|
doc->dom = dom;
|
|
108
149
|
doc->sys = sys;
|
|
109
150
|
doc->lazy_tape = NULL;
|
|
151
|
+
doc->lazy_kind = 0;
|
|
110
152
|
doc->schema = YEPTRIS_SCHEMA_12_CORE; /* strict JSON is core by construction */
|
|
111
153
|
doc->transcoded = NULL;
|
|
112
154
|
doc->transcoded_len = 0;
|
|
@@ -161,6 +203,7 @@ YEPTRIS_API YeptrisDocument yeptris_parse_json(const char* buf, size_t len, Yept
|
|
|
161
203
|
YeptrisDocument h = yep_json_doc_wrap(NULL, buf, len, sys, status);
|
|
162
204
|
if (h != NULL) {
|
|
163
205
|
((yeptris_document*)h)->lazy_tape = t;
|
|
206
|
+
((yeptris_document*)h)->lazy_kind = 0;
|
|
164
207
|
return h;
|
|
165
208
|
}
|
|
166
209
|
yeptris_tape_free(t); /* wrap failed (memory): below */
|
|
@@ -206,7 +249,7 @@ YEPTRIS_API YeptrisDocument yeptris_parse_json(const char* buf, size_t len, Yept
|
|
|
206
249
|
}
|
|
207
250
|
if (brc == -2) {
|
|
208
251
|
yep_dom_destroy(dom);
|
|
209
|
-
return parse_impl(buf, len, NULL, 1, status);
|
|
252
|
+
return parse_impl(buf, len, NULL, 1, 0, status);
|
|
210
253
|
}
|
|
211
254
|
return yep_json_doc_wrap(dom, buf, len, sys, status);
|
|
212
255
|
}
|
|
@@ -218,7 +261,7 @@ jfail:
|
|
|
218
261
|
}
|
|
219
262
|
|
|
220
263
|
static YeptrisDocument parse_impl(const char* buf, size_t len, const YeptrisParseOptions* opts,
|
|
221
|
-
int json_mode, YeptrisStatus* status) {
|
|
264
|
+
int json_mode, int lazy, YeptrisStatus* status) {
|
|
222
265
|
YeptrisStatus st = YEPTRIS_OK;
|
|
223
266
|
if (buf == NULL && len != 0) {
|
|
224
267
|
st = YEPTRIS_ERROR_ARG;
|
|
@@ -303,24 +346,30 @@ engine_enter:
|
|
|
303
346
|
st = YEPTRIS_ERROR_MEMORY;
|
|
304
347
|
goto fail;
|
|
305
348
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
349
|
+
/* the lazy route builds NO tree at parse: the dom (and its whole
|
|
350
|
+
* setup) exists only for the eager sink (the ASAN leak lesson —
|
|
351
|
+
* an unused dom leaked per lazy parse) */
|
|
352
|
+
yep_dom* dom = NULL;
|
|
353
|
+
if (!lazy) {
|
|
354
|
+
dom = yep_dom_create(sys);
|
|
355
|
+
if (dom == NULL) {
|
|
356
|
+
yep_engine_destroy(eng);
|
|
357
|
+
yep_free(sys, transcoded);
|
|
358
|
+
st = YEPTRIS_ERROR_MEMORY;
|
|
359
|
+
goto fail;
|
|
360
|
+
}
|
|
361
|
+
/* the direct builders resolve with the engine's schema (the typing
|
|
362
|
+
* SSOT — one resolver decision per scalar, whichever path builds) */
|
|
363
|
+
dom->resolver = (opts != NULL && opts->schema == YEPTRIS_SCHEMA_11_COMPAT)
|
|
364
|
+
? yep_resolver_compat11()
|
|
365
|
+
: yep_resolver_core12();
|
|
366
|
+
/* BEFORE the run: input-slice strings borrow as views (zero copy)
|
|
367
|
+
* — the document keeps `transcoded` alive for exactly this. Set
|
|
368
|
+
* after, every scalar was arena-copied (found 2026-09-10). */
|
|
369
|
+
dom->input_len = data_len;
|
|
370
|
+
dom->input_base = transcoded ? (const char*)transcoded : buf;
|
|
371
|
+
yep_dom_prepare_len(dom, data_len);
|
|
312
372
|
}
|
|
313
|
-
/* the direct builders resolve with the engine's schema (the typing
|
|
314
|
-
* SSOT — one resolver decision per scalar, whichever path builds) */
|
|
315
|
-
dom->resolver = (opts != NULL && opts->schema == YEPTRIS_SCHEMA_11_COMPAT)
|
|
316
|
-
? yep_resolver_compat11()
|
|
317
|
-
: yep_resolver_core12();
|
|
318
|
-
/* BEFORE the run: input-slice strings borrow as views (zero copy)
|
|
319
|
-
* — the document keeps `transcoded` alive for exactly this. Set
|
|
320
|
-
* after, every scalar was arena-copied (found 2026-09-10). */
|
|
321
|
-
dom->input_len = data_len;
|
|
322
|
-
dom->input_base = transcoded ? (const char*)transcoded : buf;
|
|
323
|
-
yep_dom_prepare_len(dom, data_len);
|
|
324
373
|
{
|
|
325
374
|
/* the nametab reserve survives: a memchr chain for '&' is
|
|
326
375
|
* far cheaper than the class sweep it replaced */
|
|
@@ -336,15 +385,31 @@ engine_enter:
|
|
|
336
385
|
yep_engine_prepare(eng, &_only);
|
|
337
386
|
}
|
|
338
387
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
388
|
+
yep_ytape yt = {0}; /* zeroed: MSVC cannot couple have_tape to ytap_init's fill */
|
|
389
|
+
int have_tape = 0;
|
|
390
|
+
yep_sink sink;
|
|
391
|
+
if (lazy) {
|
|
392
|
+
/* #378: the recorder rides the SAME engine run — the fused
|
|
393
|
+
* arms stay hot, the builders' node lane defers to replay */
|
|
394
|
+
if (ytap_init(&yt, data, data_len, 0) != 0) {
|
|
395
|
+
yep_engine_destroy(eng);
|
|
396
|
+
yep_free(sys, transcoded);
|
|
397
|
+
st = YEPTRIS_ERROR_MEMORY;
|
|
398
|
+
goto fail;
|
|
399
|
+
}
|
|
400
|
+
ytap_sink(&yt, &sink);
|
|
401
|
+
have_tape = 1;
|
|
402
|
+
} else {
|
|
403
|
+
sink = (yep_sink){.on_event = yep_dom_on_event,
|
|
404
|
+
.ctx = dom,
|
|
405
|
+
.on_flow_build = dom_on_flow_build,
|
|
406
|
+
.on_flow_commit = dom_on_flow_commit,
|
|
407
|
+
.on_flow_rollback = dom_on_flow_rollback,
|
|
408
|
+
.on_block_pair = dom_on_block_pair,
|
|
409
|
+
.on_scalar = dom_on_scalar,
|
|
410
|
+
.on_block_open = dom_on_block_open,
|
|
411
|
+
.on_block_item = dom_on_block_item};
|
|
412
|
+
}
|
|
348
413
|
int rc = yep_engine_run(eng, data, data_len, &sink);
|
|
349
414
|
if (rc != 0) {
|
|
350
415
|
const yep_error* ee = yep_engine_error(eng);
|
|
@@ -353,6 +418,9 @@ engine_enter:
|
|
|
353
418
|
yep_error* tls = yep_error_tls();
|
|
354
419
|
*tls = *ee;
|
|
355
420
|
}
|
|
421
|
+
if (have_tape) {
|
|
422
|
+
ytap_free(&yt);
|
|
423
|
+
}
|
|
356
424
|
yep_dom_destroy(dom);
|
|
357
425
|
yep_engine_destroy(eng);
|
|
358
426
|
yep_free(sys, transcoded);
|
|
@@ -366,12 +434,14 @@ engine_enter:
|
|
|
366
434
|
* dangle at engine teardown (found by ASAN). */
|
|
367
435
|
yep_pool* finish = yep_engine_detach_pool(eng);
|
|
368
436
|
yep_engine_destroy(eng);
|
|
369
|
-
/* DOM strings are input-offsets or arena copies; nothing in the
|
|
370
|
-
* tree references the finish pool anymore — release it now */
|
|
371
437
|
|
|
372
438
|
/* Empty stream (no documents): NULL document with YEPTRIS_OK. */
|
|
373
|
-
if (dom->dcount == 0) {
|
|
374
|
-
|
|
439
|
+
if (have_tape ? (yt.docs == 0) : (dom->dcount == 0)) {
|
|
440
|
+
if (have_tape) {
|
|
441
|
+
ytap_free(&yt);
|
|
442
|
+
} else {
|
|
443
|
+
yep_dom_destroy(dom);
|
|
444
|
+
}
|
|
375
445
|
yep_pool_destroy(finish);
|
|
376
446
|
yep_free(sys, transcoded);
|
|
377
447
|
if (status != NULL) {
|
|
@@ -379,6 +449,13 @@ engine_enter:
|
|
|
379
449
|
}
|
|
380
450
|
return NULL;
|
|
381
451
|
}
|
|
452
|
+
if (!have_tape) {
|
|
453
|
+
/* DOM strings are input-offsets or arena copies; nothing in the
|
|
454
|
+
* tree references the finish pool anymore — release it now */
|
|
455
|
+
yep_pool_destroy(finish);
|
|
456
|
+
finish = NULL;
|
|
457
|
+
} /* the lazy route keeps it: the records carry pool spans until
|
|
458
|
+
replay copies (doc.h's finish_pool contract) */
|
|
382
459
|
|
|
383
460
|
yeptris_document* doc = yep_alloc(sys, sizeof(yeptris_document));
|
|
384
461
|
if (doc == NULL) {
|
|
@@ -388,7 +465,6 @@ engine_enter:
|
|
|
388
465
|
st = YEPTRIS_ERROR_MEMORY;
|
|
389
466
|
goto fail;
|
|
390
467
|
}
|
|
391
|
-
doc->dom = dom;
|
|
392
468
|
doc->sys = sys;
|
|
393
469
|
doc->schema = (opts != NULL && opts->schema == YEPTRIS_SCHEMA_11_COMPAT)
|
|
394
470
|
? YEPTRIS_SCHEMA_11_COMPAT
|
|
@@ -396,12 +472,26 @@ engine_enter:
|
|
|
396
472
|
doc->transcoded = transcoded;
|
|
397
473
|
doc->transcoded_len = transcoded_len;
|
|
398
474
|
doc->input = buf;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
475
|
+
doc->finish_pool = finish; /* NULL on the eager route */
|
|
476
|
+
doc->lazy_tape = NULL;
|
|
477
|
+
doc->lazy_kind = 0;
|
|
478
|
+
if (have_tape) {
|
|
479
|
+
yep_ytape* heap_tape = yep_alloc(sys, sizeof(*heap_tape));
|
|
480
|
+
if (heap_tape == NULL) {
|
|
481
|
+
ytap_free(&yt);
|
|
482
|
+
yep_pool_destroy(finish);
|
|
483
|
+
yep_free(sys, transcoded);
|
|
484
|
+
yep_free(sys, doc);
|
|
485
|
+
st = YEPTRIS_ERROR_MEMORY;
|
|
486
|
+
goto fail;
|
|
487
|
+
}
|
|
488
|
+
*heap_tape = yt;
|
|
489
|
+
doc->dom = NULL;
|
|
490
|
+
doc->lazy_tape = heap_tape;
|
|
491
|
+
doc->lazy_kind = 1;
|
|
492
|
+
} else {
|
|
493
|
+
doc->dom = dom;
|
|
494
|
+
}
|
|
405
495
|
return (YeptrisDocument)doc;
|
|
406
496
|
|
|
407
497
|
fail:
|
|
@@ -414,7 +504,15 @@ fail:
|
|
|
414
504
|
YEPTRIS_API YeptrisDocument yeptris_parse_ex(const char* buf, size_t len,
|
|
415
505
|
const YeptrisParseOptions* opts,
|
|
416
506
|
YeptrisStatus* status) {
|
|
417
|
-
return parse_impl(buf, len, opts, 0, status);
|
|
507
|
+
return parse_impl(buf, len, opts, 0, 0, status);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/* #378 slice 1 (internal seam): the YAML parse rides the packed record
|
|
511
|
+
* tape — the tree materializes from the records on first access. Same
|
|
512
|
+
* grammar, same errors; parse-only workloads never build nodes. */
|
|
513
|
+
YeptrisDocument yeptris_parse_ytape_ex(const char* buf, size_t len, const YeptrisParseOptions* opts,
|
|
514
|
+
YeptrisStatus* status) {
|
|
515
|
+
return parse_impl(buf, len, opts, 0, 1, status);
|
|
418
516
|
}
|
|
419
517
|
|
|
420
518
|
YEPTRIS_API void yeptris_document_free(YeptrisDocument handle) {
|
|
@@ -423,7 +521,11 @@ YEPTRIS_API void yeptris_document_free(YeptrisDocument handle) {
|
|
|
423
521
|
return;
|
|
424
522
|
}
|
|
425
523
|
if (doc->lazy_tape != NULL) { /* never materialized: free stays free */
|
|
426
|
-
|
|
524
|
+
if (doc->lazy_kind == 1) {
|
|
525
|
+
ytap_free((yep_ytape*)doc->lazy_tape);
|
|
526
|
+
} else {
|
|
527
|
+
yeptris_tape_free((yeptris_json_tape*)doc->lazy_tape);
|
|
528
|
+
}
|
|
427
529
|
yep_free(doc->sys, doc->lazy_tape);
|
|
428
530
|
}
|
|
429
531
|
yep_dom_destroy(doc->dom);
|
|
@@ -761,12 +761,13 @@ yep_jw_status yep_json_walk_next(yep_json_walk* w, yep_json_tok* t) {
|
|
|
761
761
|
* parity error. The mask-level identity set (escape scanner via the
|
|
762
762
|
* ODD_BITS borrow trick, prefix-xor string parity) is simdjson's. */
|
|
763
763
|
|
|
764
|
-
YEPTRIS_API int yep_json_stage1_scalar(const char* p, size_t len, uint32_t* idx, size_t* nidx
|
|
764
|
+
YEPTRIS_API int yep_json_stage1_scalar(const char* p, size_t len, uint32_t* idx, size_t* nidx,
|
|
765
|
+
unsigned* flags) {
|
|
765
766
|
size_t n = 0;
|
|
766
|
-
uint64_t prev_in_string = 0, esc_carry = 0
|
|
767
|
+
uint64_t prev_in_string = 0, esc_carry = 0;
|
|
767
768
|
for (size_t off = 0; off < len; off += 64) {
|
|
768
769
|
size_t cn = len - off < 64 ? len - off : 64;
|
|
769
|
-
uint64_t q = 0, bs = 0, op = 0, ws = 0;
|
|
770
|
+
uint64_t q = 0, bs = 0, op = 0, ws = 0, c0 = 0;
|
|
770
771
|
for (size_t k = 0; k < cn; k++) {
|
|
771
772
|
unsigned char c = (unsigned char)p[off + k];
|
|
772
773
|
uint64_t bit = 1ull << k;
|
|
@@ -779,14 +780,51 @@ YEPTRIS_API int yep_json_stage1_scalar(const char* p, size_t len, uint32_t* idx,
|
|
|
779
780
|
} else if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
|
780
781
|
ws |= bit;
|
|
781
782
|
}
|
|
783
|
+
if (c < 0x20) {
|
|
784
|
+
c0 |= bit;
|
|
785
|
+
}
|
|
782
786
|
}
|
|
783
787
|
uint64_t valid = cn == 64 ? ~0ull : ((1ull << cn) - 1ull);
|
|
784
|
-
n = yep_json_stage1_resolve(q, bs, op, ws, valid, &prev_in_string, &esc_carry,
|
|
785
|
-
|
|
788
|
+
n = yep_json_stage1_resolve(q, bs, op, ws, c0, valid, &prev_in_string, &esc_carry, off, idx,
|
|
789
|
+
n, flags);
|
|
786
790
|
}
|
|
787
791
|
*nidx = n;
|
|
788
792
|
return prev_in_string ? 0 : 1;
|
|
789
793
|
}
|
|
790
794
|
|
|
795
|
+
YEPTRIS_API int yep_json_stage1_masks_scalar(const char* p, size_t len, struct yep_s1_block* blocks,
|
|
796
|
+
size_t* nblocks, unsigned* flags) {
|
|
797
|
+
size_t nb = 0;
|
|
798
|
+
uint64_t prev_in_string = 0, esc_carry = 0;
|
|
799
|
+
for (size_t off = 0; off < len; off += 64) {
|
|
800
|
+
size_t cn = len - off < 64 ? len - off : 64;
|
|
801
|
+
uint64_t q = 0, bs = 0, op = 0, c0 = 0;
|
|
802
|
+
for (size_t k = 0; k < cn; k++) {
|
|
803
|
+
unsigned char c = (unsigned char)p[off + k];
|
|
804
|
+
uint64_t bit = 1ull << k;
|
|
805
|
+
if (c == '"') {
|
|
806
|
+
q |= bit;
|
|
807
|
+
} else if (c == '\\') {
|
|
808
|
+
bs |= bit;
|
|
809
|
+
} else if (c == '{' || c == '}' || c == '[' || c == ']' || c == ',' || c == ':') {
|
|
810
|
+
op |= bit;
|
|
811
|
+
}
|
|
812
|
+
if (c < 0x20) {
|
|
813
|
+
c0 |= bit;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
uint64_t valid = cn == 64 ? ~0ull : ((1ull << cn) - 1ull);
|
|
817
|
+
blocks[nb].q = q;
|
|
818
|
+
blocks[nb].bs = bs;
|
|
819
|
+
blocks[nb].op = op;
|
|
820
|
+
blocks[nb].c0 = c0;
|
|
821
|
+
blocks[nb].tokens =
|
|
822
|
+
yep_json_stage1_tokens(q, bs, op, c0, valid, &prev_in_string, &esc_carry, flags);
|
|
823
|
+
nb++;
|
|
824
|
+
}
|
|
825
|
+
*nblocks = nb;
|
|
826
|
+
return prev_in_string ? 0 : 1;
|
|
827
|
+
}
|
|
828
|
+
|
|
791
829
|
/* The per-chunk classifier: the kernels table's json_chunk slot
|
|
792
830
|
* (scalar reference in common, NEON/AVX2 TUs on their ISAs). */
|
|
@@ -93,8 +93,15 @@ YEPTRIS_API int yep_json_string(const char* p, size_t len, size_t* i, size_t* cl
|
|
|
93
93
|
* (scalar reference; the kernels table's json_stage1 slot carries the
|
|
94
94
|
* ISA twins). Writes the token positions stage 2 dispatches on —
|
|
95
95
|
* operators, string OPEN quotes, scalar-run starts — and returns 0
|
|
96
|
-
* only for an unterminated string. idx holds len+2 entries.
|
|
97
|
-
|
|
96
|
+
* only for an unterminated string. idx holds len+2 entries. flags
|
|
97
|
+
* (never NULL) accumulates the YEP_S1_* doc-level facts. */
|
|
98
|
+
YEPTRIS_API int yep_json_stage1_scalar(const char* p, size_t len, uint32_t* idx, size_t* nidx,
|
|
99
|
+
unsigned* flags);
|
|
100
|
+
/* The classification half (no emission) — the kernels table's
|
|
101
|
+
* json_stage1_masks slot carries the ISA twins. */
|
|
102
|
+
struct yep_s1_block; /* defined in scan/json.c (the span blocks) */
|
|
103
|
+
YEPTRIS_API int yep_json_stage1_masks_scalar(const char* p, size_t len, struct yep_s1_block* blocks,
|
|
104
|
+
size_t* nblocks, unsigned* flags);
|
|
98
105
|
|
|
99
106
|
/* The per-chunk byte-class classifier behind the flow kernels: the
|
|
100
107
|
* kernels table's json_chunk slot (common/simd_text.h) — yep_chunk_masks
|