}
PROGRAM_NEXT_INSTRUCTION
- PROGRAM_CASE(CHECK_DEPTH) {
- DEBUG_PRINTF("current depth %u, check min depth %u\n",
- tctxt->depth, ri->min_depth);
- if (ri->min_depth > tctxt->depth) {
- DEBUG_PRINTF("failed depth check\n");
- assert(ri->fail_jump); // must progress
- pc += ri->fail_jump;
- continue;
- }
- }
- PROGRAM_NEXT_INSTRUCTION
-
PROGRAM_CASE(CHECK_ONLY_EOD) {
struct core_info *ci = &tctxtToScratch(tctxt)->core_info;
if (end != ci->buf_offset + ci->len) {
const void *get() const {
switch (code()) {
- case ROSE_INSTR_CHECK_DEPTH: return &u.checkDepth;
case ROSE_INSTR_CHECK_ONLY_EOD: return &u.checkOnlyEod;
case ROSE_INSTR_CHECK_BOUNDS: return &u.checkBounds;
case ROSE_INSTR_CHECK_NOT_HANDLED: return &u.checkNotHandled;
size_t length() const {
switch (code()) {
- case ROSE_INSTR_CHECK_DEPTH: return sizeof(u.checkDepth);
case ROSE_INSTR_CHECK_ONLY_EOD: return sizeof(u.checkOnlyEod);
case ROSE_INSTR_CHECK_BOUNDS: return sizeof(u.checkBounds);
case ROSE_INSTR_CHECK_NOT_HANDLED: return sizeof(u.checkNotHandled);
}
union {
- ROSE_STRUCT_CHECK_DEPTH checkDepth;
ROSE_STRUCT_CHECK_ONLY_EOD checkOnlyEod;
ROSE_STRUCT_CHECK_BOUNDS checkBounds;
ROSE_STRUCT_CHECK_NOT_HANDLED checkNotHandled;
assert(targets[i] > offsets[i]); // jumps always progress
ri.u.anchoredDelay.done_jump = targets[i] - offsets[i];
break;
- case ROSE_INSTR_CHECK_DEPTH:
- assert(targets[i] > offsets[i]);
- ri.u.checkDepth.fail_jump = targets[i] - offsets[i];
- break;
case ROSE_INSTR_CHECK_ONLY_EOD:
assert(targets[i] > offsets[i]);
ri.u.checkOnlyEod.fail_jump = targets[i] - offsets[i];
static
pair<u32, u32> makeSparseIterProgram(build_context &bc,
map<u32, vector<vector<RoseInstruction>>> &predProgramLists,
- const vector<RoseVertex> &verts,
const vector<RoseInstruction> &root_program) {
vector<RoseInstruction> program;
u32 iter_offset = 0;
vector<u32> jump_table;
u32 curr_offset = 0;
- // Add a pre-check for min depth, if it's useful.
- if (!verts.empty()) {
- u32 min_depth = calcMinDepth(bc.depths, verts);
- if (min_depth > 1) {
- auto ri = RoseInstruction(ROSE_INSTR_CHECK_DEPTH);
- ri.u.checkDepth.min_depth = min_depth;
- program.push_back(ri);
- curr_offset = ROUNDUP_N(ri.length(), ROSE_INSTR_MIN_ALIGN);
- }
- }
-
program.push_back(RoseInstruction(ROSE_INSTR_SPARSE_ITER_BEGIN));
curr_offset += ROUNDUP_N(program.back().length(), ROSE_INSTR_MIN_ALIGN);
for (size_t i = 0; i < program.size(); i++) {
auto &ri = program[i];
switch (ri.code()) {
- case ROSE_INSTR_CHECK_DEPTH:
- ri.u.checkDepth.fail_jump = end_offset - curr_offset;
- break;
case ROSE_INSTR_SPARSE_ITER_BEGIN:
ri.u.sparseIterBegin.iter_offset = iter_offset;
ri.u.sparseIterBegin.jump_table = jump_table_offset;
}
// Put it all together.
- return makeSparseIterProgram(bc, predProgramLists, nonroot_verts,
- root_program).first;
+ return makeSparseIterProgram(bc, predProgramLists, root_program).first;
}
static
return {0, 0};
}
- return makeSparseIterProgram(bc, predProgramLists, {}, {});
+ return makeSparseIterProgram(bc, predProgramLists, {});
}
static
/** \brief Role program instruction opcodes. */
enum RoseInstructionCode {
ROSE_INSTR_ANCHORED_DELAY, //!< Delay until after anchored matcher.
- ROSE_INSTR_CHECK_DEPTH, //!< Check minimum graph depth.
ROSE_INSTR_CHECK_ONLY_EOD, //!< Role matches only at EOD.
ROSE_INSTR_CHECK_BOUNDS, //!< Bounds on distance from offset 0.
ROSE_INSTR_CHECK_NOT_HANDLED, //!< Test & set role in "handled".
u32 done_jump; //!< Jump forward this many bytes if successful.
};
-struct ROSE_STRUCT_CHECK_DEPTH {
- u8 code; //!< From enum RoseInstructionCode.
- u8 min_depth; //!< Minimum depth of this literal in the Rose graph.
- u32 fail_jump; //!< Jump forward this many bytes on failure.
-};
-
struct ROSE_STRUCT_CHECK_ONLY_EOD {
u8 code; //!< From enum RoseInstructionCode.
u32 fail_jump; //!< Jump forward this many bytes on failure.