Как создавать более новые версии файлов классов с помощью Scala (50.0 / 51.0)? - PullRequest
7 голосов
/ 27 февраля 2011

Я хочу протестировать новый верификатор байт-кода проверки типов с классами, созданными scalac.

scalac в настоящее время выводит файлы классов версии 49.0, но новый верификатор проверки типов является обязательным только с версии 51.0.

Я попытался «предварительно проверить» классы с помощью ProGuard (который фактическипреобразовал их в версию 50.0), но я не уверен, что новый верификатор просто вернулся к старому верификатору с выводом типа автоматически.

Как я могу преобразовать файлы классов в версию 51.0 (или как узнать,какой верификатор используется при загрузке файлов классов версии 50.0)?

Ответы [ 5 ]

2 голосов
/ 15 марта 2011

Похоже, что FJBG (библиотека, которую NSC использует для генерации байт-кода) предприняла некоторые усилия по поддержке StackMap , но я понятия не имею, как далеко она продвинулась.

Если вы спросите о scala-internals, может появиться Stephane Michelou. Это парень, который работает над этим .

1 голос
/ 10 марта 2011

Я бы использовал ASM для разбора байт-кода. Я знаю, что scala (и clojure) используют ASM для внутреннего использования, поэтому усилия, потраченные на его изучение, не будут потрачены впустую. Вы, вероятно, можете собрать вместе ClassReader и EmptyVisitor , который переопределяет метод посещения, который довольно быстро предоставляет информацию заголовка.

1 голос
/ 01 марта 2011

Я не уверен, но я думаю, что формат байт-кода никогда не менялся глубоко и, вероятно, он всегда обратно совместим.(Если вы знаете что-то о байт-коде, помните о длинных и двойных числах в константном пуле и стеке операндов, которые были спроектированы немного безумно. Разве это не было изменено?*

Как это сделать?Есть два способа:

  • Использовать редактор hexa и изменять его вручную.Это должно быть действительно просто, если вы знаете положение байтов.Там это [спецификация байт-кода] [1], которая говорит, что вы должны пропустить первые четыре байта, и вы увидите два байта младшей версии и два байта старшей версии (в этом порядке).
  • ИспользованиебиблиотекаУ меня есть некоторый опыт работы с BCEL.Это не самая лучшая библиотека, которую я когда-либо видел, но она должна быть достаточно хороша для вашего случая.Я видел методы setMinor и setMajor в классе (взгляните на ClassGen и «почти неизменный» JavaClass).

[1] http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

0 голосов
/ 11 марта 2011

Полагаю, что одним из самых простых способов было бы использовать декомпилятор Java (см. JADClipse для плагина Eclipse), а затем перекомпилировать исходный код в любую нужную версию.

0 голосов
/ 10 марта 2011

Я знаю, что это может быть очевидно, но я не уверен после прочтения вашего вопроса, поэтому я спрошу:

Используете ли вы бета-сборку? Как в одной из ночных сборок? Или вы хотите изменить текущий выпуск?

РЕДАКТИРОВАТЬ: Хорошо, есть кое-что, что я не понимаю здесь. Я только что попробовал ночные сборки и да, это версия 49.0. Но, насколько я знаю, это устанавливается компилятором.

Вы пытаетесь изменить версию, чтобы получить доступ к некоторым новым модным функциям. Но это не имеет смысла для меня. Если компилятор выпускает версию 49.0, вы меняете ее на более новую версию (50.0, 51.0 или 70.0, в зависимости от того, что имеет значение), не должно иметь никакого влияния. Насколько я знаю, версия предназначена для обеспечения совместимости, а это означает, что вы не будете запускать новый класс со старой виртуальной машиной, которая не будет поддерживать ваш язык.

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

Я имею в виду, может быть, то, что вы пытаетесь сделать, совершенно нормально, просто я не знаю об этом, и я показываю свое невежество в этой области :), но я думаю, что там чего-то не хватает.

...