mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
rose: add CLEAR_WORK_DONE instruction
Preparatory work for allowing fragments to be shared between literals that squash groups and those that don't.
This commit is contained in:
parent
803f61d818
commit
18f843bcc1
@ -2166,6 +2166,12 @@ hwlmcb_rv_t roseRunProgram_i(const struct RoseEngine *t,
|
||||
}
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(CLEAR_WORK_DONE) {
|
||||
DEBUG_PRINTF("clear work_done flag\n");
|
||||
work_done = 0;
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4517,6 +4517,18 @@ u32 writeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
|
||||
bool is_anchored_program) {
|
||||
assert(!lit_ids.empty());
|
||||
|
||||
// If we have multiple literals and any of them squash groups, we will have
|
||||
// to add a CLEAR_WORK_DONE instruction to each literal program block to
|
||||
// clear the work_done flags so that it's only set if a state has been
|
||||
// switched on for that literal.
|
||||
|
||||
// Note that we add it to every lit program, as they may be
|
||||
// reordered/uniquified by assembleProgramBlocks() above.
|
||||
const bool needs_clear_work = lit_ids.size() > 1 &&
|
||||
any_of_in(lit_ids, [&](u32 lit_id) {
|
||||
return build.literal_info.at(lit_id).squash_group;
|
||||
});
|
||||
|
||||
vector<RoseProgram> blocks;
|
||||
|
||||
const vector<RoseEdge> no_edges;
|
||||
@ -4531,6 +4543,11 @@ u32 writeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
|
||||
}
|
||||
auto prog = buildLiteralProgram(build, bc, prog_build, lit_id,
|
||||
*edges_ptr, is_anchored_program);
|
||||
if (needs_clear_work) {
|
||||
RoseProgram clear_block;
|
||||
clear_block.add_before_end(make_unique<RoseInstrClearWorkDone>());
|
||||
prog.add_block(move(clear_block));
|
||||
}
|
||||
blocks.push_back(move(prog));
|
||||
}
|
||||
|
||||
|
@ -1100,6 +1100,9 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(CLEAR_WORK_DONE) {}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
default:
|
||||
os << " UNKNOWN (code " << int{code} << ")" << endl;
|
||||
os << " <stopping>" << endl;
|
||||
|
@ -48,6 +48,7 @@ RoseInstrSomZero::~RoseInstrSomZero() = default;
|
||||
RoseInstrSuffixesEod::~RoseInstrSuffixesEod() = default;
|
||||
RoseInstrMatcherEod::~RoseInstrMatcherEod() = default;
|
||||
RoseInstrEnd::~RoseInstrEnd() = default;
|
||||
RoseInstrClearWorkDone::~RoseInstrClearWorkDone() = default;
|
||||
|
||||
using OffsetMap = RoseInstruction::OffsetMap;
|
||||
|
||||
|
@ -1851,6 +1851,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class RoseInstrClearWorkDone
|
||||
: public RoseInstrBaseTrivial<ROSE_INSTR_CLEAR_WORK_DONE,
|
||||
ROSE_STRUCT_CLEAR_WORK_DONE,
|
||||
RoseInstrClearWorkDone> {
|
||||
public:
|
||||
~RoseInstrClearWorkDone() override;
|
||||
};
|
||||
|
||||
class RoseInstrEnd
|
||||
: public RoseInstrBaseTrivial<ROSE_INSTR_END, ROSE_STRUCT_END,
|
||||
RoseInstrEnd> {
|
||||
|
@ -141,7 +141,12 @@ enum RoseInstructionCode {
|
||||
*/
|
||||
ROSE_INSTR_CHECK_MED_LIT_NOCASE,
|
||||
|
||||
LAST_ROSE_INSTRUCTION = ROSE_INSTR_CHECK_MED_LIT_NOCASE //!< Sentinel.
|
||||
/**
|
||||
* \brief Clear the "work done" flag used by the SQUASH_GROUPS instruction.
|
||||
*/
|
||||
ROSE_INSTR_CLEAR_WORK_DONE,
|
||||
|
||||
LAST_ROSE_INSTRUCTION = ROSE_INSTR_CLEAR_WORK_DONE //!< Sentinel.
|
||||
};
|
||||
|
||||
struct ROSE_STRUCT_END {
|
||||
@ -517,4 +522,8 @@ struct ROSE_STRUCT_CHECK_MED_LIT_NOCASE {
|
||||
u32 fail_jump; //!< Jump forward this many bytes on failure.
|
||||
};
|
||||
|
||||
struct ROSE_STRUCT_CLEAR_WORK_DONE {
|
||||
u8 code; //!< From enum RoseInstructionCode.
|
||||
};
|
||||
|
||||
#endif // ROSE_ROSE_PROGRAM_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user