Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Jasper compiler bug
#1
Недавно, я со своим хорошим другом обнаружил достаточно интересный баг в джаспере. Причем мы пришли к выводу, что это баг компилятора.

Для примера, такой код:
Код:
        List<Long> list = new ArrayList<>();
        
        for(long a : list) {
            
        }

Скомпилируется javac'ом в такой:
Код:
...
    21  invokeinterface java.util.Iterator.next() : java.lang.Object [28] [nargs: 1]
    26  checkcast java.lang.Long [34]
    29  invokevirtual java.lang.Long.longValue() : long [36]
    32  lstore_2
...

Как видно, у нас все хорошо, наш лонг сторится. Теперь же, для сравнения код джаспера:
Код:
...
   86:    invokeinterface    #117,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   91:    checkcast    #122; //class java/lang/Long
   94:    invokevirtual    #124; //Method java/lang/Long.longValue:()J
   97:    pop
...
Как видно, наш джаспер решил зачем-то вытаскивать со стека какие-то значения и вообще забил на наш лонг. При этом интересен тот факт, что на стеке может ничего не оказаться, из-за чего мы получим ошибку верификации байткода.

Теперь попробуем такой код:
Код:
        List<Long> list = new ArrayList<>();
        
        for(Long a : list) {
            
        }

Javac:
Код:
19  invokeinterface java.util.Iterator.next() : java.lang.Object [28] [nargs: 1]
    24  checkcast java.lang.Long [34]
    27  astore_2

Jasper:
Код:
86:    invokeinterface    #117,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   91:    checkcast    #122; //class java/lang/Long
   94:    pop

Опять та же песня. Что самое интересное, на второй позиции (astore_2), у нас реально ничего нет (по Jasper), видимо ребята не любят число два х)
Нам удалось добиться таки, что бы верификатор нормально отрабатывал, с помощью того, что мы кладем на стек какое-то говно. Это конечно не выход, но когда висит продакшен - очень даже Smile

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

Добавлено через 39 минут
Для примера, как джаспер откомпилил код вида for(long a : list) { System.println(a); }
Код:
91:    checkcast    #122; //class java/lang/Long
   94:    invokevirtual    #124; //Method java/lang/Long.longValue:()J
   97:    lstore    8

Тут все ок, байткод не чищенный, а вот в примерах, где переменная не используется, видимо байткод кто-то подчистил (привет анциент и ребеллион тим!).
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)