aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/hyperscan/src/nfa/sheng.c
diff options
context:
space:
mode:
authorIvan Blinkov <ivan@blinkov.ru>2022-02-10 16:47:10 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:47:10 +0300
commit1aeb9a455974457866f78722ad98114bafc84e8a (patch)
treee4340eaf1668684d83a0a58c36947c5def5350ad /contrib/libs/hyperscan/src/nfa/sheng.c
parentbd5ef432f5cfb1e18851381329d94665a4c22470 (diff)
downloadydb-1aeb9a455974457866f78722ad98114bafc84e8a.tar.gz
Restoring authorship annotation for Ivan Blinkov <ivan@blinkov.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/hyperscan/src/nfa/sheng.c')
-rw-r--r--contrib/libs/hyperscan/src/nfa/sheng.c1342
1 files changed, 671 insertions, 671 deletions
diff --git a/contrib/libs/hyperscan/src/nfa/sheng.c b/contrib/libs/hyperscan/src/nfa/sheng.c
index 3f36e21891..d4fb1250f2 100644
--- a/contrib/libs/hyperscan/src/nfa/sheng.c
+++ b/contrib/libs/hyperscan/src/nfa/sheng.c
@@ -1,159 +1,159 @@
-/*
+/*
* Copyright (c) 2016-2020, Intel Corporation
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "sheng.h"
-
-#include "accel.h"
-#include "sheng_internal.h"
-#include "nfa_api.h"
-#include "nfa_api_queue.h"
-#include "nfa_internal.h"
-#include "util/bitutils.h"
-#include "util/compare.h"
-#include "util/join.h"
-#include "util/simd_utils.h"
-
-enum MatchMode {
- CALLBACK_OUTPUT,
- STOP_AT_MATCH,
- NO_MATCHES
-};
-
-static really_inline
-const struct sheng *get_sheng(const struct NFA *n) {
- return (const struct sheng *)getImplNfa(n);
-}
-
-static really_inline
-const struct sstate_aux *get_aux(const struct sheng *sh, u8 id) {
- u32 offset = sh->aux_offset - sizeof(struct NFA) +
- (id & SHENG_STATE_MASK) * sizeof(struct sstate_aux);
- DEBUG_PRINTF("Getting aux for state %u at offset %llu\n",
- id & SHENG_STATE_MASK, (u64a)offset + sizeof(struct NFA));
- return (const struct sstate_aux *)((const char *) sh + offset);
-}
-
-static really_inline
-const union AccelAux *get_accel(const struct sheng *sh, u8 id) {
- const struct sstate_aux *saux = get_aux(sh, id);
- DEBUG_PRINTF("Getting accel aux at offset %u\n", saux->accel);
- const union AccelAux *aux = (const union AccelAux *)
- ((const char *)sh + saux->accel - sizeof(struct NFA));
- return aux;
-}
-
-static really_inline
-const struct report_list *get_rl(const struct sheng *sh,
- const struct sstate_aux *aux) {
- DEBUG_PRINTF("Getting report list at offset %u\n", aux->accept);
- return (const struct report_list *)
- ((const char *)sh + aux->accept - sizeof(struct NFA));
-}
-
-static really_inline
-const struct report_list *get_eod_rl(const struct sheng *sh,
- const struct sstate_aux *aux) {
- DEBUG_PRINTF("Getting EOD report list at offset %u\n", aux->accept);
- return (const struct report_list *)
- ((const char *)sh + aux->accept_eod - sizeof(struct NFA));
-}
-
-static really_inline
-char shengHasAccept(const struct sheng *sh, const struct sstate_aux *aux,
- ReportID report) {
- assert(sh && aux);
-
- const struct report_list *rl = get_rl(sh, aux);
- assert(ISALIGNED_N(rl, 4));
-
- DEBUG_PRINTF("report list has %u entries\n", rl->count);
-
- for (u32 i = 0; i < rl->count; i++) {
- if (rl->report[i] == report) {
- DEBUG_PRINTF("reporting %u\n", rl->report[i]);
- return 1;
- }
- }
-
- return 0;
-}
-
-static really_inline
-char fireSingleReport(NfaCallback cb, void *ctxt, ReportID r, u64a loc) {
- DEBUG_PRINTF("reporting %u\n", r);
- if (cb(0, loc, r, ctxt) == MO_HALT_MATCHING) {
- return MO_HALT_MATCHING; /* termination requested */
- }
- return MO_CONTINUE_MATCHING; /* continue execution */
-}
-
-static really_inline
-char fireReports(const struct sheng *sh, NfaCallback cb, void *ctxt,
- const u8 state, u64a loc, u8 *const cached_accept_state,
- ReportID *const cached_accept_id, char eod) {
- DEBUG_PRINTF("reporting matches @ %llu\n", loc);
-
- if (!eod && state == *cached_accept_state) {
- DEBUG_PRINTF("reporting %u\n", *cached_accept_id);
- if (cb(0, loc, *cached_accept_id, ctxt) == MO_HALT_MATCHING) {
- return MO_HALT_MATCHING; /* termination requested */
- }
-
- return MO_CONTINUE_MATCHING; /* continue execution */
- }
- const struct sstate_aux *aux = get_aux(sh, state);
- const struct report_list *rl = eod ? get_eod_rl(sh, aux) : get_rl(sh, aux);
- assert(ISALIGNED(rl));
-
- DEBUG_PRINTF("report list has %u entries\n", rl->count);
- u32 count = rl->count;
-
- if (!eod && count == 1) {
- *cached_accept_state = state;
- *cached_accept_id = rl->report[0];
-
- DEBUG_PRINTF("reporting %u\n", rl->report[0]);
- if (cb(0, loc, rl->report[0], ctxt) == MO_HALT_MATCHING) {
- return MO_HALT_MATCHING; /* termination requested */
- }
-
- return MO_CONTINUE_MATCHING; /* continue execution */
- }
-
- for (u32 i = 0; i < count; i++) {
- DEBUG_PRINTF("reporting %u\n", rl->report[i]);
- if (cb(0, loc, rl->report[i], ctxt) == MO_HALT_MATCHING) {
- return MO_HALT_MATCHING; /* termination requested */
- }
- }
- return MO_CONTINUE_MATCHING; /* continue execution */
-}
-
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sheng.h"
+
+#include "accel.h"
+#include "sheng_internal.h"
+#include "nfa_api.h"
+#include "nfa_api_queue.h"
+#include "nfa_internal.h"
+#include "util/bitutils.h"
+#include "util/compare.h"
+#include "util/join.h"
+#include "util/simd_utils.h"
+
+enum MatchMode {
+ CALLBACK_OUTPUT,
+ STOP_AT_MATCH,
+ NO_MATCHES
+};
+
+static really_inline
+const struct sheng *get_sheng(const struct NFA *n) {
+ return (const struct sheng *)getImplNfa(n);
+}
+
+static really_inline
+const struct sstate_aux *get_aux(const struct sheng *sh, u8 id) {
+ u32 offset = sh->aux_offset - sizeof(struct NFA) +
+ (id & SHENG_STATE_MASK) * sizeof(struct sstate_aux);
+ DEBUG_PRINTF("Getting aux for state %u at offset %llu\n",
+ id & SHENG_STATE_MASK, (u64a)offset + sizeof(struct NFA));
+ return (const struct sstate_aux *)((const char *) sh + offset);
+}
+
+static really_inline
+const union AccelAux *get_accel(const struct sheng *sh, u8 id) {
+ const struct sstate_aux *saux = get_aux(sh, id);
+ DEBUG_PRINTF("Getting accel aux at offset %u\n", saux->accel);
+ const union AccelAux *aux = (const union AccelAux *)
+ ((const char *)sh + saux->accel - sizeof(struct NFA));
+ return aux;
+}
+
+static really_inline
+const struct report_list *get_rl(const struct sheng *sh,
+ const struct sstate_aux *aux) {
+ DEBUG_PRINTF("Getting report list at offset %u\n", aux->accept);
+ return (const struct report_list *)
+ ((const char *)sh + aux->accept - sizeof(struct NFA));
+}
+
+static really_inline
+const struct report_list *get_eod_rl(const struct sheng *sh,
+ const struct sstate_aux *aux) {
+ DEBUG_PRINTF("Getting EOD report list at offset %u\n", aux->accept);
+ return (const struct report_list *)
+ ((const char *)sh + aux->accept_eod - sizeof(struct NFA));
+}
+
+static really_inline
+char shengHasAccept(const struct sheng *sh, const struct sstate_aux *aux,
+ ReportID report) {
+ assert(sh && aux);
+
+ const struct report_list *rl = get_rl(sh, aux);
+ assert(ISALIGNED_N(rl, 4));
+
+ DEBUG_PRINTF("report list has %u entries\n", rl->count);
+
+ for (u32 i = 0; i < rl->count; i++) {
+ if (rl->report[i] == report) {
+ DEBUG_PRINTF("reporting %u\n", rl->report[i]);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static really_inline
+char fireSingleReport(NfaCallback cb, void *ctxt, ReportID r, u64a loc) {
+ DEBUG_PRINTF("reporting %u\n", r);
+ if (cb(0, loc, r, ctxt) == MO_HALT_MATCHING) {
+ return MO_HALT_MATCHING; /* termination requested */
+ }
+ return MO_CONTINUE_MATCHING; /* continue execution */
+}
+
+static really_inline
+char fireReports(const struct sheng *sh, NfaCallback cb, void *ctxt,
+ const u8 state, u64a loc, u8 *const cached_accept_state,
+ ReportID *const cached_accept_id, char eod) {
+ DEBUG_PRINTF("reporting matches @ %llu\n", loc);
+
+ if (!eod && state == *cached_accept_state) {
+ DEBUG_PRINTF("reporting %u\n", *cached_accept_id);
+ if (cb(0, loc, *cached_accept_id, ctxt) == MO_HALT_MATCHING) {
+ return MO_HALT_MATCHING; /* termination requested */
+ }
+
+ return MO_CONTINUE_MATCHING; /* continue execution */
+ }
+ const struct sstate_aux *aux = get_aux(sh, state);
+ const struct report_list *rl = eod ? get_eod_rl(sh, aux) : get_rl(sh, aux);
+ assert(ISALIGNED(rl));
+
+ DEBUG_PRINTF("report list has %u entries\n", rl->count);
+ u32 count = rl->count;
+
+ if (!eod && count == 1) {
+ *cached_accept_state = state;
+ *cached_accept_id = rl->report[0];
+
+ DEBUG_PRINTF("reporting %u\n", rl->report[0]);
+ if (cb(0, loc, rl->report[0], ctxt) == MO_HALT_MATCHING) {
+ return MO_HALT_MATCHING; /* termination requested */
+ }
+
+ return MO_CONTINUE_MATCHING; /* continue execution */
+ }
+
+ for (u32 i = 0; i < count; i++) {
+ DEBUG_PRINTF("reporting %u\n", rl->report[i]);
+ if (cb(0, loc, rl->report[i], ctxt) == MO_HALT_MATCHING) {
+ return MO_HALT_MATCHING; /* termination requested */
+ }
+ }
+ return MO_CONTINUE_MATCHING; /* continue execution */
+}
+
#if defined(HAVE_AVX512VBMI)
// Sheng32
static really_inline
@@ -353,523 +353,523 @@ char fireReports64(const struct sheng64 *sh, NfaCallback cb, void *ctxt,
}
#endif // end of HAVE_AVX512VBMI
-/* include Sheng function definitions */
-#include "sheng_defs.h"
-
-static really_inline
-char runShengCb(const struct sheng *sh, NfaCallback cb, void *ctxt, u64a offset,
- u8 *const cached_accept_state, ReportID *const cached_accept_id,
- const u8 *cur_buf, const u8 *start, const u8 *end, u8 can_die,
- u8 has_accel, u8 single, const u8 **scanned, u8 *state) {
- DEBUG_PRINTF("Scanning %llu bytes (offset %llu) in callback mode\n",
- (u64a)(end - start), offset);
- DEBUG_PRINTF("start: %lli end: %lli\n", (s64a)(start - cur_buf),
- (s64a)(end - cur_buf));
- DEBUG_PRINTF("can die: %u has accel: %u single: %u\n", !!can_die,
- !!has_accel, !!single);
- int rv;
- /* scan and report all matches */
- if (can_die) {
- if (has_accel) {
- rv = sheng4_coda(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- } else {
- rv = sheng4_cod(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- }
- if (rv == MO_HALT_MATCHING) {
- return MO_DEAD;
- }
- rv = sheng_cod(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, *scanned, end,
- scanned);
- } else {
- if (has_accel) {
- rv = sheng4_coa(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- } else {
- rv = sheng4_co(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- }
- if (rv == MO_HALT_MATCHING) {
- return MO_DEAD;
- }
- rv = sheng_co(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, *scanned, end,
- scanned);
- }
- if (rv == MO_HALT_MATCHING) {
- return MO_DEAD;
- }
- return MO_ALIVE;
-}
-
-static really_inline
-void runShengNm(const struct sheng *sh, NfaCallback cb, void *ctxt, u64a offset,
- u8 *const cached_accept_state, ReportID *const cached_accept_id,
- const u8 *cur_buf, const u8 *start, const u8 *end, u8 can_die,
- u8 has_accel, u8 single, const u8 **scanned, u8 *state) {
- DEBUG_PRINTF("Scanning %llu bytes (offset %llu) in nomatch mode\n",
- (u64a)(end - start), offset);
- DEBUG_PRINTF("start: %lli end: %lli\n", (s64a)(start - cur_buf),
- (s64a)(end - cur_buf));
- DEBUG_PRINTF("can die: %u has accel: %u single: %u\n", !!can_die,
- !!has_accel, !!single);
- /* just scan the buffer */
- if (can_die) {
- if (has_accel) {
- sheng4_nmda(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start, end,
- scanned);
- } else {
- sheng4_nmd(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start, end,
- scanned);
- }
- sheng_nmd(state, cb, ctxt, sh, cached_accept_state, cached_accept_id,
- single, offset, cur_buf, *scanned, end, scanned);
- } else {
- sheng4_nm(state, cb, ctxt, sh, cached_accept_state, cached_accept_id,
- single, offset, cur_buf, start, end, scanned);
- sheng_nm(state, cb, ctxt, sh, cached_accept_state, cached_accept_id,
- single, offset, cur_buf, *scanned, end, scanned);
- }
-}
-
-static really_inline
-char runShengSam(const struct sheng *sh, NfaCallback cb, void *ctxt,
- u64a offset, u8 *const cached_accept_state,
- ReportID *const cached_accept_id, const u8 *cur_buf,
- const u8 *start, const u8 *end, u8 can_die, u8 has_accel,
- u8 single, const u8 **scanned, u8 *state) {
- DEBUG_PRINTF("Scanning %llu bytes (offset %llu) in stop at match mode\n",
- (u64a)(end - start), offset);
- DEBUG_PRINTF("start: %lli end: %lli\n", (s64a)(start - cur_buf),
- (s64a)(end - cur_buf));
- DEBUG_PRINTF("can die: %u has accel: %u single: %u\n", !!can_die,
- !!has_accel, !!single);
- int rv;
- /* scan until first match */
- if (can_die) {
- if (has_accel) {
- rv = sheng4_samda(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- } else {
- rv = sheng4_samd(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- }
- if (rv == MO_HALT_MATCHING) {
- return MO_DEAD;
- }
- /* if we stopped before we expected, we found a match */
- if (rv == MO_MATCHES_PENDING) {
- return MO_MATCHES_PENDING;
- }
-
- rv = sheng_samd(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, *scanned,
- end, scanned);
- } else {
- if (has_accel) {
- rv = sheng4_sama(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- } else {
- rv = sheng4_sam(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, start,
- end, scanned);
- }
- if (rv == MO_HALT_MATCHING) {
- return MO_DEAD;
- }
- /* if we stopped before we expected, we found a match */
- if (rv == MO_MATCHES_PENDING) {
- return MO_MATCHES_PENDING;
- }
-
- rv = sheng_sam(state, cb, ctxt, sh, cached_accept_state,
- cached_accept_id, single, offset, cur_buf, *scanned, end,
- scanned);
- }
- if (rv == MO_HALT_MATCHING) {
- return MO_DEAD;
- }
- /* if we stopped before we expected, we found a match */
- if (rv == MO_MATCHES_PENDING) {
- return MO_MATCHES_PENDING;
- }
- return MO_ALIVE;
-}
-
-static never_inline
-char runSheng(const struct sheng *sh, struct mq *q, s64a b_end,
- enum MatchMode mode) {
- u8 state = *(u8 *)q->state;
- u8 can_die = sh->flags & SHENG_FLAG_CAN_DIE;
- u8 has_accel = sh->flags & SHENG_FLAG_HAS_ACCEL;
- u8 single = sh->flags & SHENG_FLAG_SINGLE_REPORT;
-
- u8 cached_accept_state = 0;
- ReportID cached_accept_id = 0;
-
- DEBUG_PRINTF("starting Sheng execution in state %u\n",
- state & SHENG_STATE_MASK);
-
- if (q->report_current) {
- DEBUG_PRINTF("reporting current pending matches\n");
- assert(sh);
-
- q->report_current = 0;
-
- int rv;
- if (single) {
- rv = fireSingleReport(q->cb, q->context, sh->report,
- q_cur_offset(q));
- } else {
- rv = fireReports(sh, q->cb, q->context, state, q_cur_offset(q),
- &cached_accept_state, &cached_accept_id, 0);
- }
- if (rv == MO_HALT_MATCHING) {
- DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
- return MO_DEAD;
- }
-
- DEBUG_PRINTF("proceeding with matching\n");
- }
-
- assert(q_cur_type(q) == MQE_START);
- s64a start = q_cur_loc(q);
-
- DEBUG_PRINTF("offset: %lli, location: %lli, mode: %s\n", q->offset, start,
- mode == CALLBACK_OUTPUT ? "CALLBACK OUTPUT" :
- mode == NO_MATCHES ? "NO MATCHES" :
- mode == STOP_AT_MATCH ? "STOP AT MATCH" : "???");
-
- DEBUG_PRINTF("processing event @ %lli: %s\n", q->offset + q_cur_loc(q),
- q_cur_type(q) == MQE_START ? "START" :
- q_cur_type(q) == MQE_TOP ? "TOP" :
- q_cur_type(q) == MQE_END ? "END" : "???");
-
- const u8* cur_buf;
- if (start < 0) {
- DEBUG_PRINTF("negative location, scanning history\n");
- DEBUG_PRINTF("min location: %zd\n", -q->hlength);
- cur_buf = q->history + q->hlength;
- } else {
- DEBUG_PRINTF("positive location, scanning buffer\n");
- DEBUG_PRINTF("max location: %lli\n", b_end);
- cur_buf = q->buffer;
- }
-
- /* if we our queue event is past our end */
- if (mode != NO_MATCHES && q_cur_loc(q) > b_end) {
- DEBUG_PRINTF("current location past buffer end\n");
- DEBUG_PRINTF("setting q location to %llu\n", b_end);
- DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
- q->items[q->cur].location = b_end;
- return MO_ALIVE;
- }
-
- q->cur++;
-
- s64a cur_start = start;
-
- while (1) {
- DEBUG_PRINTF("processing event @ %lli: %s\n", q->offset + q_cur_loc(q),
- q_cur_type(q) == MQE_START ? "START" :
- q_cur_type(q) == MQE_TOP ? "TOP" :
- q_cur_type(q) == MQE_END ? "END" : "???");
- s64a end = q_cur_loc(q);
- if (mode != NO_MATCHES) {
- end = MIN(end, b_end);
- }
- assert(end <= (s64a) q->length);
- s64a cur_end = end;
-
- /* we may cross the border between history and current buffer */
- if (cur_start < 0) {
- cur_end = MIN(0, cur_end);
- }
-
- DEBUG_PRINTF("start: %lli end: %lli\n", start, end);
-
- /* don't scan zero length buffer */
- if (cur_start != cur_end) {
- const u8 * scanned = cur_buf;
- char rv;
-
- if (mode == NO_MATCHES) {
- runShengNm(sh, q->cb, q->context, q->offset,
- &cached_accept_state, &cached_accept_id, cur_buf,
- cur_buf + cur_start, cur_buf + cur_end, can_die,
- has_accel, single, &scanned, &state);
- } else if (mode == CALLBACK_OUTPUT) {
- rv = runShengCb(sh, q->cb, q->context, q->offset,
- &cached_accept_state, &cached_accept_id,
- cur_buf, cur_buf + cur_start, cur_buf + cur_end,
- can_die, has_accel, single, &scanned, &state);
- if (rv == MO_DEAD) {
- DEBUG_PRINTF("exiting in state %u\n",
- state & SHENG_STATE_MASK);
- return MO_DEAD;
- }
- } else if (mode == STOP_AT_MATCH) {
- rv = runShengSam(sh, q->cb, q->context, q->offset,
- &cached_accept_state, &cached_accept_id,
- cur_buf, cur_buf + cur_start,
- cur_buf + cur_end, can_die, has_accel, single,
- &scanned, &state);
- if (rv == MO_DEAD) {
- DEBUG_PRINTF("exiting in state %u\n",
- state & SHENG_STATE_MASK);
- return rv;
- } else if (rv == MO_MATCHES_PENDING) {
- assert(q->cur);
- DEBUG_PRINTF("found a match, setting q location to %zd\n",
- scanned - cur_buf + 1);
- q->cur--;
- q->items[q->cur].type = MQE_START;
- q->items[q->cur].location =
- scanned - cur_buf + 1; /* due to exiting early */
- *(u8 *)q->state = state;
- DEBUG_PRINTF("exiting in state %u\n",
- state & SHENG_STATE_MASK);
- return rv;
- }
- } else {
- assert(!"invalid scanning mode!");
- }
- assert(scanned == cur_buf + cur_end);
-
- cur_start = cur_end;
- }
-
- /* if we our queue event is past our end */
- if (mode != NO_MATCHES && q_cur_loc(q) > b_end) {
- DEBUG_PRINTF("current location past buffer end\n");
- DEBUG_PRINTF("setting q location to %llu\n", b_end);
- DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
- q->cur--;
- q->items[q->cur].type = MQE_START;
- q->items[q->cur].location = b_end;
- *(u8 *)q->state = state;
- return MO_ALIVE;
- }
-
- /* crossing over into actual buffer */
- if (cur_start == 0) {
- DEBUG_PRINTF("positive location, scanning buffer\n");
- DEBUG_PRINTF("max offset: %lli\n", b_end);
- cur_buf = q->buffer;
- }
-
- /* continue scanning the same buffer */
- if (end != cur_end) {
- continue;
- }
-
- switch (q_cur_type(q)) {
- case MQE_END:
- *(u8 *)q->state = state;
- q->cur++;
- DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
- if (can_die) {
- return (state & SHENG_STATE_DEAD) ? MO_DEAD : MO_ALIVE;
- }
- return MO_ALIVE;
- case MQE_TOP:
- if (q->offset + cur_start == 0) {
- DEBUG_PRINTF("Anchored start, going to state %u\n",
- sh->anchored);
- state = sh->anchored;
- } else {
- u8 new_state = get_aux(sh, state)->top;
- DEBUG_PRINTF("Top event %u->%u\n", state & SHENG_STATE_MASK,
- new_state & SHENG_STATE_MASK);
- state = new_state;
- }
- break;
- default:
- assert(!"invalid queue event");
- break;
- }
- q->cur++;
- }
-}
-
-char nfaExecSheng_B(const struct NFA *n, u64a offset, const u8 *buffer,
- size_t length, NfaCallback cb, void *context) {
- DEBUG_PRINTF("smallwrite Sheng\n");
- assert(n->type == SHENG_NFA);
- const struct sheng *sh = getImplNfa(n);
- u8 state = sh->anchored;
- u8 can_die = sh->flags & SHENG_FLAG_CAN_DIE;
- u8 has_accel = sh->flags & SHENG_FLAG_HAS_ACCEL;
- u8 single = sh->flags & SHENG_FLAG_SINGLE_REPORT;
- u8 cached_accept_state = 0;
- ReportID cached_accept_id = 0;
-
- /* scan and report all matches */
- int rv;
- s64a end = length;
- const u8 *scanned;
-
- rv = runShengCb(sh, cb, context, offset, &cached_accept_state,
- &cached_accept_id, buffer, buffer, buffer + end, can_die,
- has_accel, single, &scanned, &state);
- if (rv == MO_DEAD) {
- DEBUG_PRINTF("exiting in state %u\n",
- state & SHENG_STATE_MASK);
- return MO_DEAD;
- }
-
- DEBUG_PRINTF("%u\n", state & SHENG_STATE_MASK);
-
- const struct sstate_aux *aux = get_aux(sh, state);
-
- if (aux->accept_eod) {
- DEBUG_PRINTF("Reporting EOD matches\n");
- fireReports(sh, cb, context, state, end + offset, &cached_accept_state,
- &cached_accept_id, 1);
- }
-
- return state & SHENG_STATE_DEAD ? MO_DEAD : MO_ALIVE;
-}
-
-char nfaExecSheng_Q(const struct NFA *n, struct mq *q, s64a end) {
- const struct sheng *sh = get_sheng(n);
- char rv = runSheng(sh, q, end, CALLBACK_OUTPUT);
- return rv;
-}
-
-char nfaExecSheng_Q2(const struct NFA *n, struct mq *q, s64a end) {
- const struct sheng *sh = get_sheng(n);
- char rv = runSheng(sh, q, end, STOP_AT_MATCH);
- return rv;
-}
-
-char nfaExecSheng_QR(const struct NFA *n, struct mq *q, ReportID report) {
- assert(q_cur_type(q) == MQE_START);
-
- const struct sheng *sh = get_sheng(n);
- char rv = runSheng(sh, q, 0 /* end */, NO_MATCHES);
-
- if (rv && nfaExecSheng_inAccept(n, report, q)) {
- return MO_MATCHES_PENDING;
- }
- return rv;
-}
-
-char nfaExecSheng_inAccept(const struct NFA *n, ReportID report, struct mq *q) {
- assert(n && q);
-
- const struct sheng *sh = get_sheng(n);
- u8 s = *(const u8 *)q->state;
- DEBUG_PRINTF("checking accepts for %u\n", (u8)(s & SHENG_STATE_MASK));
-
- const struct sstate_aux *aux = get_aux(sh, s);
-
- if (!aux->accept) {
- return 0;
- }
-
- return shengHasAccept(sh, aux, report);
-}
-
-char nfaExecSheng_inAnyAccept(const struct NFA *n, struct mq *q) {
- assert(n && q);
-
- const struct sheng *sh = get_sheng(n);
- u8 s = *(const u8 *)q->state;
- DEBUG_PRINTF("checking accepts for %u\n", (u8)(s & SHENG_STATE_MASK));
-
- const struct sstate_aux *aux = get_aux(sh, s);
- return !!aux->accept;
-}
-
-char nfaExecSheng_testEOD(const struct NFA *nfa, const char *state,
- UNUSED const char *streamState, u64a offset,
- NfaCallback cb, void *ctxt) {
- assert(nfa);
-
- const struct sheng *sh = get_sheng(nfa);
- u8 s = *(const u8 *)state;
- DEBUG_PRINTF("checking EOD accepts for %u\n", (u8)(s & SHENG_STATE_MASK));
-
- const struct sstate_aux *aux = get_aux(sh, s);
-
- if (!aux->accept_eod) {
- return MO_CONTINUE_MATCHING;
- }
-
- return fireReports(sh, cb, ctxt, s, offset, NULL, NULL, 1);
-}
-
-char nfaExecSheng_reportCurrent(const struct NFA *n, struct mq *q) {
- const struct sheng *sh = (const struct sheng *)getImplNfa(n);
- NfaCallback cb = q->cb;
- void *ctxt = q->context;
- u8 s = *(u8 *)q->state;
- const struct sstate_aux *aux = get_aux(sh, s);
- u64a offset = q_cur_offset(q);
- u8 cached_state_id = 0;
- ReportID cached_report_id = 0;
- assert(q_cur_type(q) == MQE_START);
-
- if (aux->accept) {
- if (sh->flags & SHENG_FLAG_SINGLE_REPORT) {
- fireSingleReport(cb, ctxt, sh->report, offset);
- } else {
- fireReports(sh, cb, ctxt, s, offset, &cached_state_id,
+/* include Sheng function definitions */
+#include "sheng_defs.h"
+
+static really_inline
+char runShengCb(const struct sheng *sh, NfaCallback cb, void *ctxt, u64a offset,
+ u8 *const cached_accept_state, ReportID *const cached_accept_id,
+ const u8 *cur_buf, const u8 *start, const u8 *end, u8 can_die,
+ u8 has_accel, u8 single, const u8 **scanned, u8 *state) {
+ DEBUG_PRINTF("Scanning %llu bytes (offset %llu) in callback mode\n",
+ (u64a)(end - start), offset);
+ DEBUG_PRINTF("start: %lli end: %lli\n", (s64a)(start - cur_buf),
+ (s64a)(end - cur_buf));
+ DEBUG_PRINTF("can die: %u has accel: %u single: %u\n", !!can_die,
+ !!has_accel, !!single);
+ int rv;
+ /* scan and report all matches */
+ if (can_die) {
+ if (has_accel) {
+ rv = sheng4_coda(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ } else {
+ rv = sheng4_cod(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ return MO_DEAD;
+ }
+ rv = sheng_cod(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, *scanned, end,
+ scanned);
+ } else {
+ if (has_accel) {
+ rv = sheng4_coa(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ } else {
+ rv = sheng4_co(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ return MO_DEAD;
+ }
+ rv = sheng_co(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, *scanned, end,
+ scanned);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ return MO_DEAD;
+ }
+ return MO_ALIVE;
+}
+
+static really_inline
+void runShengNm(const struct sheng *sh, NfaCallback cb, void *ctxt, u64a offset,
+ u8 *const cached_accept_state, ReportID *const cached_accept_id,
+ const u8 *cur_buf, const u8 *start, const u8 *end, u8 can_die,
+ u8 has_accel, u8 single, const u8 **scanned, u8 *state) {
+ DEBUG_PRINTF("Scanning %llu bytes (offset %llu) in nomatch mode\n",
+ (u64a)(end - start), offset);
+ DEBUG_PRINTF("start: %lli end: %lli\n", (s64a)(start - cur_buf),
+ (s64a)(end - cur_buf));
+ DEBUG_PRINTF("can die: %u has accel: %u single: %u\n", !!can_die,
+ !!has_accel, !!single);
+ /* just scan the buffer */
+ if (can_die) {
+ if (has_accel) {
+ sheng4_nmda(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start, end,
+ scanned);
+ } else {
+ sheng4_nmd(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start, end,
+ scanned);
+ }
+ sheng_nmd(state, cb, ctxt, sh, cached_accept_state, cached_accept_id,
+ single, offset, cur_buf, *scanned, end, scanned);
+ } else {
+ sheng4_nm(state, cb, ctxt, sh, cached_accept_state, cached_accept_id,
+ single, offset, cur_buf, start, end, scanned);
+ sheng_nm(state, cb, ctxt, sh, cached_accept_state, cached_accept_id,
+ single, offset, cur_buf, *scanned, end, scanned);
+ }
+}
+
+static really_inline
+char runShengSam(const struct sheng *sh, NfaCallback cb, void *ctxt,
+ u64a offset, u8 *const cached_accept_state,
+ ReportID *const cached_accept_id, const u8 *cur_buf,
+ const u8 *start, const u8 *end, u8 can_die, u8 has_accel,
+ u8 single, const u8 **scanned, u8 *state) {
+ DEBUG_PRINTF("Scanning %llu bytes (offset %llu) in stop at match mode\n",
+ (u64a)(end - start), offset);
+ DEBUG_PRINTF("start: %lli end: %lli\n", (s64a)(start - cur_buf),
+ (s64a)(end - cur_buf));
+ DEBUG_PRINTF("can die: %u has accel: %u single: %u\n", !!can_die,
+ !!has_accel, !!single);
+ int rv;
+ /* scan until first match */
+ if (can_die) {
+ if (has_accel) {
+ rv = sheng4_samda(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ } else {
+ rv = sheng4_samd(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ return MO_DEAD;
+ }
+ /* if we stopped before we expected, we found a match */
+ if (rv == MO_MATCHES_PENDING) {
+ return MO_MATCHES_PENDING;
+ }
+
+ rv = sheng_samd(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, *scanned,
+ end, scanned);
+ } else {
+ if (has_accel) {
+ rv = sheng4_sama(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ } else {
+ rv = sheng4_sam(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, start,
+ end, scanned);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ return MO_DEAD;
+ }
+ /* if we stopped before we expected, we found a match */
+ if (rv == MO_MATCHES_PENDING) {
+ return MO_MATCHES_PENDING;
+ }
+
+ rv = sheng_sam(state, cb, ctxt, sh, cached_accept_state,
+ cached_accept_id, single, offset, cur_buf, *scanned, end,
+ scanned);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ return MO_DEAD;
+ }
+ /* if we stopped before we expected, we found a match */
+ if (rv == MO_MATCHES_PENDING) {
+ return MO_MATCHES_PENDING;
+ }
+ return MO_ALIVE;
+}
+
+static never_inline
+char runSheng(const struct sheng *sh, struct mq *q, s64a b_end,
+ enum MatchMode mode) {
+ u8 state = *(u8 *)q->state;
+ u8 can_die = sh->flags & SHENG_FLAG_CAN_DIE;
+ u8 has_accel = sh->flags & SHENG_FLAG_HAS_ACCEL;
+ u8 single = sh->flags & SHENG_FLAG_SINGLE_REPORT;
+
+ u8 cached_accept_state = 0;
+ ReportID cached_accept_id = 0;
+
+ DEBUG_PRINTF("starting Sheng execution in state %u\n",
+ state & SHENG_STATE_MASK);
+
+ if (q->report_current) {
+ DEBUG_PRINTF("reporting current pending matches\n");
+ assert(sh);
+
+ q->report_current = 0;
+
+ int rv;
+ if (single) {
+ rv = fireSingleReport(q->cb, q->context, sh->report,
+ q_cur_offset(q));
+ } else {
+ rv = fireReports(sh, q->cb, q->context, state, q_cur_offset(q),
+ &cached_accept_state, &cached_accept_id, 0);
+ }
+ if (rv == MO_HALT_MATCHING) {
+ DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
+ return MO_DEAD;
+ }
+
+ DEBUG_PRINTF("proceeding with matching\n");
+ }
+
+ assert(q_cur_type(q) == MQE_START);
+ s64a start = q_cur_loc(q);
+
+ DEBUG_PRINTF("offset: %lli, location: %lli, mode: %s\n", q->offset, start,
+ mode == CALLBACK_OUTPUT ? "CALLBACK OUTPUT" :
+ mode == NO_MATCHES ? "NO MATCHES" :
+ mode == STOP_AT_MATCH ? "STOP AT MATCH" : "???");
+
+ DEBUG_PRINTF("processing event @ %lli: %s\n", q->offset + q_cur_loc(q),
+ q_cur_type(q) == MQE_START ? "START" :
+ q_cur_type(q) == MQE_TOP ? "TOP" :
+ q_cur_type(q) == MQE_END ? "END" : "???");
+
+ const u8* cur_buf;
+ if (start < 0) {
+ DEBUG_PRINTF("negative location, scanning history\n");
+ DEBUG_PRINTF("min location: %zd\n", -q->hlength);
+ cur_buf = q->history + q->hlength;
+ } else {
+ DEBUG_PRINTF("positive location, scanning buffer\n");
+ DEBUG_PRINTF("max location: %lli\n", b_end);
+ cur_buf = q->buffer;
+ }
+
+ /* if we our queue event is past our end */
+ if (mode != NO_MATCHES && q_cur_loc(q) > b_end) {
+ DEBUG_PRINTF("current location past buffer end\n");
+ DEBUG_PRINTF("setting q location to %llu\n", b_end);
+ DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
+ q->items[q->cur].location = b_end;
+ return MO_ALIVE;
+ }
+
+ q->cur++;
+
+ s64a cur_start = start;
+
+ while (1) {
+ DEBUG_PRINTF("processing event @ %lli: %s\n", q->offset + q_cur_loc(q),
+ q_cur_type(q) == MQE_START ? "START" :
+ q_cur_type(q) == MQE_TOP ? "TOP" :
+ q_cur_type(q) == MQE_END ? "END" : "???");
+ s64a end = q_cur_loc(q);
+ if (mode != NO_MATCHES) {
+ end = MIN(end, b_end);
+ }
+ assert(end <= (s64a) q->length);
+ s64a cur_end = end;
+
+ /* we may cross the border between history and current buffer */
+ if (cur_start < 0) {
+ cur_end = MIN(0, cur_end);
+ }
+
+ DEBUG_PRINTF("start: %lli end: %lli\n", start, end);
+
+ /* don't scan zero length buffer */
+ if (cur_start != cur_end) {
+ const u8 * scanned = cur_buf;
+ char rv;
+
+ if (mode == NO_MATCHES) {
+ runShengNm(sh, q->cb, q->context, q->offset,
+ &cached_accept_state, &cached_accept_id, cur_buf,
+ cur_buf + cur_start, cur_buf + cur_end, can_die,
+ has_accel, single, &scanned, &state);
+ } else if (mode == CALLBACK_OUTPUT) {
+ rv = runShengCb(sh, q->cb, q->context, q->offset,
+ &cached_accept_state, &cached_accept_id,
+ cur_buf, cur_buf + cur_start, cur_buf + cur_end,
+ can_die, has_accel, single, &scanned, &state);
+ if (rv == MO_DEAD) {
+ DEBUG_PRINTF("exiting in state %u\n",
+ state & SHENG_STATE_MASK);
+ return MO_DEAD;
+ }
+ } else if (mode == STOP_AT_MATCH) {
+ rv = runShengSam(sh, q->cb, q->context, q->offset,
+ &cached_accept_state, &cached_accept_id,
+ cur_buf, cur_buf + cur_start,
+ cur_buf + cur_end, can_die, has_accel, single,
+ &scanned, &state);
+ if (rv == MO_DEAD) {
+ DEBUG_PRINTF("exiting in state %u\n",
+ state & SHENG_STATE_MASK);
+ return rv;
+ } else if (rv == MO_MATCHES_PENDING) {
+ assert(q->cur);
+ DEBUG_PRINTF("found a match, setting q location to %zd\n",
+ scanned - cur_buf + 1);
+ q->cur--;
+ q->items[q->cur].type = MQE_START;
+ q->items[q->cur].location =
+ scanned - cur_buf + 1; /* due to exiting early */
+ *(u8 *)q->state = state;
+ DEBUG_PRINTF("exiting in state %u\n",
+ state & SHENG_STATE_MASK);
+ return rv;
+ }
+ } else {
+ assert(!"invalid scanning mode!");
+ }
+ assert(scanned == cur_buf + cur_end);
+
+ cur_start = cur_end;
+ }
+
+ /* if we our queue event is past our end */
+ if (mode != NO_MATCHES && q_cur_loc(q) > b_end) {
+ DEBUG_PRINTF("current location past buffer end\n");
+ DEBUG_PRINTF("setting q location to %llu\n", b_end);
+ DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
+ q->cur--;
+ q->items[q->cur].type = MQE_START;
+ q->items[q->cur].location = b_end;
+ *(u8 *)q->state = state;
+ return MO_ALIVE;
+ }
+
+ /* crossing over into actual buffer */
+ if (cur_start == 0) {
+ DEBUG_PRINTF("positive location, scanning buffer\n");
+ DEBUG_PRINTF("max offset: %lli\n", b_end);
+ cur_buf = q->buffer;
+ }
+
+ /* continue scanning the same buffer */
+ if (end != cur_end) {
+ continue;
+ }
+
+ switch (q_cur_type(q)) {
+ case MQE_END:
+ *(u8 *)q->state = state;
+ q->cur++;
+ DEBUG_PRINTF("exiting in state %u\n", state & SHENG_STATE_MASK);
+ if (can_die) {
+ return (state & SHENG_STATE_DEAD) ? MO_DEAD : MO_ALIVE;
+ }
+ return MO_ALIVE;
+ case MQE_TOP:
+ if (q->offset + cur_start == 0) {
+ DEBUG_PRINTF("Anchored start, going to state %u\n",
+ sh->anchored);
+ state = sh->anchored;
+ } else {
+ u8 new_state = get_aux(sh, state)->top;
+ DEBUG_PRINTF("Top event %u->%u\n", state & SHENG_STATE_MASK,
+ new_state & SHENG_STATE_MASK);
+ state = new_state;
+ }
+ break;
+ default:
+ assert(!"invalid queue event");
+ break;
+ }
+ q->cur++;
+ }
+}
+
+char nfaExecSheng_B(const struct NFA *n, u64a offset, const u8 *buffer,
+ size_t length, NfaCallback cb, void *context) {
+ DEBUG_PRINTF("smallwrite Sheng\n");
+ assert(n->type == SHENG_NFA);
+ const struct sheng *sh = getImplNfa(n);
+ u8 state = sh->anchored;
+ u8 can_die = sh->flags & SHENG_FLAG_CAN_DIE;
+ u8 has_accel = sh->flags & SHENG_FLAG_HAS_ACCEL;
+ u8 single = sh->flags & SHENG_FLAG_SINGLE_REPORT;
+ u8 cached_accept_state = 0;
+ ReportID cached_accept_id = 0;
+
+ /* scan and report all matches */
+ int rv;
+ s64a end = length;
+ const u8 *scanned;
+
+ rv = runShengCb(sh, cb, context, offset, &cached_accept_state,
+ &cached_accept_id, buffer, buffer, buffer + end, can_die,
+ has_accel, single, &scanned, &state);
+ if (rv == MO_DEAD) {
+ DEBUG_PRINTF("exiting in state %u\n",
+ state & SHENG_STATE_MASK);
+ return MO_DEAD;
+ }
+
+ DEBUG_PRINTF("%u\n", state & SHENG_STATE_MASK);
+
+ const struct sstate_aux *aux = get_aux(sh, state);
+
+ if (aux->accept_eod) {
+ DEBUG_PRINTF("Reporting EOD matches\n");
+ fireReports(sh, cb, context, state, end + offset, &cached_accept_state,
+ &cached_accept_id, 1);
+ }
+
+ return state & SHENG_STATE_DEAD ? MO_DEAD : MO_ALIVE;
+}
+
+char nfaExecSheng_Q(const struct NFA *n, struct mq *q, s64a end) {
+ const struct sheng *sh = get_sheng(n);
+ char rv = runSheng(sh, q, end, CALLBACK_OUTPUT);
+ return rv;
+}
+
+char nfaExecSheng_Q2(const struct NFA *n, struct mq *q, s64a end) {
+ const struct sheng *sh = get_sheng(n);
+ char rv = runSheng(sh, q, end, STOP_AT_MATCH);
+ return rv;
+}
+
+char nfaExecSheng_QR(const struct NFA *n, struct mq *q, ReportID report) {
+ assert(q_cur_type(q) == MQE_START);
+
+ const struct sheng *sh = get_sheng(n);
+ char rv = runSheng(sh, q, 0 /* end */, NO_MATCHES);
+
+ if (rv && nfaExecSheng_inAccept(n, report, q)) {
+ return MO_MATCHES_PENDING;
+ }
+ return rv;
+}
+
+char nfaExecSheng_inAccept(const struct NFA *n, ReportID report, struct mq *q) {
+ assert(n && q);
+
+ const struct sheng *sh = get_sheng(n);
+ u8 s = *(const u8 *)q->state;
+ DEBUG_PRINTF("checking accepts for %u\n", (u8)(s & SHENG_STATE_MASK));
+
+ const struct sstate_aux *aux = get_aux(sh, s);
+
+ if (!aux->accept) {
+ return 0;
+ }
+
+ return shengHasAccept(sh, aux, report);
+}
+
+char nfaExecSheng_inAnyAccept(const struct NFA *n, struct mq *q) {
+ assert(n && q);
+
+ const struct sheng *sh = get_sheng(n);
+ u8 s = *(const u8 *)q->state;
+ DEBUG_PRINTF("checking accepts for %u\n", (u8)(s & SHENG_STATE_MASK));
+
+ const struct sstate_aux *aux = get_aux(sh, s);
+ return !!aux->accept;
+}
+
+char nfaExecSheng_testEOD(const struct NFA *nfa, const char *state,
+ UNUSED const char *streamState, u64a offset,
+ NfaCallback cb, void *ctxt) {
+ assert(nfa);
+
+ const struct sheng *sh = get_sheng(nfa);
+ u8 s = *(const u8 *)state;
+ DEBUG_PRINTF("checking EOD accepts for %u\n", (u8)(s & SHENG_STATE_MASK));
+
+ const struct sstate_aux *aux = get_aux(sh, s);
+
+ if (!aux->accept_eod) {
+ return MO_CONTINUE_MATCHING;
+ }
+
+ return fireReports(sh, cb, ctxt, s, offset, NULL, NULL, 1);
+}
+
+char nfaExecSheng_reportCurrent(const struct NFA *n, struct mq *q) {
+ const struct sheng *sh = (const struct sheng *)getImplNfa(n);
+ NfaCallback cb = q->cb;
+ void *ctxt = q->context;
+ u8 s = *(u8 *)q->state;
+ const struct sstate_aux *aux = get_aux(sh, s);
+ u64a offset = q_cur_offset(q);
+ u8 cached_state_id = 0;
+ ReportID cached_report_id = 0;
+ assert(q_cur_type(q) == MQE_START);
+
+ if (aux->accept) {
+ if (sh->flags & SHENG_FLAG_SINGLE_REPORT) {
+ fireSingleReport(cb, ctxt, sh->report, offset);
+ } else {
+ fireReports(sh, cb, ctxt, s, offset, &cached_state_id,
&cached_report_id, 0);
- }
- }
-
- return 0;
-}
-
-char nfaExecSheng_initCompressedState(const struct NFA *nfa, u64a offset,
- void *state, UNUSED u8 key) {
- const struct sheng *sh = get_sheng(nfa);
- u8 *s = (u8 *)state;
- *s = offset ? sh->floating: sh->anchored;
- return !(*s & SHENG_STATE_DEAD);
-}
-
-char nfaExecSheng_queueInitState(const struct NFA *nfa, struct mq *q) {
- assert(nfa->scratchStateSize == 1);
-
- /* starting in floating state */
- const struct sheng *sh = get_sheng(nfa);
- *(u8 *)q->state = sh->floating;
- DEBUG_PRINTF("starting in floating state\n");
- return 0;
-}
-
-char nfaExecSheng_queueCompressState(UNUSED const struct NFA *nfa,
- const struct mq *q, UNUSED s64a loc) {
- void *dest = q->streamState;
- const void *src = q->state;
- assert(nfa->scratchStateSize == 1);
- assert(nfa->streamStateSize == 1);
- *(u8 *)dest = *(const u8 *)src;
- return 0;
-}
-
-char nfaExecSheng_expandState(UNUSED const struct NFA *nfa, void *dest,
- const void *src, UNUSED u64a offset,
- UNUSED u8 key) {
- assert(nfa->scratchStateSize == 1);
- assert(nfa->streamStateSize == 1);
- *(u8 *)dest = *(const u8 *)src;
- return 0;
-}
+ }
+ }
+
+ return 0;
+}
+
+char nfaExecSheng_initCompressedState(const struct NFA *nfa, u64a offset,
+ void *state, UNUSED u8 key) {
+ const struct sheng *sh = get_sheng(nfa);
+ u8 *s = (u8 *)state;
+ *s = offset ? sh->floating: sh->anchored;
+ return !(*s & SHENG_STATE_DEAD);
+}
+
+char nfaExecSheng_queueInitState(const struct NFA *nfa, struct mq *q) {
+ assert(nfa->scratchStateSize == 1);
+
+ /* starting in floating state */
+ const struct sheng *sh = get_sheng(nfa);
+ *(u8 *)q->state = sh->floating;
+ DEBUG_PRINTF("starting in floating state\n");
+ return 0;
+}
+
+char nfaExecSheng_queueCompressState(UNUSED const struct NFA *nfa,
+ const struct mq *q, UNUSED s64a loc) {
+ void *dest = q->streamState;
+ const void *src = q->state;
+ assert(nfa->scratchStateSize == 1);
+ assert(nfa->streamStateSize == 1);
+ *(u8 *)dest = *(const u8 *)src;
+ return 0;
+}
+
+char nfaExecSheng_expandState(UNUSED const struct NFA *nfa, void *dest,
+ const void *src, UNUSED u64a offset,
+ UNUSED u8 key) {
+ assert(nfa->scratchStateSize == 1);
+ assert(nfa->streamStateSize == 1);
+ *(u8 *)dest = *(const u8 *)src;
+ return 0;
+}
#if defined(HAVE_AVX512VBMI)
// Sheng32