All Rose callbacks receive scratch as their context.
static really_inline
void init_for_block(const struct RoseEngine *t, struct hs_scratch *scratch,
RoseCallback callback, RoseCallbackSom som_callback,
- void *ctxt, char *state, char is_small_block) {
+ char *state, char is_small_block) {
init_state_for_block(t, state);
struct RoseContext *tctxt = &scratch->tctxt;
tctxt->filledDelayedSlots = 0;
tctxt->cb = callback;
tctxt->cb_som = som_callback;
- tctxt->userCtx = ctxt;
tctxt->lastMatchOffset = 0;
tctxt->minMatchOffset = 0;
tctxt->minNonMpvMatchOffset = 0;
}
void roseBlockExec_i(const struct RoseEngine *t, struct hs_scratch *scratch,
- RoseCallback callback, RoseCallbackSom som_callback,
- void *ctx) {
+ RoseCallback callback, RoseCallbackSom som_callback) {
assert(t);
assert(scratch);
assert(scratch->core_info.buf);
char *state = scratch->core_info.state;
- init_for_block(t, scratch, callback, som_callback, ctx, state,
+ init_for_block(t, scratch, callback, som_callback, state,
is_small_block);
struct RoseContext *tctxt = &scratch->tctxt;
return MO_CONTINUE_MATCHING;
}
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
offset, id);
updateLastMatchOffset(tctxt, offset);
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
updateLastMatchOffset(tctxt, offset);
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
offset, id);
updateLastMatchOffset(tctxt, offset);
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
return MO_CONTINUE_MATCHING;
}
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
offset, id);
updateLastMatchOffset(tctxt, offset);
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
updateLastMatchOffset(tctxt, offset);
/* must be a external report as haig cannot directly participate in chain */
- int cb_rv = tctxt->cb_som(from_offset, offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb_som(from_offset, offset, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
return MO_HALT_MATCHING;
} else if (cb_rv == ROSE_CONTINUE_MATCHING_NO_EXHAUST) {
return MO_CONTINUE_MATCHING;
}
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(offset, id, scratch);
return cb_rv;
}
DEBUG_PRINTF("masky got himself a match @%llu id %u !woot!\n", offset, id);
updateLastMatchOffset(tctxt, offset);
- int cb_rv = tctxt->cb(offset, id, tctxt->userCtx);
- return cb_rv;
+ return tctxt->cb(offset, id, tctxtToScratch(tctxt));
}
int roseNfaSomAdaptor(u64a from_offset, u64a offset, ReportID id,
updateLastMatchOffset(tctxt, offset);
/* must be a external report as haig cannot directly participate in chain */
- int cb_rv = tctxt->cb_som(from_offset, offset, id, tctxt->userCtx);
- return cb_rv;
+ return tctxt->cb_som(from_offset, offset, id, tctxtToScratch(tctxt));
}
static really_inline
goto next;
}
- if (tctxt->cb(anchored_end, anchored_report, tctxt->userCtx)
+ if (tctxt->cb(anchored_end, anchored_report, scratch)
== MO_HALT_MATCHING) {
DEBUG_PRINTF("termination requested\n");
return HWLM_TERMINATE_MATCHING;
goto next;
}
- if (tctxt->cb(anchored_end, anchored_report, tctxt->userCtx)
+ if (tctxt->cb(anchored_end, anchored_report, scratch)
== MO_HALT_MATCHING) {
DEBUG_PRINTF("termination requested\n");
return HWLM_TERMINATE_MATCHING;
static really_inline
void initContext(const struct RoseEngine *t, char *state, u64a offset,
struct hs_scratch *scratch, RoseCallback callback,
- RoseCallbackSom som_callback, void *ctx) {
+ RoseCallbackSom som_callback) {
struct RoseContext *tctxt = &scratch->tctxt;
tctxt->groups = loadGroups(t, state); /* TODO: diff groups for eod */
tctxt->lit_offset_adjust = scratch->core_info.buf_offset
tctxt->filledDelayedSlots = 0;
tctxt->cb = callback;
tctxt->cb_som = som_callback;
- tctxt->userCtx = ctx;
tctxt->lastMatchOffset = 0;
tctxt->minMatchOffset = 0;
tctxt->minNonMpvMatchOffset = 0;
if (nfaCheckFinalState(nfa, fstate, sstate, offset, scratch->tctxt.cb,
scratch->tctxt.cb_som,
- scratch->tctxt.userCtx) == MO_HALT_MATCHING) {
+ scratch) == MO_HALT_MATCHING) {
DEBUG_PRINTF("user instructed us to stop\n");
return;
}
if (rv) { /* nfa is still alive */
if (nfaCheckFinalState(nfa, fstate, sstate, offset,
scratch->tctxt.cb, scratch->tctxt.cb_som,
- scratch->tctxt.userCtx) ==
- MO_HALT_MATCHING) {
+ scratch) == MO_HALT_MATCHING) {
DEBUG_PRINTF("user instructed us to stop\n");
return;
}
void roseEodExec(const struct RoseEngine *t, u64a offset,
struct hs_scratch *scratch, RoseCallback callback,
- RoseCallbackSom som_callback, void *context) {
+ RoseCallbackSom som_callback) {
assert(scratch);
assert(callback);
- assert(context);
assert(t->requiresEodCheck);
DEBUG_PRINTF("ci buf %p/%zu his %p/%zu\n", scratch->core_info.buf,
scratch->core_info.len, scratch->core_info.hbuf,
char *state = scratch->core_info.state;
assert(state);
- initContext(t, state, offset, scratch, callback, som_callback, context);
+ initContext(t, state, offset, scratch, callback, som_callback);
roseEodExec_i(t, state, offset, scratch, 1);
}
return 1;
}
+static rose_inline
+hwlmcb_rv_t roseHaltIfExhausted(const struct RoseEngine *t,
+ struct hs_scratch *scratch) {
+ struct core_info *ci = &scratch->core_info;
+ if (isAllExhausted(t, ci->exhaustionVector)) {
+ if (!ci->broken) {
+ ci->broken = BROKEN_EXHAUSTED;
+ }
+ scratch->tctxt.groups = 0;
+ DEBUG_PRINTF("all exhausted, termination requested\n");
+ return HWLM_TERMINATE_MATCHING;
+ }
+
+ return HWLM_CONTINUE_MATCHING;
+}
+
static really_inline
hwlmcb_rv_t ensureQueueFlushed_i(const struct RoseEngine *t,
struct hs_scratch *scratch, u32 qi, s64a loc,
assert(!isQueueFull(q));
- if (isAllExhausted(t, scratch->core_info.exhaustionVector)) {
- if (!scratch->core_info.broken) {
- scratch->core_info.broken = BROKEN_EXHAUSTED;
- }
- tctxt->groups = 0;
- DEBUG_PRINTF("termination requested\n");
- return HWLM_TERMINATE_MATCHING;
- }
-
- return HWLM_CONTINUE_MATCHING;
+ return roseHaltIfExhausted(t, scratch);
}
static really_inline
DEBUG_PRINTF("firing callback reportId=%u, end=%llu\n", id, end);
updateLastMatchOffset(tctxt, end);
- int cb_rv = tctxt->cb(end, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb(end, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
DEBUG_PRINTF("termination requested\n");
return HWLM_TERMINATE_MATCHING;
return HWLM_CONTINUE_MATCHING;
}
- if (isAllExhausted(t, scratch->core_info.exhaustionVector)) {
- if (!scratch->core_info.broken) {
- scratch->core_info.broken = BROKEN_EXHAUSTED;
- }
- tctxt->groups = 0;
- DEBUG_PRINTF("termination requested\n");
- return HWLM_TERMINATE_MATCHING;
- }
-
- return HWLM_CONTINUE_MATCHING;
+ return roseHaltIfExhausted(t, scratch);
}
/* catches up engines enough to ensure any earlier mpv triggers are enqueued
hwlmcb_rv_t roseHandleSomMatch(const struct RoseEngine *t, char *state,
ReportID id, u64a start, u64a end,
struct RoseContext *tctxt, char in_anchored) {
- if (roseCatchUpTo(t, state, end, tctxtToScratch(tctxt), in_anchored)
+ struct hs_scratch *scratch = tctxtToScratch(tctxt);
+
+ if (roseCatchUpTo(t, state, end, scratch, in_anchored)
== HWLM_TERMINATE_MATCHING) {
return HWLM_TERMINATE_MATCHING;
}
assert(end == tctxt->minMatchOffset);
updateLastMatchOffset(tctxt, end);
- int cb_rv = tctxt->cb_som(start, end, id, tctxt->userCtx);
+ int cb_rv = tctxt->cb_som(start, end, id, scratch);
if (cb_rv == MO_HALT_MATCHING) {
DEBUG_PRINTF("termination requested\n");
return HWLM_TERMINATE_MATCHING;
return HWLM_CONTINUE_MATCHING;
}
- struct core_info *ci = &tctxtToScratch(tctxt)->core_info;
- if (isAllExhausted(t, ci->exhaustionVector)) {
- if (!ci->broken) {
- ci->broken = BROKEN_EXHAUSTED;
- }
- tctxt->groups = 0;
- DEBUG_PRINTF("termination requested\n");
- return HWLM_TERMINATE_MATCHING;
- }
-
- return HWLM_CONTINUE_MATCHING;
+ return roseHaltIfExhausted(t, scratch);
}
static rose_inline
PROGRAM_NEXT_INSTRUCTION
PROGRAM_CASE(REPORT_EOD) {
- if (tctxt->cb(end, ri->report, tctxt->userCtx) ==
- MO_HALT_MATCHING) {
+ if (tctxt->cb(end, ri->report, scratch) == MO_HALT_MATCHING) {
return HWLM_TERMINATE_MATCHING;
}
work_done = 1;
void roseBlockEodExec(const struct RoseEngine *t, u64a offset,
struct hs_scratch *scratch);
void roseBlockExec_i(const struct RoseEngine *t, struct hs_scratch *scratch,
- RoseCallback callback, RoseCallbackSom som_callback,
- void *context);
+ RoseCallback callback, RoseCallbackSom som_callback);
static really_inline
int roseBlockHasEodWork(const struct RoseEngine *t,
/* assumes core_info in scratch has been init to point to data */
static really_inline
void roseBlockExec(const struct RoseEngine *t, struct hs_scratch *scratch,
- RoseCallback callback, RoseCallbackSom som_callback,
- void *context) {
+ RoseCallback callback, RoseCallbackSom som_callback) {
assert(t);
assert(scratch);
assert(scratch->core_info.buf);
assert(t->maxBiAnchoredWidth == ROSE_BOUND_INF
|| length <= t->maxBiAnchoredWidth);
- roseBlockExec_i(t, scratch, callback, som_callback, context);
+ roseBlockExec_i(t, scratch, callback, som_callback);
if (!t->requiresEodCheck) {
return;
/* assumes core_info in scratch has been init to point to data */
void roseStreamExec(const struct RoseEngine *t, struct hs_scratch *scratch,
- RoseCallback callback, RoseCallbackSom som_callback,
- void *context);
+ RoseCallback callback, RoseCallbackSom som_callback);
void roseEodExec(const struct RoseEngine *t, u64a offset,
struct hs_scratch *scratch, RoseCallback callback,
- RoseCallbackSom som_callback, void *context);
+ RoseCallbackSom som_callback);
#define ROSE_CONTINUE_MATCHING_NO_EXHAUST 2
struct RoseEngine;
-// Note: identical signature to NfaCallback
+// Note: identical signature to NfaCallback, but all Rose callbacks must be
+// passed scratch as their context ptr.
+
typedef int (*RoseCallback)(u64a offset, ReportID id, void *context);
typedef int (*RoseCallbackSom)(u64a from_offset, u64a to_offset, ReportID id,
void *context);
}
void roseStreamExec(const struct RoseEngine *t, struct hs_scratch *scratch,
- RoseCallback callback, RoseCallbackSom som_callback,
- void *ctx) {
+ RoseCallback callback, RoseCallbackSom som_callback) {
DEBUG_PRINTF("OH HAI\n");
assert(t);
assert(scratch->core_info.hbuf);
tctxt->filledDelayedSlots = 0;
tctxt->cb = callback;
tctxt->cb_som = som_callback;
- tctxt->userCtx = ctx;
tctxt->lastMatchOffset = 0;
tctxt->minMatchOffset = offset;
tctxt->minNonMpvMatchOffset = offset;
DEBUG_PRINTF("blockmode scan len=%zu\n", scratch->core_info.len);
roseBlockExec(rose, scratch, selectAdaptor(rose),
- selectSomAdaptor(rose), scratch);
+ selectSomAdaptor(rose));
}
static really_inline
}
roseEodExec(rose, id->offset, scratch, selectAdaptor(rose),
- selectSomAdaptor(rose), scratch);
+ selectSomAdaptor(rose));
}
static never_inline
const struct RoseEngine *rose = stream_state->rose;
assert(rose);
- roseStreamExec(rose, scratch, selectAdaptor(rose), selectSomAdaptor(rose),
- scratch);
+ roseStreamExec(rose, scratch, selectAdaptor(rose), selectSomAdaptor(rose));
if (!told_to_stop_matching(scratch) &&
isAllExhausted(rose, scratch->core_info.exhaustionVector)) {
* match, cleared if top events arrive */
RoseCallback cb;
RoseCallbackSom cb_som;
- void *userCtx;
u32 filledDelayedSlots;
u32 curr_anchored_loc; /**< last read/written row */
u32 curr_row_offset; /**< last read/written entry */