Замыкания инструкций вместо диспетчеризации в цикле
Каждая инструкция становится замыканием со своими операндами и правилом управления, а вектор процедур переиспользуется между экземплярами машины.
Вопрос для размышления
Какую работу ассемблер может выполнить один раз, чтобы цикл машины только выбирал и вызывал процедуру выполнения?
Создание одного исполняемого замыкания для каждой ассемблированной инструкции
Захват имен регистров, выражений источников и целей ветвления при ассемблировании
Подсчет числа выбранных инструкций в цикле машины
Выполнение контроллеров без повторной проверки тегов инструкций на каждом цикле
Повторное использование последовательности процедур выполнения с новыми состояниями машины
Процедура make-execution-procedure выполняет диспетчеризацию по тегу инструкции во время ассемблирования. Каждая ветвь возвращает замыкание, которое запоминает целевой регистр, выражение источника, метку или необходимую операцию со стеком. Цикл выполнения больше не содержит форму cond для assign/test/branch/goto, а выбирает замыкание по значению pc и вызывает его.
Первая программа показывает, что даже присваивание, пропущенное ветвлением по истине, получает процедуру выполнения, поскольку ассемблирование охватывает структуру контроллера, а не один путь выполнения. Программа вычисления factorial один раз ассемблирует шесть замыканий и использует ту же последовательность для двух новых экземпляров машины. Замыкания по-прежнему получают текущую машину, поэтому регистры, стек, flag, pc и пакет операций остаются индивидуальными для каждого экземпляра.
Журнал ассемблирования возвращает ((assign test branch assign assign goto save assign restore perform halt) 11 #t complete 10 (10) 10). Повторно используемая последовательность factorial возвращает (6 (complete 120 28) (complete 6 18)).
На что обратить внимание в трассе
Отделите однократный проход map по данным инструкций от последующего цикла выборки и вызова. Пропущенное присваивание -1 все еще присутствует в generation-log, тогда как путь выполнения никогда не вызывает его замыкание. В примере с factorial убедитесь, что оба экземпляра машины разделяют список процедур, но не свои изменяемые регистры или счетчики.
Попробуйте сами
Измените программу и сравните результат.
Добавьте save и restore в контроллер factorial или оснастите каждое созданное замыкание записью тега инструкции. Предскажите, какая работа выполняется во время ассемблирования, а какая повторяется при каждом запуске машины.
Показать подсказку
Все, что определяется исключительно синтаксисом контроллера, относится к созданному замыканию. Значения регистров и зависящее от pc управление остаются входными данными времени выполнения.