Построение срезов для программ на динамических языках - page 8

А.О. Крючков, В.А. Крищенко
8
переход в оператор
o
2
». Группировка операторов в простые блоки
будет выполнена при считывании траектории.
Процедуру сериализации ГПУ можно описать следующим псев-
докодом, в котором
operators
— массив всех операторов текущей
процедуры.
добавить_в_траекторию('CFG_START');
for i := 1 to length(operators):
o1 := operators[i];
if is_conditional_jump(o1):
for o2 in jump_targets(o1):
добавить_в_траекторию('$o1 JUMPSTO $o2');
else if is_return_from_procedure(o1):
добавить_в_траекторию('$o1 JUMPSTO End');
else:
o2 := next_operator(o1);
добавить_в_траекторию('$o1 JUMPSTO $o2');
добавить_в_траекторию('CFG_END');
Вызовы процедур
не относятся к зависимостям по управлению,
так как условный переход при самом вызове отсутствует. Информа-
ция о вызовах процедур используется для построения межпроцедур-
ных срезов [8]. В траекторию добавляются следующие типы записей:
вызов процедуры —
O
1
FUNCALL O
2
и возврат из процедуры —
O
1
RETURN
.
Записи
FUNCALL
предшествуют записи
REFS
для каждого фак-
тического параметра, передаваемого в процедуру. Аналогично после
записи
RETURN
должны следовать записи
REFS
, соответствующие
возвращенным из процедуры значениям. Обработка инструкции вы-
зова процедуры в модифицированном операторе принимает следую-
щий вид:
current_pos := определить_положение_текущей_инструкции;
func_def_pos := DEF_AT(вызываемая_процедура);
for v in actual_arguments:
ref_pos := DEF_AT(v);
добавить_в_траекторию('$current_pos REFS $ref_pos');
добавить_в_траекторию('$current_pos FUNCALL $func_def_pos');
перейти_к_выполнению_вызываемой_процедуры;
При возврате из процедуры записи траектории формируются по
следующему алгоритму:
current_pos :=
определить_положение_места_возврата_из_процедуры;
call_pos := определить_положение_места_вызова_процедуры;
for v in returned_values:
ref_pos := DEF_AT(v);
добавить_в_траекторию('$current_pos REFS $ref_pos');
1,2,3,4,5,6,7 9,10,11,12,13,14,15,16,17
Powered by FlippingBook