Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, ·, Вы писали: S>·>А у тайпскрипта разве есть байткод? wasm что-ли? S>Нет. Байткод нужен джавный. Просто писать компиляторщину на Java — это боль.
Scala? Cotlin? Clojure? https://github.com/caoccao/Javet/?
Здравствуйте, novitk, Вы писали: N>Scala? Cotlin? Clojure? https://github.com/caoccao/Javet/?
Clojure недостаточно типизирована. Учебный компилятор — не то место, которое хочется в шесть слоёв покрывать тестами.
На Kotlin смотрю пока. Вот, вчера поставил IntelliJ.
Есть для него библиотека PEG-парсинга?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S> N>Scala? Cotlin? Clojure? https://github.com/caoccao/Javet/?
S> Clojure недостаточно типизирована. Учебный компилятор — не то место, которое хочется в шесть слоёв покрывать тестами. S> На Kotlin смотрю пока. Вот, вчера поставил IntelliJ. S> Есть для него библиотека PEG-парсинга?
Для всяких CS-изысков обычно всё-таки Скалу юзают. Если я правильно понял, тут вроде всё что надо: https://github.com/sirthias/parboiled2
Здравствуйте, Sinclair, Вы писали:
S>Clojure недостаточно типизирована. Учебный компилятор — не то место, которое хочется в шесть слоёв покрывать тестами. S>На Kotlin смотрю пока. Вот, вчера поставил IntelliJ.
я бывший скалист, Котлином не пользовался. ИМХО Скалка самый удобный и продвинытый язык из немаргинальных. Для компилятора сам бог велел.
S>Есть для него библиотека PEG-парсинга?
Для скалки в компиляторо-писание все есть: https://github.com/lauris/awesome-scala?tab=readme-ov-file#parsing
Здравствуйте, Sinclair, Вы писали:
S>Я так понял, что штатный способ прямого порождения байткода Java — это библиотека AST. S>А есть ли аналог этой библиотеки на тайпскрипте?
Можно попробовать запустить AST в среде JS через TeaVM. Берем AST, прогоняем через TeaVM, получаем AST, которую можно запускать в среде JS. Вроде бы то, что хочется получить.
Здравствуйте, Sinclair, Вы писали:
S>Задача — сделать компилятор воображаемого языка. S>В JVM — потому, что это проще, чем в натив (и даже в LLVM). S>В принципе, можно и Java-код порождать, но это не даст студентам понимания устройства байт-кода
А зачем какие то библиотеки? Почему нельзя тупо писать байтики напрямую? Одно дело когда ты байткод сам анализируешь, тут библиотека поможет и снимет куча геморроя. Но если задача байткод генерить, да еще в учебных целях — ИМХО лучше тупо в файлик сразу байты писать да и все. Если не ставится задача вообще все покрыть, а чтоб было покрытие ограниченного подмножества — достаточно просто быстро и интересно делается.
Здравствуйте, elmal, Вы писали:
E>Здравствуйте, Sinclair, Вы писали:
S>>Задача — сделать компилятор воображаемого языка. S>>В JVM — потому, что это проще, чем в натив (и даже в LLVM). S>>В принципе, можно и Java-код порождать, но это не даст студентам понимания устройства байт-кода E>А зачем какие то библиотеки? Почему нельзя тупо писать байтики напрямую? Одно дело когда ты байткод сам анализируешь, тут библиотека поможет и снимет куча геморроя. Но если задача байткод генерить, да еще в учебных целях — ИМХО лучше тупо в файлик сразу байты писать да и все. Если не ставится задача вообще все покрыть, а чтоб было покрытие ограниченного подмножества — достаточно просто быстро и интересно делается.
Чтобы генерить байтики, нужно знать, какие байтики генерить.
Я не очень разбираюсь в JVM-ном байткоде, но из опыта дотнетного байткода уже понятно, что
а) мнемоники команд. Банальная штука типа "положи в стек целую константу" требует енкодинга команды и енкодинга константы. Делать это каждый раз руками? Код становится невозможно даже прочитать, не то что поддерживать. Интуитивно хочется иметь готовую функцию типа EmitLoadConstant(x byteCodeStream, int value) или byteCodeStream.EmitLoadConstant(value).
б) goto. Не хочется вручную вычислять байтовые смещения с риском промахнуться. Удобнее иметь функции вида MarkLabel() c возможностью использовать результат этой функции в эмите jump-инструкций
в) метаданные. Банальный Call использует в аргументах method token, который весьма нетривиально устроен. Вычислять его вручную — крайне громоздко.
г) предсказание будущего. Каждый метод указывает в заголовке размер байт-кода, количество переменных, а также максимальную глубину стека. При кодогенерации это довольно-таки тяжело оценить заранее — так что либо делать два прохода по внутреннему представлению, либо, всё-таки, инкапсулировать это всё в некий класс, отвечающий за порождение байтиков, который всё это рассчитает самостоятельно с гарантиями корректности и без замусоривания пользовательского кода.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>а) мнемоники команд. Банальная штука типа "положи в стек целую константу" требует енкодинга команды и енкодинга константы. Делать это каждый раз руками? Код становится невозможно даже прочитать, не то что поддерживать. Интуитивно хочется иметь готовую функцию типа EmitLoadConstant(x byteCodeStream, int value) или byteCodeStream.EmitLoadConstant(value).
А что, сейчас такую вещь как словари, студенты не знают? Причем не знают в джаваскрипте, где это основная структура данных? Я вот считаю, что прежде чем рассказывать студентам как компилятор работает, нужно их с базовыми структурами данных познакомить и приучить их использовать. А так да, я в курсе что сейчас и выпускают специалистов без этого знания.
Относительно готовых функция и того, как ты считаешь они должны выглядеть. То, что ты привел — это нарушение Single Responsibility Principle в чистом виде. Я бы делал проще, функция encode, на вход енам команды и опциональные параметры (если язык понавороченнее, то можно и поинтереснее фичи использовать вроде Sealed Class и тому подобному), на выходе массив байт. Внутри логика преобразования, причем весьма тривиальная. И отдельно уже идет запись в стрим или еще куда, уже стандартными средствами. Базовый принцип — нельзя смешивать логику и ввод вывод, это всегда должно быть отделено. В идеале сначала ввод без логики, затем операции, затем вывод без логики, тривиальный — если так делать, то код прекрасно становится читаемый и поддерживаемый.
Кстати рекомендую прочитать: https://habr.com/ru/companies/jugru/articles/858418/
Принцип блин в 1977 сформулирован!
S>б) goto. Не хочется вручную вычислять байтовые смещения с риском промахнуться. Удобнее иметь функции вида MarkLabel() c возможностью использовать результат этой функции в эмите jump-инструкций
Тоже самое, эту функцию написать самому тривиально, там кода 3 строчки. Если студент не в состоянии это написать сам — рано ему компиляторами заниматься.
S>г) предсказание будущего. Каждый метод указывает в заголовке размер байт-кода, количество переменных, а также максимальную глубину стека. При кодогенерации это довольно-таки тяжело оценить заранее — так что либо делать два прохода по внутреннему представлению, либо, всё-таки, инкапсулировать это всё в некий класс, отвечающий за порождение байтиков, который всё это рассчитает самостоятельно с гарантиями корректности и без замусоривания пользовательского кода.
Да, нужно инкапсулировать. И там не будет ничего сложного и громоздкого. Можно через ленивые вычисления и все такое, совершенно не обязательно в несколько проходов. А на деле — а хоть бы и в несколько проходов, что тут такого? Ну медленнее, но зато код будет вообще шикарный и простой, прекрасно тестируемый. Хоть 10 проходов, лишь бы почище сам код был.
Вот студенты и должны научиться это делать. Написать компилятор учебный — это именно требуется разобраться как подобные вещи делаются с нуля. Без библиотек кодогенерации, только через стандартные структуры данных, средства языка и все такое. Для начала следует сделать интерпретатор, крайне б желательно было осилить книжку SICP, чтоб мозги на место поставить, и там собственно пример как делается интерпретатор вполне есть. Изменений как из интерпретатора сделать компилятор, кстати, будет вообще минимум! Тупо бежишь по AST, но не непосредственно выполняешь, а делаешь кодогенерарацию.
Если же пользоваться готовыми библиотеками — ни хрена студенты не поймут! И придется еще тратить время на то, чтоб с библиотекой разобраться. И далеко не факт что API библиотеки будет сделано достаточно хорошо. В результате что был курс, что его не было — в памяти не останется вообще ни черта! Особенно если упор делать не на реализацию и программу, а на отчет и его защиту с презентациями, как у нас тут некоторые делают, да еще и ЕСПД привлекают начиная с первого курса для даже лабораторных.
На деле — прекрасная учебная задача, на которой студенты могут набить руку и попробовать не городить спагетти говнокод, а написать прекрасный компактный и поддерживаемый код, пусть и не идеально шустрый, однопроходный и все такое. Однопроходный тоже кстати можно написать достаточно компактно и поддерживаемо, но напрягаться умственно придется сложнее, все эти ленивости и все такое, контекст держать — если нет цели сделать максимально шустро, лучше сделать просто максимально понятно. Нужно именно приучить студентов не говнокодить копипастить, а бороться со сложностью и запутанностью, походя самим писать вспомогательные функции для удобства на скорость, причем чтоб тратить на это меньше времени, чем если говнокодить все в лоб! А то ведь большинство такому не научится даже на работе реальной, тупо никто не покажет как можно, так и будут блин ждать пока добрый буржуй напишет удобную функцию, а если функции нет, так и будут копипастить блин один и тот же код и даже мысли блин не возникнет написать так, как удобно. Собственно большинство библиотек тоже ни фига не удобны в использовании.
А вообще, я блин в шоке насколько мало программистов с профильным блин образованием в курсе как работают интерпретаторы, компиляторы и т.д. Не на детальном уровне, а на базовом и общем!!!! Мне в обычной работе, если что, неоднократно приходилось это писать. Чаще всего интерпретаторы, именно компилятор не было смысла, но кодогенератор тоже приходилось писать далеко не один раз, и напишу еще не раз. Вроде не совсем ненужный навык.
PS Хотел еще ссылку на охрененный курс по компиляторам на ютубе привести, но блин не могу найти. Даже университет не помню какой, толь MIT, толь Беркли. Там несколько, более ранний был довольно стандартный, профессора звали что то вроде Кубианович, начинается точно на Куби, а вот более поздний там преподавали поинтереснее и был фокус на написании DSL и еще там в названии было Hack Your Language. Очень мне б блин самому не помешало пересмотреть, а то как понадобилось однопроходный парсер с приоритетами операций писать — я блин нормально хрен написал, тупо забыл как это все элегантно делается.
Здравствуйте, elmal, Вы писали:
E>А что, сейчас такую вещь как словари, студенты не знают? Причем не знают в джаваскрипте, где это основная структура данных? Я вот считаю, что прежде чем рассказывать студентам как компилятор работает, нужно их с базовыми структурами данных познакомить и приучить их использовать. А так да, я в курсе что сейчас и выпускают специалистов без этого знания.
Непонятно, при чём тут словари.
E>Относительно готовых функция и того, как ты считаешь они должны выглядеть. То, что ты привел — это нарушение Single Responsibility Principle в чистом виде.
С чего бы это вдруг? E>Я бы делал проще, функция encode, на вход енам команды и опциональные параметры (если язык понавороченнее, то можно и поинтереснее фичи использовать вроде Sealed Class и тому подобному), на выходе массив байт.
В принципе, можно и так. Хотя не очень понятно, как будет выглядеть сигнатура этой функции. И как потом этой функцией пользоваться. E>Внутри логика преобразования, причем весьма тривиальная. И отдельно уже идет запись в стрим или еще куда, уже стандартными средствами.
Вы так говорите, как будто я предлагал что-то другое. E>Базовый принцип — нельзя смешивать логику и ввод вывод, это всегда должно быть отделено. В идеале сначала ввод без логики, затем операции, затем вывод без логики, тривиальный — если так делать, то код прекрасно становится читаемый и поддерживаемый.
E>Кстати рекомендую прочитать: E>https://habr.com/ru/companies/jugru/articles/858418/ E>Принцип блин в 1977 сформулирован!
Спасибо за ссылку на общеизвестное.
По-прежнему непонятно, как то, что вы предлагаете, противоречит идее библиотеки.
E>Да, нужно инкапсулировать. И там не будет ничего сложного и громоздкого. Можно через ленивые вычисления и все такое, совершенно не обязательно в несколько проходов. А на деле — а хоть бы и в несколько проходов, что тут такого? Ну медленнее, но зато код будет вообще шикарный и простой, прекрасно тестируемый. Хоть 10 проходов, лишь бы почище сам код был. E>Вот студенты и должны научиться это делать. Написать компилятор учебный — это именно требуется разобраться как подобные вещи делаются с нуля. Без библиотек кодогенерации, только через стандартные структуры данных, средства языка и все такое. Для начала следует сделать интерпретатор, крайне б желательно было осилить книжку SICP, чтоб мозги на место поставить, и там собственно пример как делается интерпретатор вполне есть. Изменений как из интерпретатора сделать компилятор, кстати, будет вообще минимум! Тупо бежишь по AST, но не непосредственно выполняешь, а делаешь кодогенерарацию.
В итоге 3/4 курса студенты будут заниматься нудным выпиливанием лобзиком по вазелину, и только 1/4 — собственно компиляцией.
E>Если же пользоваться готовыми библиотеками — ни хрена студенты не поймут! И придется еще тратить время на то, чтоб с библиотекой разобраться. И далеко не факт что API библиотеки будет сделано достаточно хорошо. В результате что был курс, что его не было — в памяти не останется вообще ни черта! Особенно если упор делать не на реализацию и программу, а на отчет и его защиту с презентациями, как у нас тут некоторые делают, да еще и ЕСПД привлекают начиная с первого курса для даже лабораторных.
Если бы у нас было всё время мира — да, можно всё пилить с нуля. Но у нас — 1 семестр, и это не единственный предмет в семестре. Положа руку на сердце: вы напишете с нуля компилятор небольшого языка с кодогенерацией и статической верификацией корректности за 32 часа?
E>А вообще, я блин в шоке насколько мало программистов с профильным блин образованием в курсе как работают интерпретаторы, компиляторы и т.д. Не на детальном уровне, а на базовом и общем!!!! Мне в обычной работе, если что, неоднократно приходилось это писать. Чаще всего интерпретаторы, именно компилятор не было смысла, но кодогенератор тоже приходилось писать далеко не один раз, и напишу еще не раз. Вроде не совсем ненужный навык.
Ну, вот мы их и обучаем. Причём в реальном производстве никогда они не будут с нуля ни токенайзер, ни парсер, ни кодогенератор писать. Бессмысленная затея. Значит, и навыки им нужны больше похожие на то, что в жизни понадобится.
E>PS Хотел еще ссылку на охрененный курс по компиляторам на ютубе привести, но блин не могу найти. Даже университет не помню какой, толь MIT, толь Беркли. Там несколько, более ранний был довольно стандартный, профессора звали что то вроде Кубианович, начинается точно на Куби, а вот более поздний там преподавали поинтереснее и был фокус на написании DSL и еще там в названии было Hack Your Language. Очень мне б блин самому не помешало пересмотреть, а то как понадобилось однопроходный парсер с приоритетами операций писать — я блин нормально хрен написал, тупо забыл как это все элегантно делается.
Вот у нас студенты как раз учатся делать это элегантно — на PEG-грамматиках.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Непонятно, при чём тут словари.
Для сопоставления инструкции на ее код и тому подобное. Я не очень понимаю смысл жестко хардкодить кучу методов вроде writeLoadInstructionToStream и т.д. Но это ладно, вкусовщина.
S>В итоге 3/4 курса студенты будут заниматься нудным выпиливанием лобзиком по вазелину, и только 1/4 — собственно компиляцией.
Да не будет там выпиливания лобзиком по вазелину.
S>Если бы у нас было всё время мира — да, можно всё пилить с нуля. Но у нас — 1 семестр, и это не единственный предмет в семестре. Положа руку на сердце: вы напишете с нуля компилятор небольшого языка с кодогенерацией и статической верификацией корректности за 32 часа?
Да, напишу. Правда без статической верификации корректности, этим никогда не занимался. Мне когда на практике такие задачи попадаются, естественно никто время на это не выделяет и не ставит задачу написания DSL. Но приходилось этим заниматься в трех разных конторах, навык оказался полезным.
S>Ну, вот мы их и обучаем. Причём в реальном производстве никогда они не будут с нуля ни токенайзер, ни парсер, ни кодогенератор писать. Бессмысленная затея. Значит, и навыки им нужны больше похожие на то, что в жизни понадобится.
Что интересно — мне это реально понадобилось в реальном проекте, и я писал и токенайзер (примитивный, тупо сплитом строки по регэкспу), и парсер, и кодогенератор. Причем на время и именно что с нуля. Язык, который пришлось парсить — 1С, естественно очень ограниченное подмножество . Некоторые таланты блин в базу зафигачили 1С выражение как строку. Тупо логическое выражение с приоритетом, но там тысячи переменных со скобками и сотни функций, и вот мне требовалось повторить логику, но в более чем тысячу раз быстрее, ибо если реюзать функцию на 1С оригинальную, расчет займет много лет при полной загрузке всех серверов . Как пример просто. Так еще доводилось DSL писать уже на текущем языке, чтоб можно было описывать уравнения на миллионы переменных в виде близкой к математической записи и затем из этого интерпретировать в различные решатели систем уравнений. Проект правда через года 3 всеж помер, из за смены языка программирования на питон, но тем не менее какое то время доводилось писать и классический интерпретатор, хоть и без токенайзера и парсера, ибо DSL была на том же языке сделана, тупо переопределены операторы были и был набор классов определенных и функций их конструирования, далее тупо обход AST и интерпретация, причем еще и с оптимизациями некоторыми. Написать компилятор тоже не составило б труда, но не было необходимости.
Навык написания как минимум интерпретаторов и кодогенератора, наколенный — позволяет сэкономить кучу времени, и если задачи типовые — реюзать и ОЧЕНЬ быстро реагировать на изменения требований. Тупо добавить потом пару строчек, нажать билд и деплой — и все. А не хреначить один и тот же копипастный код из проекта в проект.
S>Вот у нас студенты как раз учатся делать это элегантно — на PEG-грамматиках.
Нашел этот курс охрененный! Блин, его с ютуба удалили, потому и потерял. На всякий случай еще и сюда — http://www.infocobuild.com/education/audio-video-courses/computer-science/CS164-Spring2012-Berkeley/lecture-01.html. Ключевые слова CS 164 Ras Bodik Spring 2012. Здесь именно упор на написание DSL, кажется всеж этот, надо будет пересмотреть, а то я забыл все нафик. Или посмотреть что поновее было б неплохо, но именно от этого курса я был в свое время в восторге и этот курс много заставил переосмыслить. Надо б блин сохранить как нибудь, а то ведь удалят нафик снова ...
Здравствуйте, elmal, Вы писали: S>>Непонятно, при чём тут словари. E>Для сопоставления инструкции на ее код и тому подобное. Я не очень понимаю смысл жестко хардкодить кучу методов вроде writeLoadInstructionToStream и т.д. Но это ладно, вкусовщина.
В байткоде инструкция и есть код. Я не понимаю, что вы предлагаете — возможно, потому, что вы пишете словами, а не кодом. Какими типами будет параметризован ваш словарь?
E>Да не будет там выпиливания лобзиком по вазелину.
Только оно и будет. Рукопашное порождение каждого байта — это вот оно и есть. E>Да, напишу. Правда без статической верификации корректности, этим никогда не занимался.
Ну вот это, конечно, не суперсложная задача, но время на неё тоже надо. E>Мне когда на практике такие задачи попадаются, естественно никто время на это не выделяет и не ставит задачу написания DSL. Но приходилось этим заниматься в трех разных конторах, навык оказался полезным.
Ну, может быть вы и напишете. Я может быть тоже напишу — но у меня за плечами не один год опыта. А у студентов что? Им только что отчитали курс дискретки с конечными автоматами; а сейчас быстро-быстро запихивают формальные грамматики вместе с тройками Хоара и алгоритмами прямого и обратного прослеживания. E>Что интересно — мне это реально понадобилось в реальном проекте, и я писал и токенайзер (примитивный, тупо сплитом строки по регэкспу), и парсер, и кодогенератор. Причем на время и именно что с нуля.
Непонятно, зачем вы этим занимались. В такой задаче можно сэкономить примерно три четверти усилий, если взять готовую реализацию парсера на том же PEG.
Язык, который пришлось парсить — 1С, естественно очень ограниченное подмножество . Некоторые таланты блин в базу зафигачили 1С выражение как строку. Тупо логическое выражение с приоритетом, но там тысячи переменных со скобками и сотни функций
Вот примерно всё, что вы рассказываете — это лабораторная номер 7 (из 15), она же вторая в серии "про грамматики". Предыдущие работы — чисто на освоение языка программирования и его стандартной библиотеки; они не понадобятся, если брать менее экзотический язык.
E>Навык написания как минимум интерпретаторов и кодогенератора, наколенный — позволяет сэкономить кучу времени, и если задачи типовые — реюзать и ОЧЕНЬ быстро реагировать на изменения требований. Тупо добавить потом пару строчек, нажать билд и деплой — и все. А не хреначить один и тот же копипастный код из проекта в проект.\
Ну так вы и предлагаете хреначить копипастный код, вместо того, чтобы взять готовую реализацию и поехать
E>Нашел этот курс охрененный! Блин, его с ютуба удалили, потому и потерял. На всякий случай еще и сюда — http://www.infocobuild.com/education/audio-video-courses/computer-science/CS164-Spring2012-Berkeley/lecture-01.html. Ключевые слова CS 164 Ras Bodik Spring 2012.
Посмотрим, спасибо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>·>А, понял вопрос. Да, сабж, очень сильно. А задача то какая? Зачем генерить именно байт-код? Может джаву лучше? Ещё кстати scala или kotlin если языка не хватает. S>Задача — сделать компилятор воображаемого языка. S>В JVM — потому, что это проще, чем в натив (и даже в LLVM). S>В принципе, можно и Java-код порождать, но это не даст студентам понимания устройства байт-кода S>Вот, кстати, смотрю в сторону kotlin. Похоже, на нём тоже неплохо пишется компилятор. Но для него, я так понял, в качестве IDE можно использовать только IntelliJ, т.к. интеграция с VS Code у него так себе.
Я бы посоветовал генерировать байткод wasm.
Во-первых он реально очень простой, гораздо проще байткода JVM.
Во-вторых в нём будто всё сделано для того, чтобы его было просто генерировать.
В-третьих у него есть шикарный официальный лиспо-подобный синтаксис, который ещё проще генерировать, а уж из него в байты переконвертировать код есть.
JVM байткод не такой уж простой и там хватает нюансов...
Что такое библиотека AST я не знаю, никогда не слышал. Есть библиотека ASM. Это не официальный, но самый популярный способ генерировать байткод. Но там всё достаточно низкоуровневое, никакого компилятора в ней нет. Да и API у неё специфическое... https://www.baeldung.com/java-asm тут можно ознакомиться немного.
Здравствуйте, vsb, Вы писали: S>>Задача — сделать компилятор воображаемого языка. S>>В JVM — потому, что это проще, чем в натив (и даже в LLVM). S>>В принципе, можно и Java-код порождать, но это не даст студентам понимания устройства байт-кода S>>Вот, кстати, смотрю в сторону kotlin. Похоже, на нём тоже неплохо пишется компилятор. Но для него, я так понял, в качестве IDE можно использовать только IntelliJ, т.к. интеграция с VS Code у него так себе. vsb>Я бы посоветовал генерировать байткод wasm. vsb>Во-первых он реально очень простой, гораздо проще байткода JVM.
А вот это интересная идея. vsb>Во-вторых в нём будто всё сделано для того, чтобы его было просто генерировать.
Посмотим. vsb>В-третьих у него есть шикарный официальный лиспо-подобный синтаксис, который ещё проще генерировать, а уж из него в байты переконвертировать код есть. vsb>JVM байткод не такой уж простой и там хватает нюансов...
Отож. vsb>Что такое библиотека AST я не знаю, никогда не слышал. Есть библиотека ASM. Это не официальный, но самый популярный способ генерировать байткод. Но там всё достаточно низкоуровневое, никакого компилятора в ней нет. Да и API у неё специфическое... https://www.baeldung.com/java-asm тут можно ознакомиться немного.
Да, я как раз про неё — опечатался в названии.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.