Как стать автором
Поиск
Написать публикацию
Обновить
13.17

Компиляторы *

Из исходного кода в машинный

Сначала показывать
Порог рейтинга
Уровень сложности

Почему мы пишем и храним код в текстовых файлах?

Время на прочтение8 мин
Количество просмотров24K


Простые текстовые форматы данных — прекрасная штука. Нет, без шуток. Возьмём, например, банальные txt-файлы. Ну красота же! В любом утюге есть текстовый редактор, можно открыть файл, почитать, записать. Любой уважающий себя язык программирования из коробки даст вам средства работы с текстовыми файлами. Или вот ранние сетевые протоколы — SMTP, POP3, HTTP 1.0. Это вообще такое блаженство, что слёзы на глаза наворачиваются. Можно взять telnet, приконнектиться к серверу, отдавать команды и читать ответы! Писать клиенты, серверы, снифферы, прокси — одно удовольствие.

Но время не стоит на месте и удобство работы программиста, к сожалению (или к счастью!), давно перестало быть главным критерием выбора технологий. В прекрасные текстовые файлы понадобилось вдруг добавлять графики, картинки и ссылки — и вот у нас есть форматы pdf и doc. С сетевыми протоколами вообще беда — людям зачем-то понадобились сжатие трафика, шифрование, мультиплексирование и другие страшные вещи. И вот уже у нас есть HTTP/2, с которым телнетом не очень-то поработаешь. Даже всем красивый REST разные негодяи типа Google нет-нет, да и пытаются заменить на какой-нибудь gRPC. И это я ещё не начал рассуждать о том, что мало что нынче сохраняется текстовые файлы — все почему-то используют какие-то базы данных, совершенно нечитабельные при открытии их текстовым редактором, но какой-то магией позволяющие информацию структурировать, индексировать, эффективно искать и т.д.

И вот здесь мы подходим к теме того, что я хотел бы обсудить. Как видите, все форматы хранения данных, протоколы и прочие штуки прошли длинный путь в поисках своего оптимального вида. Однако мы, программисты, продолжаем писать код наших программ в текстовых файлах, как делали это наши дедушки лет 50 назад (или уже больше?). Какую бы ОС мы ни использовали, какой бы модный язык ни выбрали, как бы ни была крутой наша IDE — результатом написания кода будут буквы в текстовом файле. Что, согласитесь, в теории совершенно не обязательно, ибо наши буквы компьютеру нужны как зайцу стоп-сигнал. Ему нужны машинные команды для выполнения, это просто нам удобнее описывать их какими-то там буквами. А на самом деле ведь «цикл» или «функция» будут тем, чем они являются, как ты их не назови и где ты их не храни. «Роза пахнет розой, хоть розой назови её, хоть нет».

Да, мы привыкли писать код в текстовые файлы. Вы открываете файл — ну и вроде бы видите код своей программы. Какую-то его часть, вернее. Как-то видите. Понимаете. Ну или думаете, что понимаете. Но вот пост на Facebook вы тоже открываете, видите и понимаете — а ведь Facebook точно этот пост не в текстовом файле хранил.

Давайте же посмотрим, какие проблемы нам создаёт хранение кода в виде набора текстовых строк.
Читать дальше →

Язык шаблонов для универсального сигнатурного анализатора кода

Время на прочтение5 мин
Количество просмотров8.4K

Процесс сигнатурного анализа кода в нашем проекте PT Application Inspector разбит на следующие этапы:


  1. парсинг в зависимое от языка представление (abstract syntax tree, AST);
  2. преобразование AST в независимый от языка унифицированный формат;
  3. непосредственное сопоставление с шаблонами, описанными на DSL.

О первых двух этапах было рассказано в предыдущих статьях «Теория и практика парсинга исходников с помощью ANTLR и Roslyn» и «Обработка древовидных структур и унифицированное AST». Данная статья посвящена третьему этапу, а именно: различным способам описания шаблонов, разработке специализированного языка (DSL) для их описания, а также примерам шаблонов на этом языке.


Читать дальше →

Обработка древовидных структур и унифицированное AST

Время на прочтение11 мин
Количество просмотров20K

Предыдущая статья серии была посвящена теории парсинга исходников с использованием ANTLR и Roslyn. В ней было отмечено, что процесс сигнатурного анализа кода в нашем проекте PT Application Inspector разбит на следующие этапы:


  1. парсинг в зависимое от языка представление (abstract syntax tree, AST);
  2. преобразование AST в независимый от языка унифицированный формат (Unified AST, UAST);
  3. непосредственное сопоставление с шаблонами, описанными на DSL.

Данная статья посвящена второму этапу, а именно: обработке AST с помощью стратегий Visitor и Listener, преобразованию AST в унифицированный формат, упрощению AST, а также алгоритму сопоставления древовидных структур.



Содержание


Читать дальше →

Персистентная ОС: ничто не блокируется

Время на прочтение6 мин
Количество просмотров18K
Это — статья-вопрос. У меня нет идеального ответа на то, что здесь будет описано. Какой-то есть, но насколько он удачен — неочевидно.

Статья касается одной из концептуальных проблем ОС Фантом, ну или любой другой системы, в которой есть персистентная и «волатильная» составляющие.

Для понимания сути проблемы стоит прочесть одну из предыдущих статей — про персистентную оперативную память.

Краткая постановка проблемы: В силу того, что прикладная программа в ОС Фантом персистентна (не перезапускается при перезагрузке), а ядро — нет (перезапускается при перезагрузке и может быть изменено между запусками), в такой системе нельзя делать блокирующие системные вызовы. Обычным способом.
Читать дальше →

Суперскалярный стековый процессор: оптимизация

Время на прочтение6 мин
Количество просмотров6.3K

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

Предыдущие статьи:
1 — описание работы на линейном куске
2 — вызов функций, сохраняем регистры
3 — вызов функций, взгляд изнутри
Читать дальше →

Сборка мусора в персистентной модели: от терабайта и дальше

Время на прочтение5 мин
Количество просмотров12K
Привет всем. Продолжу о Фантоме. Для понимания полезно прочесть статью про персистентную оперативку, а так же общую статью про Фантом на Открытых Системах. Но можно и так.

Итак, мы имеем ОС (или просто среду, не важно), которая обеспечивает прикладным программам персистентную оперативную память, и вообще персистентную «жизнь». Программы живут в общем адресном пространстве с управляемыми (managed) пойнтерами, объектной байткод-машиной, не замечают рестарта ОС и, в целом, счастливы.

Очевидно, что такой среде нужна сборка мусора. Но — какая?

Есть несколько проблем, навязанных спецификой.

Во-первых, теоретически, объём виртуальной памяти в такой среде огромен — терабайты, всё содержимое диска. Ведь мы отображаем в память всё и всегда.

Во-вторых, нас категорически не устраивают stop the world алгоритмы. Если для обычного процесса остановка в полсекундны может быть приемлема, то для виртуальной памяти, которая, большей частью, на диске, это будут уже полчаса, а то как бы не полсуток!

Наконец, если считать, что полная сборка мусора составляет полсуток, нас, наверное, это не устроит — было бы здорово иметь какой-то быстрый процесс сбора мусора, хотя бы и не полностью честный, пусть он часть мусора теряет, но если удаётся быстро вернуть 90% — уже хорошо.

Тут нужна оговорка. Вообще говоря, в системе, которая располагает парой терабайт виртуальной памяти, это не так уж критично — даже если не делать освобождение памяти полсуток, возможно, не так много и набежит — ну, например, истратится 2-3, ну 5 гигабайт, ну даже и 50 гигабайт — не жалко, диск большой.

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

Ок, итого у нас две задачи.
Читать дальше →

Облачное коммерческое объектно-ориентированное бизнес-приложение для платного туалета или мысли об архитектуре

Время на прочтение5 мин
Количество просмотров3.2K
Коллеги, всем доброго дня. На sql'e кто-то создал шутливую тему, но модераторы вырезали ее под корень. Однако, эта тема запустила некий мыслительный процесс, результатами которого хотел бы с Вами поделиться. Однако, к сожалению, вопросов она родила еще больше.
Итак, удаленный пост:
pisun
Облачное коммерческое объектно-ориентированное бизнес-приложение для платного туалета
У меня есть средний бизнес — три платных туалета. Считаю, что пришло время автоматизировать бизнес-процессы моего бизнеса с помощью коммерческих объектно-ориентированных облачных бизнес-приложений.

Какие подходы, методологии, фреймворки необходимо использовать для разработки облачных коммерческих объектно-ориентированных бизнес-приложений для платных туалетов?

Сколько строк коммерческого кода должно содержать облачное коммерческое объектно-ориентированное бизнес-приложение для платного туалета?

Какие есть готовые коробочные облачные коммерческие объектно-ориентированные бизнес-приложения для платного туалета?


И некоторые мои мысли, которые, возможно, будут кому-то интересны.

Давайте разложим архитектуру на 3 основных составляющих:
* это фронт (то, что видит клиент, с чем он работает)
* сервер приложений (отвечает за обработку бизнес-логики)
* база данных (где хранятся данные)

так же надо учесть два важных момента: учетная система — это не самоцель. Нельзя просто так хранить все данные — они зачем-то нужны. Вопрос, какие данные мы будем хранить, для чего они нужны:
* для ведения финансовой деятельности предприятия
* для предоставления регламентрованной отчетности контролирующим органам
* для изучения потребностей клиента и возможностей их максимально удовлетворить (анализ поставляемых продуктов и услуг, изучение поведенческих моделей, прогнозирования спроса на основе исторических данных)
Следовательно, мы храним те данные, которые нам будут необходимы в дальнейшем — для ведения управленческого и бухгалтерского учета и бизнес-аналитики. Так же, для ведения бухгалтерского и кадрового учета необходимо вести учет ряда документов строгой отчетности — чеки/акты/счета/приказы и т.д., но ряд этих функций относятся к бэк-офису и могут вестись в отдельной системе.
Однако, иногда необходимо предусмотреть и фиксирование операций из фронт-системы (чеки, авторизация на выполнение операций по банковской карте и т.п.). А это иногда требует отдельного ряда решений по интеграции с платежными системами и/или POS-системами, а так же обеспечения безопасности подобных операций и восстановлению истории операций при сбое.
Таким образом, мы подходим к немаловажным вещам — это backup, который, в принципе, возможен стандартными средствами СУБД, и безопасности.

Вернемся к архитектуре:
* сервер приложений (отвечает за обработку бизнес-логики)
* база данных (где хранятся данные)
Вопрос, на каком из этих слоев необходимо обеспечивать безопасность и разделение доступа?
Читать дальше →

Особенности и отличия языка программирования MSH от MUMPS

Время на прочтение6 мин
Количество просмотров4.2K
Основой для языка MSH послужил язык MUMPS. MUMPS разработан где то в 80-х годах прошлого столетия, как впрочем и многие другие современные языки. Он с самого начала разрабатывался как язык для создания больших информационных систем, работы с большими распределенными данными. В связи с чем имеет некоторую специфику. Программирование на этом языке несколько отличается от программирования на других языках. Несмотря на его малую распространенность у него существует довольно устойчивое сообщество в разных частях света программистов разрабатывающих на нем информационные системы. За время своего существования MUMPS мало изменился. Некоторые элементы языка потеряли актуальность. И язык на данный момент несколько архаичен. Хотелось бы иметь более современный язык подобный MUMPS. С этой целью и создавался язык MSH. Некоторые концепции языка MSH отличаются или отсутствуют в языке MUMPS. В основном для аудитории MUMS программистов и написан данный материал, но может и другим будет интересно.
Читать дальше →

Суперскалярный стековый процессор: подробности

Время на прочтение7 мин
Количество просмотров9.1K


Продолжение серии статей, разбирающих идею суперскалярного процессора с OoO и фронтендом стековой машины.
Тема данной статьи — вызов функций, вид изнутри.
Читать дальше →

Правила работы с Tasks API. Часть 1

Время на прочтение3 мин
Количество просмотров53K
С момента появления тасков в .NET прошло почти 6 лет. Однако я до сих пор вижу некоторую путаницу при использовании Task.Run() и Task.Factory.StartNew() в коде проектов. Если это можно списать на их схожесть, то некоторые проблемы могут возникнуть из-за dynamic в C#.

В этом посте я попытаюсь показать проблему, решение и истоки.

Проблема


Пусть у нас есть код, который выглядит так:

static async Task<dynamic> Compute(Task<dynamic> inner)
{
    return await Task.Factory.StartNew(async () => await inner);
}

Вопрос знатокам: есть ли в данном примере проблема? Если да, то какая? Код компилируется, возвращаемый тип Task на месте, модификатор async при использовании await — тоже.

Думаете, речь идет о пропущенном ConfigureAwait? Хаха!
Если интересно, тогда прошу под кат

Суперскалярный стековый процессор: продолжаем скрещивать ужа и ежа

Время на прочтение6 мин
Количество просмотров8.3K

Продолжение статьи, где удалось продемонстрировать, что фронтенд стековой машины вполне позволяет спрятать за ним суперскалярный процессор с OoO.
Тема данной статьи — вызов функций.
Читать дальше →

1.5 Компиляция SFML с помощью CMake

Время на прочтение11 мин
Количество просмотров25K


От переводчика: данная статья является пятой в цикле переводов официального руководства по библиотеке SFML. Прошлую статью можно найти тут. Данный цикл статей ставит своей целью предоставить людям, не знающим язык оригинала, возможность ознакомится с этой библиотекой. SFML — это простая и кроссплатформенная мультимедиа библиотека. SFML обеспечивает простой интерфейс для разработки игр и прочих мультимедийных приложений. Оригинальную статью можно найти тут. Начнем.
Читать дальше →

1.2 SFML и Code::Blocks (MinGW)

Время на прочтение5 мин
Количество просмотров33K


От переводчика: данная статья является второй в цикле переводов официального руководства по библиотеке SFML. Прошлую статью можно найти тут. Данный цикл статей ставит своей целью предоставить людям, не знающим язык оригинала, возможность ознакомится с этой библиотекой. SFML — это простая и кроссплатформенная мультимедиа библиотека. SFML обеспечивает простой интерфейс для разработки игр и прочих мультимедийных приложений. Оригинальную статью можно найти тут. Начнем.
Читать дальше →

Ближайшие события

Суперскалярный стековый процессор: скрещиваем ужа и ежа

Время на прочтение11 мин
Количество просмотров14K

В данной статье мы будем разрабатывать (программную) модель суперскалярного процессора с OOO и фронтендом стековой машины.
Читать дальше →

Теория и практика парсинга исходников с помощью ANTLR и Roslyn

Время на прочтение23 мин
Количество просмотров42K

В нашем проекте PT Application Inspector реализовано несколько подходов к анализу исходного кода на различных языках программирования:


  • поиск по сигнатурам;
  • исследование свойств математических моделей, полученных в результате статической абстрактной интерпретации кода;
  • динамический анализ развернутого приложения и верификация на нем результатов статического анализа.

Наш цикл статей посвящен структуре и принципам работы модуля сигнатурного поиска (PM, pattern matching). Преимущества такого анализатора — скорость работы, простота описания шаблонов и масштабируемость на другие языки. Среди недостатков можно выделить то, что модуль не в состоянии анализировать сложные уязвимости, требующие построения высокоуровневых моделей выполнения кода.



К разрабатываемому модулю были, в числе прочих, сформулированы следующие требования:


  • поддержка нескольких языков программирования и простое добавление новых;
  • поддержка анализа кода, содержащего синтаксические и семантические ошибки;
  • возможность описания шаблонов на универсальном языке (DSL, domain specific language).

В нашем случае все шаблоны описывают какие-либо уязвимости или недостатки в исходном коде.


Весь процесс анализа кода может быть разбит на следующие этапы:


  1. парсинг в зависимое от языка представление (abstract syntax tree, AST);
  2. преобразование AST в независимый от языка унифицированный формат;
  3. непосредственное сопоставление с шаблонами, описанными на DSL.

Данная статья посвящена первому этапу, а именно: парсингу, сравнению функциональных возможностей и особенностей различных парсеров, применению теории на практике на примере грамматик Java, PHP, PLSQL, TSQL и даже C#. Остальные этапы будут рассмотрены в следующих публикациях.

Читать дальше →

Грэйс «бабуля COBOL» Хоппер

Время на прочтение4 мин
Количество просмотров24K
«Она истинный морпех, но если копнуть глубже, мы найдем пирата.»



Грейс Хоппер (Grace Hopper) — американская учёная и контр-адмирал флота США. Программист гарвардского компьютера Марк I.

  • В детстве разобрала 7 будильников, чтобы понять, как все устроено.
  • Боролась за идею машинонезависимого языка программирования.
  • Разработала первый компилятор.
  • Приложила руку к распространению мема «дебаггинг» (выловив настоящего жука из Mark 2).
  • Могла объяснить сообразительным военным, что такое «наносекунда» и «пикосекунда». На пальцах.
  • В её честь назвали эсминец USS Hopper (DDG-70).
  • И суперкомпьютер Cray XE6 «Hopper».
  • И в ее честь именная премия Ассоциации вычислительной техники (ACM) — присуждается молодому (до 35 лет) специалисту, сделавшему значительный вклад в области вычислительной техники.

Построив успешную карьеру математика в Йеле (защитив докторскую и став профессором), Грэйс Хоппер в 1943 (37 лет) пошла добровольцем во Флот.
Но у нее был недобор по весу 6 кг, поэтому пришлось сесть «за клавиатуру» Гарвардского Mark 1.


Стек стеком погоняет, или преобразование байткода виртуальной машины Java в байткод машины Фантом ОС

Время на прочтение5 мин
Количество просмотров13K
ОС Фантом — экспериментальная операционная система, содержащая на прикладном уровне виртуальную байткод-машину в персистентной оперативной памяти.

Один из двух ключевых запланированных для ОС Фантом путей миграции существующего кода — преобразование байткода Java в байткод Фантом.

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

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

Естественно, что и набор операций стековых машин местами схож как две капли.

Но, безусловно, есть и весьма существенные отличия.
Читать дальше →

LLVM: компилятор своими руками. Введение

Время на прочтение14 мин
Количество просмотров59K
Представим себе, что в один прекрасный день вам пришла в голову идея процессора собственной, ни на что не похожей архитектуры, и вам очень захотелось эту идею реализовать «в железе». К счастью, в этом нет ничего невозможного. Немного верилога, и вот ваша идея реализована. Вам уже снятся прекрасные сны про то, как Intel разорилась, Microsoft спешно переписывает Windows под вашу архитектуру, а Linux-сообщество уже написало под ваш микропроцессор свежую версию системы с весьма нескучными обоями.
Однако, для всего этого не хватает одной мелочи: компилятора!
Да, я знаю, что многие не считают наличие компилятора чем-то важным, считая, что все должны программировать строго на ассемблере. Если вы тоже так считаете, я не буду с вами спорить, просто не читайте дальше.
Если вы хотите, чтобы для вашей оригинальной архитектуры был доступен хотя бы язык С, прошу под кат.
В статье будет рассматриваться применение инфраструктуры компиляторов LLVM для построения собственных решений на её основе.
Область применения LLVM не ограничивается разработкой компиляторов для новых процессоров, инфраструктура компиляторов LLVM также может применяться для разработки компиляторов новых языков программирования, новых алгоритмов оптимизации и специфических инструментов статического анализа программного кода (поиск ошибок, сбор статистики и т.п.).
Например, вы можете использовать какой-то стандартный процессор (например, ARM) в сочетании с специализированным сопроцессором (например, матричный FPU), в этом случае вам может понадобиться модифицировать существующий компилятор для ARM так, чтобы он мог генерировать код для вашего FPU.
Также интересным применением LLVM может быть генерация исходных текстов на языке высокого уровня («перевод» с одного языка на другой). Например, можно написать генератор кода на Verilog по исходному коду на С.



КДПВ

Читать дальше →

Как непродуманные предупреждения компиляторов помогают портить совершенно правильный код

Время на прочтение6 мин
Количество просмотров25K
Это пост о сложностях взаимодействия искусственного и естественного интеллекта. Современные компиляторы имеют довольно развитые средства статического анализа, которые умеют выдавать предупреждения на разные подозрительные конструкции в коде. В теории эти предупреждения должны помочь разработчикам делать меньше ошибок в коде.

На практике далеко не всегда предупреждения компилятора одинаково полезны. Зачастую они не помогают разработчикам, а мешают им и могут провоцировать на исправление совершенно правильного кода, т.е. на нарушение правила «работает — не трогай».
Читать дальше →

Знакомьтесь: Jack и Jill на платформе x86

Время на прочтение3 мин
Количество просмотров13K
Jack (Java Android Compiler Kit) – это компилятор, преобразующий исходный код на Java в DEX-файлы Android. Jack – это набор инструментов, среди его возможностей – переупаковка, сжатие, обфускация и поддержка множественных DEX-файлов.

В Jack используются промежуточные библиотеки в формате .jack. Преобразованием существующих .aar/.jar файлов в этот формат занимается Jill (Jack Intermediate Library Linker).



Если для сборки используется Jack, то сначала Jill конвертирует внешние библиотеки, используемые в проекте, в .jack-файлы. Это подготавливает библиотеки к быстрому слиянию с другими .jack-файлами на следующем этапе, когда Jack и плагин Android Gradle, используя подготовленные ранее.jack-файлы и исходный Java-код, компилируют DEX-файл (или файлы). В ходе этого процесса Jack может выполнить минификацию кода (сжатие, обфускацию, или и то и другое вместе). На выходе получается APK-файл Android-приложения.
Читать дальше →

Вклад авторов