mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
Split CHECK_LEFTFIX into CHECK_{INFIX,PREFIX}
This commit is contained in:
parent
7a775e5fab
commit
5a1dd54049
@ -144,8 +144,9 @@ void rosePushDelayedMatch(const struct RoseEngine *t,
|
||||
static rose_inline
|
||||
char roseLeftfixCheckMiracles(const struct RoseEngine *t,
|
||||
const struct LeftNfaInfo *left,
|
||||
struct core_info *ci, struct mq *q, u64a end) {
|
||||
if (left->transient) {
|
||||
struct core_info *ci, struct mq *q, u64a end,
|
||||
const char is_infix) {
|
||||
if (!is_infix && left->transient) {
|
||||
// Miracles won't help us with transient leftfix engines; they only
|
||||
// scan for a limited time anyway.
|
||||
return 1;
|
||||
@ -178,7 +179,7 @@ found_miracle:
|
||||
|
||||
// If we're a prefix, then a miracle effectively results in us needing to
|
||||
// re-init our state and start fresh.
|
||||
if (!left->infix) {
|
||||
if (!is_infix) {
|
||||
if (miracle_loc != begin_loc) {
|
||||
DEBUG_PRINTF("re-init prefix state\n");
|
||||
q->cur = q->end = 0;
|
||||
@ -355,9 +356,10 @@ hwlmcb_rv_t roseTriggerSuffix(const struct RoseEngine *t,
|
||||
return HWLM_CONTINUE_MATCHING;
|
||||
}
|
||||
|
||||
static rose_inline
|
||||
static really_inline
|
||||
char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end) {
|
||||
u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end,
|
||||
const char is_infix) {
|
||||
struct core_info *ci = &scratch->core_info;
|
||||
|
||||
u32 ri = queueToLeftIndex(t, qi);
|
||||
@ -365,10 +367,12 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
|
||||
DEBUG_PRINTF("testing %s %s %u/%u with lag %u (maxLag=%u)\n",
|
||||
(left->transient ? "transient" : "active"),
|
||||
(left->infix ? "infix" : "prefix"),
|
||||
(is_infix ? "infix" : "prefix"),
|
||||
ri, qi, leftfixLag, left->maxLag);
|
||||
|
||||
assert(leftfixLag <= left->maxLag);
|
||||
assert(left->infix == is_infix);
|
||||
assert(!is_infix || !left->transient); // Only prefixes can be transient.
|
||||
|
||||
struct mq *q = scratch->queues + qi;
|
||||
char *state = scratch->core_info.state;
|
||||
@ -398,7 +402,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
initRoseQueue(t, qi, left, scratch);
|
||||
if (ci->buf_offset) { // there have been writes before us!
|
||||
s32 sp;
|
||||
if (left->transient) {
|
||||
if (!is_infix && left->transient) {
|
||||
sp = -(s32)ci->hlen;
|
||||
} else {
|
||||
sp = -(s32)loadRoseDelay(t, state, left);
|
||||
@ -408,7 +412,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
* at stream boundary */
|
||||
|
||||
pushQueueAt(q, 0, MQE_START, sp);
|
||||
if (left->infix || (ci->buf_offset + sp > 0 && !left->transient)) {
|
||||
if (is_infix || (ci->buf_offset + sp > 0 && !left->transient)) {
|
||||
loadStreamState(q->nfa, q, sp);
|
||||
} else {
|
||||
pushQueueAt(q, 1, MQE_TOP, sp);
|
||||
@ -425,7 +429,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
assert(loc >= q_cur_loc(q));
|
||||
assert(leftfixReport != MO_INVALID_IDX);
|
||||
|
||||
if (left->transient) {
|
||||
if (!is_infix && left->transient) {
|
||||
s64a start_loc = loc - left->transient;
|
||||
if (q_cur_loc(q) < start_loc) {
|
||||
q->cur = q->end = 0;
|
||||
@ -436,7 +440,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
}
|
||||
|
||||
if (q_cur_loc(q) < loc || q_last_type(q) != MQE_START) {
|
||||
if (left->infix) {
|
||||
if (is_infix) {
|
||||
if (infixTooOld(q, loc)) {
|
||||
DEBUG_PRINTF("infix %u died of old age\n", ri);
|
||||
goto nfa_dead;
|
||||
@ -445,7 +449,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
reduceInfixQueue(q, loc, left->maxQueueLen, q->nfa->maxWidth);
|
||||
}
|
||||
|
||||
if (!roseLeftfixCheckMiracles(t, left, ci, q, end)) {
|
||||
if (!roseLeftfixCheckMiracles(t, left, ci, q, end, is_infix)) {
|
||||
DEBUG_PRINTF("leftfix %u died due to miracle\n", ri);
|
||||
goto nfa_dead;
|
||||
}
|
||||
@ -482,6 +486,18 @@ nfa_dead:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static rose_inline
|
||||
char roseTestPrefix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end) {
|
||||
return roseTestLeftfix(t, scratch, qi, leftfixLag, leftfixReport, end, 0);
|
||||
}
|
||||
|
||||
static rose_inline
|
||||
char roseTestInfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end) {
|
||||
return roseTestLeftfix(t, scratch, qi, leftfixLag, leftfixReport, end, 1);
|
||||
}
|
||||
|
||||
static rose_inline
|
||||
void roseTriggerInfix(const struct RoseEngine *t, struct hs_scratch *scratch,
|
||||
u64a start, u64a end, u32 qi, u32 topEvent, u8 cancel) {
|
||||
@ -921,10 +937,21 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(CHECK_LEFTFIX) {
|
||||
if (!roseTestLeftfix(t, scratch, ri->queue, ri->lag, ri->report,
|
||||
end)) {
|
||||
DEBUG_PRINTF("failed leftfix check\n");
|
||||
PROGRAM_CASE(CHECK_INFIX) {
|
||||
if (!roseTestInfix(t, scratch, ri->queue, ri->lag, ri->report,
|
||||
end)) {
|
||||
DEBUG_PRINTF("failed infix check\n");
|
||||
assert(ri->fail_jump); // must progress
|
||||
pc += ri->fail_jump;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(CHECK_PREFIX) {
|
||||
if (!roseTestPrefix(t, scratch, ri->queue, ri->lag, ri->report,
|
||||
end)) {
|
||||
DEBUG_PRINTF("failed prefix check\n");
|
||||
assert(ri->fail_jump); // must progress
|
||||
pc += ri->fail_jump;
|
||||
continue;
|
||||
|
@ -194,7 +194,8 @@ public:
|
||||
case ROSE_INSTR_CHECK_BOUNDS: return &u.checkBounds;
|
||||
case ROSE_INSTR_CHECK_NOT_HANDLED: return &u.checkNotHandled;
|
||||
case ROSE_INSTR_CHECK_LOOKAROUND: return &u.checkLookaround;
|
||||
case ROSE_INSTR_CHECK_LEFTFIX: return &u.checkLeftfix;
|
||||
case ROSE_INSTR_CHECK_INFIX: return &u.checkInfix;
|
||||
case ROSE_INSTR_CHECK_PREFIX: return &u.checkPrefix;
|
||||
case ROSE_INSTR_ANCHORED_DELAY: return &u.anchoredDelay;
|
||||
case ROSE_INSTR_PUSH_DELAYED: return &u.pushDelayed;
|
||||
case ROSE_INSTR_CATCH_UP: return &u.catchUp;
|
||||
@ -236,7 +237,8 @@ public:
|
||||
case ROSE_INSTR_CHECK_BOUNDS: return sizeof(u.checkBounds);
|
||||
case ROSE_INSTR_CHECK_NOT_HANDLED: return sizeof(u.checkNotHandled);
|
||||
case ROSE_INSTR_CHECK_LOOKAROUND: return sizeof(u.checkLookaround);
|
||||
case ROSE_INSTR_CHECK_LEFTFIX: return sizeof(u.checkLeftfix);
|
||||
case ROSE_INSTR_CHECK_INFIX: return sizeof(u.checkInfix);
|
||||
case ROSE_INSTR_CHECK_PREFIX: return sizeof(u.checkPrefix);
|
||||
case ROSE_INSTR_ANCHORED_DELAY: return sizeof(u.anchoredDelay);
|
||||
case ROSE_INSTR_PUSH_DELAYED: return sizeof(u.pushDelayed);
|
||||
case ROSE_INSTR_CATCH_UP: return sizeof(u.catchUp);
|
||||
@ -277,7 +279,8 @@ public:
|
||||
ROSE_STRUCT_CHECK_BOUNDS checkBounds;
|
||||
ROSE_STRUCT_CHECK_NOT_HANDLED checkNotHandled;
|
||||
ROSE_STRUCT_CHECK_LOOKAROUND checkLookaround;
|
||||
ROSE_STRUCT_CHECK_LEFTFIX checkLeftfix;
|
||||
ROSE_STRUCT_CHECK_INFIX checkInfix;
|
||||
ROSE_STRUCT_CHECK_PREFIX checkPrefix;
|
||||
ROSE_STRUCT_ANCHORED_DELAY anchoredDelay;
|
||||
ROSE_STRUCT_PUSH_DELAYED pushDelayed;
|
||||
ROSE_STRUCT_CATCH_UP catchUp;
|
||||
@ -2724,8 +2727,11 @@ flattenProgram(const vector<vector<RoseInstruction>> &programs) {
|
||||
case ROSE_INSTR_CHECK_LOOKAROUND:
|
||||
ri.u.checkLookaround.fail_jump = jump_val;
|
||||
break;
|
||||
case ROSE_INSTR_CHECK_LEFTFIX:
|
||||
ri.u.checkLeftfix.fail_jump = jump_val;
|
||||
case ROSE_INSTR_CHECK_INFIX:
|
||||
ri.u.checkInfix.fail_jump = jump_val;
|
||||
break;
|
||||
case ROSE_INSTR_CHECK_PREFIX:
|
||||
ri.u.checkPrefix.fail_jump = jump_val;
|
||||
break;
|
||||
case ROSE_INSTR_DEDUPE:
|
||||
ri.u.dedupe.fail_jump = jump_val;
|
||||
@ -2986,11 +2992,22 @@ void makeRoleCheckLeftfix(RoseBuildImpl &build, build_context &bc, RoseVertex v,
|
||||
assert(!build.cc.streaming ||
|
||||
build.g[v].left.lag <= MAX_STORED_LEFTFIX_LAG);
|
||||
|
||||
auto ri = RoseInstruction(ROSE_INSTR_CHECK_LEFTFIX, JumpTarget::NEXT_BLOCK);
|
||||
ri.u.checkLeftfix.queue = lni.queue;
|
||||
ri.u.checkLeftfix.lag = build.g[v].left.lag;
|
||||
ri.u.checkLeftfix.report = build.g[v].left.leftfix_report;
|
||||
program.push_back(ri);
|
||||
bool is_prefix = build.isRootSuccessor(v);
|
||||
if (is_prefix) {
|
||||
auto ri =
|
||||
RoseInstruction(ROSE_INSTR_CHECK_PREFIX, JumpTarget::NEXT_BLOCK);
|
||||
ri.u.checkPrefix.queue = lni.queue;
|
||||
ri.u.checkPrefix.lag = build.g[v].left.lag;
|
||||
ri.u.checkPrefix.report = build.g[v].left.leftfix_report;
|
||||
program.push_back(move(ri));
|
||||
} else {
|
||||
auto ri =
|
||||
RoseInstruction(ROSE_INSTR_CHECK_INFIX, JumpTarget::NEXT_BLOCK);
|
||||
ri.u.checkInfix.queue = lni.queue;
|
||||
ri.u.checkInfix.lag = build.g[v].left.lag;
|
||||
ri.u.checkInfix.report = build.g[v].left.leftfix_report;
|
||||
program.push_back(move(ri));
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -288,7 +288,15 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(CHECK_LEFTFIX) {
|
||||
PROGRAM_CASE(CHECK_INFIX) {
|
||||
os << " queue " << ri->queue << endl;
|
||||
os << " lag " << ri->lag << endl;
|
||||
os << " report " << ri->report << endl;
|
||||
os << " fail_jump +" << ri->fail_jump << endl;
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(CHECK_PREFIX) {
|
||||
os << " queue " << ri->queue << endl;
|
||||
os << " lag " << ri->lag << endl;
|
||||
os << " report " << ri->report << endl;
|
||||
|
@ -49,7 +49,8 @@ enum RoseInstructionCode {
|
||||
ROSE_INSTR_CHECK_BOUNDS, //!< Bounds on distance from offset 0.
|
||||
ROSE_INSTR_CHECK_NOT_HANDLED, //!< Test & set role in "handled".
|
||||
ROSE_INSTR_CHECK_LOOKAROUND, //!< Lookaround check.
|
||||
ROSE_INSTR_CHECK_LEFTFIX, //!< Leftfix must be in accept state.
|
||||
ROSE_INSTR_CHECK_INFIX, //!< Infix engine must be in accept state.
|
||||
ROSE_INSTR_CHECK_PREFIX, //!< Prefix engine must be in accept state.
|
||||
ROSE_INSTR_PUSH_DELAYED, //!< Push delayed literal matches.
|
||||
ROSE_INSTR_CATCH_UP, //!< Catch up engines, anchored matches.
|
||||
ROSE_INSTR_SOM_ADJUST, //!< Set SOM from a distance to EOM.
|
||||
@ -141,7 +142,15 @@ struct ROSE_STRUCT_CHECK_LOOKAROUND {
|
||||
u32 fail_jump; //!< Jump forward this many bytes on failure.
|
||||
};
|
||||
|
||||
struct ROSE_STRUCT_CHECK_LEFTFIX {
|
||||
struct ROSE_STRUCT_CHECK_INFIX {
|
||||
u8 code; //!< From enum RoseInstructionCode.
|
||||
u32 queue; //!< Queue of leftfix to check.
|
||||
u32 lag; //!< Lag of leftfix for this case.
|
||||
ReportID report; //!< ReportID of leftfix to check.
|
||||
u32 fail_jump; //!< Jump forward this many bytes on failure.
|
||||
};
|
||||
|
||||
struct ROSE_STRUCT_CHECK_PREFIX {
|
||||
u8 code; //!< From enum RoseInstructionCode.
|
||||
u32 queue; //!< Queue of leftfix to check.
|
||||
u32 lag; //!< Lag of leftfix for this case.
|
||||
|
Loading…
x
Reference in New Issue
Block a user