Что происходит на этапе CFA.
Код разбирается на basic block-и - непрерывные последовательности, имеющие одну начальную и одну конечную точку.
В BBlock-е должна содержаться одна и только одна control flow команда - ей должен заканчиваться блок.
С точки зрения управляющих конструкций (if/while/switch), BBlock - это атомарная единица (т.е., его содержимым можно пренебречь). call/native должны рассматриваться как control flow команды только в том случае, если вызываемая функция не возвращает управление (поскольку компилятор R* в любом случае вставляет после таких call либо j либо ret, этим случаем тоже можно пренебречь).
(Следующий метод не претендует на единственно правильную истину, но у меня он работает)
Что получается: получаются две фазы: в первой, мы собираем блоки и функции. (функция представляем собой ориентированный граф, узлами которого являются б-блоки. На этом этапе я убираю все control flow команды и полностью ухожу от адресов в коде). во второй, из этих блоков собираются узлы-операторы AST.
Применительно к процитированному фрагменту, получаем следующее.
Команда #16 удаляется, следующая за ней функция выносится в отдельный объект.
Получаем:
; enter 0 2 - удаляется, переносится в параметры функции ---- #0: 2-Exit BBlock, exits: #1, #2 native n_3B0C6738 0 2; кстати, откуда здесь 2 ? должно быть один ; jf @40 - удалено, перенесено в параметры блока ---- #1: 1-exit BBlock, exit: #2 call sub_21 ---- #2: 0-exit block (предполагая, что дальше до ret ветвлений нет) ipush 0 native n_266716AC 1 0 ----2-exit блок - это либо if, либо while, в зависимости от того, есть для этого блока back edge, или нет.
(for рассматривается как разновидность while и определяется позднее).
Поскольку блок #0 не имеет back edge (т.е. перехода на него из следующих за ним блоков) - это if.
Дальше нужно определить, есть ли у него else block. Поскольку в блок #2 есть переход из блоков между #0 (блоком, в котором содержится if) и #2 (рассматриваемым блоком), он не является else блоком. Т.е. получаем:
function sub_0 (0 params, 0 frame) {
native n_3B0C6738 0 1
if {
call sub_21
}
ipush1 0
native n_266716AC 1 0
}
Примерно так, только у меня на момент получения такого текста, все выражения уже разобраны и получается нормальный высокоуровневый текст.









![СССР (USSR) [до 1991 года]](/images/flags/su.png)









