scratch->deduper.som_log_dirty = 0;
}
+ // Keep assertions in program report path happy. At offset zero, there can
+ // have been no earlier reports. At EOD, all earlier reports should have
+ // been handled and we will have been caught up to the stream offset by the
+ // time we are running boundary report programs.
+ scratch->tctxt.minMatchOffset = stream_offset;
+
const size_t match_len = 0;
const char in_anchored = 0;
hwlmcb_rv_t rv = roseRunProgram(rose, scratch, program, stream_offset,
report_block.push_back(move(ri));
}
+static
+void makeCatchup(RoseBuildImpl &build, build_context &bc,
+ const flat_set<ReportID> &reports,
+ vector<RoseInstruction> &program) {
+ if (!bc.needs_catchup) {
+ return;
+ }
+
+ // Everything except the INTERNAL_ROSE_CHAIN report needs catchup to run
+ // before reports are triggered.
+
+ auto report_needs_catchup = [&](const ReportID &id) {
+ const Report &report = build.rm.getReport(id);
+ return report.type != INTERNAL_ROSE_CHAIN;
+ };
+
+ if (!any_of(begin(reports), end(reports), report_needs_catchup)) {
+ DEBUG_PRINTF("none of the given reports needs catchup\n");
+ return;
+ }
+
+ program.emplace_back(ROSE_INSTR_CATCH_UP);
+}
+
static
void makeReport(RoseBuildImpl &build, build_context &bc, const ReportID id,
const bool has_som, vector<RoseInstruction> &program) {
report_block.push_back(move(ri));
}
- // Catch up -- everything except the INTERNAL_ROSE_CHAIN report needs this.
- // TODO: this could be floated in front of all the reports and only done
- // once.
- if (bc.needs_catchup && report.type != INTERNAL_ROSE_CHAIN) {
- report_block.emplace_back(ROSE_INSTR_CATCH_UP);
- }
-
// If this report has an exhaustion key, we can check it in the program
// rather than waiting until we're in the callback adaptor.
if (report.ekey != INVALID_EKEY) {
has_som = true;
}
- for (ReportID id : g[v].reports) {
+ const auto &reports = g[v].reports;
+ makeCatchup(build, bc, reports, program);
+
+ for (ReportID id : reports) {
makeReport(build, bc, id, has_som, program);
}
}
return 0;
}
+ // Note: no CATCHUP instruction is necessary in the boundary case, as we
+ // should always be caught up (and may not even have the resources in
+ // scratch to support it).
+
const bool has_som = false;
vector<RoseInstruction> program;
for (const auto &id : reports) {
makeRoleCheckNotHandled(bc, v, program);
}
+ const auto &reports = g[v].reports;
+ makeCatchup(build, bc, reports, program);
+
const bool has_som = false;
- for (const auto &id : g[v].reports) {
+ for (const auto &id : reports) {
makeReport(build, bc, id, has_som, program);
}