проект компилятора для прямого исполнения - PullRequest
2 голосов
/ 16 июля 2010

Знаете ли вы хорошие конструкции компилятора, когда вывод должен быть помещен в память процесса и выполняться сразу после компиляции?

Я посмотрел несколько компиляторов SCHEME и прочитал все, что мог о V8. Есть интересные методы JIT, такие как встроенное кэширование, которое я хотел бы попробовать в своем собственном компиляторе.

Можно ответить почти очевидными вещами, такими как использование того факта, что вы компилируете внутри того же адресного пространства, в котором выполняется выходная программа. Меня интересуют варианты разработки для хранения программ-эмиттеров и компоновщиков.

Ответы [ 4 ]

1 голос
/ 24 июля 2010

Разговор о генерации кода для универсального компилятора практически одинаков, независимо от языка, как только вы приступите к нему. Сложности различных языков включают в себя эффективную обработку семантики сред в языке (т. Е. В схеме есть такие вещи, как замыкания и продолжения, а в чем-то вроде BASIC нет).

Но как только вы определились с тем, как такие вещи представлены (а некоторые влияют на эффективность с точки зрения разметки памяти, доступности и т. Д.), Генерация кода становится простой.

Различия, с которыми вы сталкиваетесь, это различия между, скажем, компилятором Scheme, который компилируется в C, а затем передает его компилятору C (который может скомпилировать его для сборки и передать его ассемблеру), против генерирование машинных инструкций непосредственно в ОЗУ вашим компилятором.

Различные этапы дают вам возможность добавить оптимизацию и разделить задачи. Генерация кода C может быть проще, чем генерация сборки или, особенно, машинного кода, потому что компилятор C может сделать для вас тяжелую работу (например, переносимость архитектуры).

Но несколько систем могут использовать C для компиляции кода, который сразу же загружается через процесс динамического связывания и выполняется.

Компиляция на промежуточный язык (а-ля JVM, CLR) также может упростить ситуацию, и тогда вы JIT это. Компиляция байт-кодов JVM не особенно сложна, так как это простой стековый компьютер. Оптимизация этого кода - это другая проблема, но преобразование в машинный код довольно просто. CLR отличается тем, что он захватывает больше семантики компилируемого кода. CLR больше походит на промежуточную фазу компиляции, в отличие от JVM, который является реальным кодом, предназначенным для выполнения как есть.

В конце концов, это где-то массивы данных в ОЗУ, независимо от того, являются ли эти данные машинным кодом или кодом виртуальной машины, и это вопрос деталей. Является ли этот массив собственно ОЗУ или отображается виртуальной машиной из файла - это другая деталь. С виртуальной памятью ваша система, вероятно, не заботится так или иначе.

Так что все сводится к тому, чтобы сосредоточиться на правильной генерации кода. Как только вы освоитесь, перенаправление его на другие компиляторы, в ОЗУ или в файлы является второстепенным шагом.

1 голос
/ 16 июля 2010

Я прочитал книгу под названием «Лисп в маленьких кусочках», которая была якобы хорошей, и обсудил реализацию Лисп. Если память не изменяет, и то, что я прочитал, было правильным, это может быть очень полезно для вас.

1 голос
/ 16 июля 2010

Частично актуально: Принципы программирования искусственного интеллекта в Common Lisp Питера Норвиг.

Эта книга охватывает множество вещей, с большим количеством примеров кода CL. В одной из последующих глав обсуждается компиляция кода. На самом деле, если я правильно помню, он пишет компилятор для Scheme и обсуждает различные методы оптимизации.

Конечно, когда вы работаете в Лиспсе, большая часть работы по "компиляции" уже сделана для вас языком. Я не помню, какой «исполняемый» код он создал, может быть, какой-то байт-код CL?

0 голосов
/ 24 июля 2010

Мне кажется, что большая часть работы компилятора выполняется к тому времени, когда вы выбираете, где именно вы должны начать выводить код.Будет ли он генерировать двоичный файл на диске или внутри пространства процесса, будет в большинстве случаев невидимым для большинства компонентов компилятора.Возможно, одна очевидная вещь, которую вы можете сделать, - это использовать информацию профилирования для текущего процесса для направления ваших проходов оптимизации.

Другой выбор дизайна будет связан с быстрым выполнением!Если это JIT, то вы не хотите тратить много времени на ожидание, я должен подумать.Предположительно, это может повлиять на другие дизайнерские решения, которые вы вынуждены принимать.Я думаю, что вы вряд ли пожалеете о том, что ваш компилятор стал быстрее по сравнению с другими ограничениями.

Так что для меня основной момент заключается в том, что вам действительно не нужно слишком заботиться о том, где код закончитсяпока вы на самом деле не на месте, чтобы положить его там.Кажется, нет никаких причин, по которым один и тот же компилятор не мог генерировать обычные двоичные файлы на диске, а также выводить их в текущее пространство процесса (с должным уважением к правильным заголовкам и двоичным форматам).

...