tctxt->lastEndOffset = real_end;
}
- const u32 *programs = getByOffset(t, t->litProgramOffset);
- assert(id < t->literalCount);
+ // Note that the "id" we have been handed is the program offset.
const u8 flags = ROSE_PROG_FLAG_IN_ANCHORED;
- if (roseRunProgram(t, scratch, programs[id], start, real_end, match_len,
+ if (roseRunProgram(t, scratch, id, start, real_end, match_len,
flags) == HWLM_TERMINATE_MATCHING) {
assert(can_stop_matching(scratch));
DEBUG_PRINTF("caller requested termination\n");
}
}
+static
+void remapIds(flat_set<ReportID> &reports, const vector<u32> &litPrograms) {
+ flat_set<ReportID> new_reports;
+ for (auto id : reports) {
+ assert(id < litPrograms.size());
+ new_reports.insert(litPrograms.at(id));
+ }
+ reports = move(new_reports);
+}
+
+/**
+ * \brief Replace the reports (which are literal final_ids) in the given
+ * raw_dfa with program offsets.
+ */
+static
+void remapIdsToPrograms(raw_dfa &rdfa, const vector<u32> &litPrograms) {
+ for (dstate &ds : rdfa.states) {
+ remapIds(ds.reports, litPrograms);
+ remapIds(ds.reports_eod, litPrograms);
+ }
+}
+
static
void populate_holder(const simple_anchored_info &sai, const set<u32> &exit_ids,
NGHolder *h_in) {
aligned_unique_ptr<anchored_matcher_info>
buildAnchoredMatcher(RoseBuildImpl &build, vector<raw_dfa> &dfas,
- size_t *asize) {
+ const vector<u32> &litPrograms, size_t *asize) {
const CompileContext &cc = build.cc;
if (dfas.empty()) {
return nullptr;
}
+ for (auto &rdfa : dfas) {
+ remapIdsToPrograms(rdfa, litPrograms);
+ }
+
vector<aligned_unique_ptr<NFA>> nfas;
vector<u32> start_offset; // start offset for each dfa (dots removed)
size_t total_size = buildNfas(dfas, &nfas, &start_offset, cc, build.rm);
/**
* \brief Construct an anchored_matcher_info runtime structure from the given
* set of DFAs.
+ *
+ * Remap the literal final_ids used for raw_dfa reports to the program offsets
+ * given in litPrograms.
*/
aligned_unique_ptr<anchored_matcher_info>
buildAnchoredMatcher(RoseBuildImpl &build, std::vector<raw_dfa> &dfas,
- size_t *asize);
+ const std::vector<u32> &litPrograms, size_t *asize);
u32 anchoredStateSize(const anchored_matcher_info &atable);
* that have already been pushed into the engine_blob. */
ue2::unordered_map<u32, u32> engineOffsets;
+ /** \brief Literal programs, indexed by final_id, after they have been
+ * written to the engine_blob. */
+ vector<u32> litPrograms;
+
/** \brief Minimum offset of a match from the floating table. */
u32 floatingMinLiteralMatchOffset = 0;
const u32 num_literals = build.final_id_to_literal.size();
auto lit_edge_map = findEdgesByLiteral(build);
- vector<u32> litPrograms(num_literals);
+ bc.litPrograms.resize(num_literals);
vector<u32> delayRebuildPrograms(num_literals);
for (u32 finalId = 0; finalId != num_literals; ++finalId) {
const auto &lit_edges = lit_edge_map[finalId];
- litPrograms[finalId] =
+ bc.litPrograms[finalId] =
writeLiteralProgram(build, bc, finalId, lit_edges);
delayRebuildPrograms[finalId] =
buildDelayRebuildProgram(build, bc, finalId);
}
u32 litProgramsOffset =
- add_to_engine_blob(bc, begin(litPrograms), end(litPrograms));
+ add_to_engine_blob(bc, begin(bc.litPrograms), end(bc.litPrograms));
u32 delayRebuildProgramsOffset = add_to_engine_blob(
bc, begin(delayRebuildPrograms), end(delayRebuildPrograms));
// Build anchored matcher.
size_t asize = 0;
u32 amatcherOffset = 0;
- auto atable = buildAnchoredMatcher(*this, anchored_dfas, &asize);
+ auto atable = buildAnchoredMatcher(*this, anchored_dfas, bc.litPrograms,
+ &asize);
if (atable) {
currOffset = ROUNDUP_CL(currOffset);
amatcherOffset = currOffset;