Improve disassembly of continue/break in loops and switches

This commit is contained in:
baldurk
2020-05-05 17:36:16 +01:00
parent 9dbdee0199
commit bc3b6b9d6c
2 changed files with 72 additions and 5 deletions
@@ -992,23 +992,44 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint,
cfgStack.back().mergeTarget == decoded.targetLabel)
continue;
// if we're in a switch, branches to the merge block are printed as 'break'
if(!cfgStack.empty() && cfgStack.back().type == StructuredCFG::Switch &&
cfgStack.back().mergeTarget == decoded.targetLabel)
const StructuredCFG *lastLoopSwitch = NULL;
// walk stack to get the last switch/loop that we're in
for(size_t s = 0; s < cfgStack.size(); s++)
{
const StructuredCFG &cfg = cfgStack[cfgStack.size() - 1 - s];
if(cfg.type == StructuredCFG::Switch || cfg.type == StructuredCFG::Loop)
{
lastLoopSwitch = &cfg;
break;
}
}
// if we're in a switch/loop, branches to the merge block are printed as 'break'
if(lastLoopSwitch && lastLoopSwitch->mergeTarget == decoded.targetLabel)
{
ret += indent + "break;\n";
lineNum++;
continue;
}
// if we're in a loop, branches to the continue target are printed as 'continue'
if(lastLoopSwitch && lastLoopSwitch->type == StructuredCFG::Loop &&
lastLoopSwitch->continueTarget == decoded.targetLabel)
{
ret += indent + "continue;\n";
lineNum++;
continue;
}
// if we're in a switch and we're about to print a goto, see if it's a case label and
// print a 'nicer' goto. Fallthrough to the next case would be handled above as a
// redundant goto
if(!cfgStack.empty() && cfgStack.back().type == StructuredCFG::Switch)
if(lastLoopSwitch && lastLoopSwitch->type == StructuredCFG::Switch)
{
bool printed = false;
for(const PairLiteralIntegerIdRef &caseTarget : cfgStack.back().caseTargets)
for(const PairLiteralIntegerIdRef &caseTarget : lastLoopSwitch->caseTargets)
{
if(caseTarget.second == decoded.targetLabel)
{
@@ -1452,6 +1452,52 @@ void main()
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
break;
}
case 171:
{
vec4 ret = vec4(0,0,0,0);
// test loop continues
for(int i=0; i < flatLocalCoord + 5; i++)
{
ret.x += 0.1f;
if(i == 2)
{
ret.y += 0.2f;
continue;
}
ret.z += 0.1f;
if(i == 4)
{
continue;
}
ret.w += 0.1f;
}
Color = ret;
break;
}
case 172:
{
vec4 ret = vec4(0,0,0,0);
// test loop breaks
for(int i=0; i < flatLocalCoord + 5; i++)
{
ret.x += 0.1f;
if(i == 2)
{
break;
}
ret.y += 0.2f;
}
Color = ret;
break;
}
// test fall through
case 173:
Color += vec4(0.5, 0.5, 0.5, 0.5);
case 174:
{
Color += vec4(1.0, 1.0, 1.0, 1.0);
break;
}
default: break;
}
}