Skip to content

Commit

Permalink
Fixed an issue in getExitSet()
Browse files Browse the repository at this point in the history
Fixed an issue that caused getExitSet() to return an incorrect result in
certain configurations, leading to the unexpected exit of states unrelated to
the active transition.

fixes tklab-tud#193
  • Loading branch information
ryanhol-amazon-com committed Mar 12, 2020
1 parent 121887f commit 29f0b94
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 20 deletions.
26 changes: 16 additions & 10 deletions src/uscxml/interpreter/FastMicroStep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,21 +217,27 @@ std::pair<uint32_t, uint32_t> FastMicroStep::getExitSet(const Transition* transi
statesToExit.first = domainState->documentOrder + 1; // do not include domain itself

// end of exit set
XERCESC_NS::DOMElement* sibling = domainState->element->getNextElementSibling();
while(sibling && !isState(sibling))
sibling = sibling->getNextElementSibling();
if (sibling) {
State* siblingState = (State*)sibling->getUserData(X("uscxmlState"));
statesToExit.second = siblingState->documentOrder - 1;
} else {
statesToExit.second = _states.size() - 1;
statesToExit.second = statesToExit.first;

uint32_t second = statesToExit.first + 1;

while (second < _states.size()) {
State *childState = _states[second];

if (childState->ancestors[domain]) {
statesToExit.second = second;
} else {
break;
}

second++;
}

_exitSetCache[transition->postFixOrder] = statesToExit;
return statesToExit;
}

return _exitSetCache[transition->postFixOrder];
}

uint32_t FastMicroStep::getTransitionDomain(const Transition* transition) {
size_t i, j;
if (!transition->target.any())
Expand Down
26 changes: 16 additions & 10 deletions src/uscxml/interpreter/LargeMicroStep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,21 +1319,27 @@ std::pair<uint32_t, uint32_t> LargeMicroStep::getExitSet(const Transition* trans
statesToExit.first = domainState->documentOrder + 1; // do not include domain itself

// end of exit set
XERCESC_NS::DOMElement* sibling = domainState->element->getNextElementSibling();
while(sibling && !isState(sibling))
sibling = sibling->getNextElementSibling();
if (sibling) {
State* siblingState = (State*)sibling->getUserData(X("uscxmlState"));
statesToExit.second = siblingState->documentOrder - 1;
} else {
statesToExit.second = _states.size() - 1;
statesToExit.second = statesToExit.first;

uint32_t second = statesToExit.first + 1;

while (second < _states.size()) {
State *childState = _states[second];

if (childState->ancestors.find(domainState) != childState->ancestors.end()) {
statesToExit.second = second;
} else {
break;
}

second++;
}

_exitSetCache[transition->postFixOrder] = statesToExit;
return statesToExit;
}

return _exitSetCache[transition->postFixOrder];
}

uint32_t LargeMicroStep::getTransitionDomain(const Transition* transition) {
if (transition->target.size() == 0)
return std::numeric_limits<uint32_t>::max();
Expand Down

0 comments on commit 29f0b94

Please sign in to comment.