Как статически анализировать ссылочные типы, передаваемые каждой инструкции байт-кода? - PullRequest
14 голосов
/ 04 июня 2011

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

Анализируя байт-код Java, какой самый простой способ найти все возможные ссылочные типы, заданные в качестве параметров для данной инструкции байт-кода Java?Меня интересует тип ссылки, то есть, что заданная инструкция putfield получит Integer или что она может получить Integer или Float и т. Д.

Например, рассмотрим этот блок кода:

   0:   aload_1
   1:   invokestatic    #21; //Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
   4:   astore_2
   5:   aload_2
   6:   ifnull  17
   9:   aload_0
   10:  aload_2
   11:  putfield    #27; //Field value:Ljava/lang/Number;
   14:  goto    25
   17:  aload_0
   18:  iconst_0
   19:  invokestatic    #29; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   22:  putfield    #27; //Field value:Ljava/lang/Number;
   25:  return

Мы можем сделать вывод, что инструкция putfield на ПК 11 получит тип ссылки Integer .

0: aload pushes ref type of String (the method param)
1: invokestatic pops the ref type and pushes a ref type of Integer (invoked method return type)
4: astore pops the ref type of Integer and stores it in local variable 2
5: aload pushes the ref type of Integer from local variable 2
6: ifnull pops the ref type of Integer and conditionally jumps to pc 17
9: aload pushes "this"
10: aload pushes the ref type of Integer
11: putfield: we know we have a ref type of Integer that the instruction will put in field

Выполните любой из байт-кода / кодабиблиотеки анализа делают это для меня, или я должен написать это сам? ASM проект имеет Analyzer , который, кажется, может выполнять часть работы для меня, но на самом деле этого недостаточно, чтобы оправдать переход на его использование.

EDIT: Я сделал домашнее задание и изучил Java VM Spec .

Ответы [ 3 ]

3 голосов
/ 05 июня 2011

Метод Analyzer.analyze(...), кажется, делает именно то, что вам нужно, и если нет, у вас есть возможность взломать его. Это было бы лучше, чем начинать заново.

Другой идеей было бы посмотреть, сможете ли вы найти верификатор байт-кода, который реализован в Java. Верификатор должен использовать анализ потока данных, чтобы гарантировать, что методы не будут вызваны с неверным типом параметров.

2 голосов
/ 04 июля 2011

Я обнаружил, что нужно сделать почти то же самое в моем проекте. Возможно, вы захотите взглянуть на исходный код здесь (в методе visitEnd()). Он использует Analyzer из проекта ASM, чтобы сделать «снимок» стекового кадра во время инструкции PUTFIELD. Эти моментальные снимки затем сохраняются и могут быть извлечены после того, как посетитель закончил, часть информации, содержащейся в моментальном снимке, представляет собой тип ссылки в верхней части стека.

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

1 голос
/ 06 июня 2011

Мы можем сделать вывод, что инструкция putfield на ПК 11 получит тип ссылки Integer.

Вам не нужно выводить это, это часть определения putfield.

Перед написанием приложения вам следует потратить некоторое время на чтение VM Spec . В разделе 6 будет указано поведение всех операций с байт-кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...