1
0
Fork 0

Decompiler: if/elseif/else

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@810 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
This commit is contained in:
Xuefer 2011-04-27 07:19:24 +00:00
parent a6c2fd36f9
commit 5b25fdb3b5
1 changed files with 49 additions and 0 deletions

View File

@ -708,6 +708,15 @@ class Decompiler
$this->outputPhp($EX, $range, $indent);
}
// }}}
function isIfCondition(&$EX, $range) // {{{
{
$opcodes = &$EX['opcodes'];
$firstOp = &$opcodes[$range[0]];
return $firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP
&& !empty($opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'])
&& $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1;
}
// }}}
function removeJmpInfo(&$EX, $line) // {{{
{
$opcodes = &$EX['opcodes'];
@ -831,6 +840,46 @@ class Decompiler
return;
}
// }}}
// {{{ if/elseif/else
if ($this->isIfCondition($EX, $range)) {
$this->beginComplexBlock($EX);
$isElseIf = false;
do {
$ifRange = array($range[0], $opcodes[$range[0]]['jmpouts'][0] - 1);
$this->removeJmpInfo($EX, $ifRange[0]);
$this->removeJmpInfo($EX, $ifRange[1]);
$condition = $this->getOpVal($opcodes[$ifRange[0]]['op1'], $EX);
echo $indent, $isElseIf ? 'else if' : 'if', ' (', str($condition, $EX), ') ', '{', PHP_EOL;
$this->recognizeAndDecompileClosedBlocks($EX, $ifRange, $indent . INDENT);
$EX['lastBlock'] = null;
echo $indent, '}', PHP_EOL;
$isElseIf = true;
// search for else if
$range[0] = $ifRange[1] + 1;
for ($i = $ifRange[1] + 1; $i <= $range[1]; ++$i) {
// find first jmpout
if (!empty($opcodes[$i]['jmpouts'])) {
if ($this->isIfCondition($EX, array($i, $range[1]))) {
$this->dasmBasicBlock($EX, array($range[0], $i));
$range[0] = $i;
}
break;
}
}
} while ($this->isIfCondition($EX, $range));
if ($ifRange[1] < $range[1]) {
$elseRange = array($ifRange[1], $range[1]);
echo $indent, 'else ', '{', PHP_EOL;
$this->recognizeAndDecompileClosedBlocks($EX, $elseRange, $indent . INDENT);
$EX['lastBlock'] = null;
echo $indent, '}', PHP_EOL;
}
$this->endComplexBlock($EX);
return;
}
// }}}
// {{{ try/catch
if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) {
$catchBlocks = array();