mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
rose: fix CHECK_NOT_HANDLED placement bug
The CHECK_NOT_HANDLED instruction was being inserted into an already partially-flattened program, which would result in jump offsets becoming incorrect. This change places it as part of the normal flow of program construction, which avoids this issue.
This commit is contained in:
parent
89bc2b4b39
commit
9826522e34
@ -3019,6 +3019,25 @@ void makeRoleCheckBounds(const RoseBuildImpl &build, RoseVertex v,
|
||||
program.insert(it, ri);
|
||||
}
|
||||
|
||||
static
|
||||
void makeRoleCheckNotHandled(build_context &bc, RoseVertex v,
|
||||
vector<RoseInstruction> &program) {
|
||||
auto ri = RoseInstruction(ROSE_INSTR_CHECK_NOT_HANDLED,
|
||||
JumpTarget::NEXT_BLOCK);
|
||||
|
||||
u32 handled_key;
|
||||
if (contains(bc.handledKeys, v)) {
|
||||
handled_key = bc.handledKeys.at(v);
|
||||
} else {
|
||||
handled_key = verify_u32(bc.handledKeys.size());
|
||||
bc.handledKeys.emplace(v, handled_key);
|
||||
}
|
||||
|
||||
ri.u.checkNotHandled.key = handled_key;
|
||||
|
||||
program.push_back(move(ri));
|
||||
}
|
||||
|
||||
static
|
||||
vector<RoseInstruction> makeProgram(RoseBuildImpl &build, build_context &bc,
|
||||
const RoseEdge &e) {
|
||||
@ -3042,6 +3061,13 @@ vector<RoseInstruction> makeProgram(RoseBuildImpl &build, build_context &bc,
|
||||
makeRoleCheckBounds(build, v, e, program);
|
||||
}
|
||||
|
||||
// This program may be triggered by different predecessors, with different
|
||||
// offset bounds. We must ensure we put this check/set operation after the
|
||||
// bounds check to deal with this case.
|
||||
if (hasGreaterInDegree(1, v, g)) {
|
||||
makeRoleCheckNotHandled(bc, v, program);
|
||||
}
|
||||
|
||||
makeRoleLookaround(build, bc, v, program);
|
||||
makeRoleCheckLeftfix(build, bc, v, program);
|
||||
|
||||
@ -3228,48 +3254,6 @@ void buildLeftInfoTable(const RoseBuildImpl &tbi, build_context &bc,
|
||||
*laggedRoseCount = lagIndex;
|
||||
}
|
||||
|
||||
static
|
||||
void makeRoleCheckNotHandled(build_context &bc, RoseVertex v,
|
||||
vector<RoseInstruction> &program) {
|
||||
auto ri = RoseInstruction(ROSE_INSTR_CHECK_NOT_HANDLED,
|
||||
JumpTarget::NEXT_BLOCK);
|
||||
|
||||
u32 handled_key;
|
||||
if (contains(bc.handledKeys, v)) {
|
||||
handled_key = bc.handledKeys.at(v);
|
||||
} else {
|
||||
handled_key = verify_u32(bc.handledKeys.size());
|
||||
bc.handledKeys.emplace(v, handled_key);
|
||||
}
|
||||
|
||||
ri.u.checkNotHandled.key = handled_key;
|
||||
|
||||
// This program may be triggered by different predecessors, with different
|
||||
// offset bounds. We must ensure we put this check/set operation after the
|
||||
// bounds check to deal with this case.
|
||||
auto it =
|
||||
find_if(begin(program), end(program), [](const RoseInstruction &ri) {
|
||||
return ri.code() > ROSE_INSTR_CHECK_BOUNDS;
|
||||
});
|
||||
program.insert(it, ri);
|
||||
}
|
||||
|
||||
static
|
||||
vector<RoseInstruction> makePredProgram(RoseBuildImpl &build, build_context &bc,
|
||||
const RoseEdge &e) {
|
||||
const RoseGraph &g = build.g;
|
||||
const RoseVertex v = target(e, g);
|
||||
|
||||
auto program = makeProgram(build, bc, e);
|
||||
|
||||
if (hasGreaterInDegree(1, v, g)) {
|
||||
// Only necessary when there is more than one pred.
|
||||
makeRoleCheckNotHandled(bc, v, program);
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
static
|
||||
u32 addPredBlocksSingle(
|
||||
map<u32, vector<vector<RoseInstruction>>> &predProgramLists,
|
||||
@ -3642,7 +3626,7 @@ u32 buildLiteralProgram(RoseBuildImpl &build, build_context &bc, u32 final_id,
|
||||
g[target(e, g)].idx);
|
||||
assert(contains(bc.roleStateIndices, u));
|
||||
u32 pred_state = bc.roleStateIndices.at(u);
|
||||
auto program = makePredProgram(build, bc, e);
|
||||
auto program = makeProgram(build, bc, e);
|
||||
predProgramLists[pred_state].push_back(program);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user