Сейбел: Может быть, вы в двух словах расскажете, какую проблему главным образом должен был решить BitBlt?
Ингаллс: Проблему несоответствия между необходимостью думать о дисплее как о пиксельном экране размером 1000x1000 и тем фактом, что память организована пословно. Если вы хотите взять четыре бита и перенести их
Далее, у нас есть растровый экран - построчный экран, два измерения. BitBlt умеет работать с ситуацией, когда источник и цель имеют различное число слов на сканирующую строку.
Это было проблемой, пока не появилась четкая идея того, что нужно сделать. И именно здесь требовалось очень обобщенное ядро, потому что если бы эта идея удалась, можно было бы не просто переносить куски из одного места в другое, но и осуществлять перекрывающую прокрутку. Заодно можно было и смешивать пикселы. Все это давало возможности для обобщения.
Я протестировал и убедился, что эта идея работает, сначала на Smalltalk, затем на ассемблере, а потом перегнал все в микрокод для Alto. В итоге мы могли проводить эти операции на полной скорости памяти, без задержек из-за этой мерзкой маскировки и переносов, поскольку все это можно было спрятать за временем цикла памяти.
Появление микропрограммных компьютеров было отличной мотивацией, поскольку стало ясно, что если создать самое небольшое ядро, которое будет делать то, что требуется, его можно записать в микрокод, и все заработает быстрее. Так что я всегда был настроен делать именно так.
То, что я придумал, пришло ко мне скорее в виде образа, чем чего-то другого: это было похоже на колесо. Если посмотреть на источник, цель и границы слова, то кажется, что колесо забирает целые слова
Таким образом, в центре операции BitBlt находится один длинный процесс сдвига, который забирает слова в источнике и переносит их к цели. Над этим уже следовало подумать. Но как только понимаешь, что можно таким образом хранить константы, становится ясно, что так можно размещать текст, брать образы символа из шрифта и помещать их в любое место экрана.
Сейбел: Вернемся к варианту Smalltalk на Бейсике: получается, это был предтеча Smalltalk, даже еще до Smalltalk-72?
Ингаллс: Именно так. Как только он заработал, я тут же начал делать практически полную версию на языке ассемблера, который у меня был на Nova. Мы использовали ее для отладки, а параллельно создавался компьютер Alto. Как только он стал доступен, мы переключились на него. Так и появился Smalltalk-72.
Сейбел: Итак, Smalltalk-72 был написан на ассемблере - когда же, в таком случае, он стал самодостаточным? Часто можно услышать, что лучшее в Smalltalk - то, что многое в нем написано на нем самом.
Ингаллс: Это было уже намного позже. Smalltalk-72 содержал большое количество кода на ассемблере. Как, собственно говоря, и Smalltalk-76. Основная разница между Smalltalk-72 и Smalltalk-76 заключалась в том, что я предложил идею движка байт-кода для Smalltalk, у которого был синтаксис на основе ключевых слов и который компилировался. Так что классы и даже стековые фреймы были реальными объектами - это к вашему замечанию о самодостаточности.
Сейбел: Когда вы пришли к идее написать интерпретатор байт-кода?
Ингаллс: Меня захватила такая идея: синтаксический анализ (пар-синг) Smalltalk- 72 выполняется на лету, и как минимум по двум причинам нам нужно было уметь компилировать нечто с той же семантикой, но не требующее моментального парсинга.
И я предложил синтаксис Smalltalk-76, который во многом был близок синтаксису Smalltalk-80. Затем встал другой вопрос: как компилировать, чтобы эффективно заработало с новым синтаксисом? Впрочем, единственным моментом, с которым возникли сложности, были так называемые удаленные вычисления - переменные, которые вы объявляете в одном месте, вычисляются в другом. Так в Smalltalk появились блоки - эквиваленты замыканий в других системах.
Сейбел: А почему просто не компилировать в машинный код?
Ингаллс: Мы по-прежнему экономили память, и наш вариант выходил исключительно компактным по сравнению с любым другим. И он должен был быть компактным, потому что запускать это все равно предстояло на Alto с 96 Кбайт памяти. Потом вышли более объемные разновидности - 128 Кбайт. То есть была важна компактность.
Сейбел: Значит, порожденный код был меньше, потому что байт-код был богаче, чем машинные инструкции?
Ингаллс: Да. Я был в восторге от идеи, навеянной работой Питера Дой-ча над движком байт-кода для Лиспа. Это взаимодействие очень повлияло на меня: появилось еще одно ядро, которое могло поместиться в микрокод. С самого начала работы я старался уместить ее в микрокоде для Alto.
Сейбел: Микрокод был в памяти, так что вы могли бы внедрить туда ядро Smalltalk, а затем переключиться на Лисп и встроить туда интерпретатор байт-кода на Лиспе.
Ингаллс: Да.
Сейбел: Что стало следующим шагом?
Ингаллс: Smalltalk-76 унаследовал тот же графический багаж: много специального кода для отрисовки линий, вывода текста и так далее. Но в то же время я уже сделал BitBlt, так что я переписал ядро, чтобы вся графика использовалась только BitBlt и Smalltalk, в итоге ядро стало значительно меньше. Это был Smalltalk-78 - первый, который мы запустили на микропроцессоре - на 8086.
Но это по-прежнему не был Smalltalk на Smalltalk. Smalltalk на Smalltalk не существовал до появления Squeak. Для Smalltalk-80 были спецификации виртуальной машины - они были опубликованы в виде книги, но все реализации были на Си или на ассемблере.
Сейбел: А компилятор?
Ингаллс: Компилятор был написан на Smalltalk. Собственно, когда мы писали книги о Smalltalk-80, мы с Дэйвом Робсоном - в основном, впрочем, он - написали на Smalltalk эмуляцию интерпретатора байт-кода. Это должно было стать частью Smalltalk-80: мы хотели помочь людям создать собственные виртуальные машины. Мы обнаружили, что очень полезно знать, какие именно байт-коды и в каком порядке выполняются при первом запуске системы.
Итак, он написал эмулятор на Smalltalk, потому что наш Smalltalk становился все быстрее, так что вполне подходил для этой цели, и создал все необходимые инструменты слежения, которые помогали пользователям при отладке.
Сейбел: Итак, вы решили помочь людям создавать собственные виртуальные машины, потому что Smalltalk-80 был задуман как спасательный круг, и Smalltalk мог выйти в свет, даже если бы PARC решила от негр отказаться?
Ингаллс: Именно так. Потом я ушел из индустрии, а когда вернулся, решил сделать Smalltalk для нового проекта. В то время все работало быстро: “Стоп, а почему бы не запустить версию этого на Smalltalk и не посмотреть, к чему это приведет?” Но главное “Ага!” заключалось в том, что нетрудно будет механически транслировать это в Си, и оно будет работать так же быстро, как и другие движки. Если вы хотели что-то изменить в виртуальной машине, можно было изменить это прямо в Smalltalk, нажать кнопочку, и все сразу оказалось бы в интерпретаторе.
Сейбел: Итак, вы взяли интерпретатор Smalltalk, написанный на каком-то подмножестве Smalltalk, и сделали специальный компилятор, который умеет компилировать это подмножество в Си?
Ингаллс: А транслятор Си был просто частью компилятора Smalltalk - с его помощью печатались синтаксические деревья. Это мы, собственно, уже делали в Xerox - Тед Кэглер написал