Создайте новый объект с помощью ASM

Я пытался использовать структуру ASM для внедрения байт-кода в интересующее меня место, и до сих пор мне это удавалось. В настоящее время я пытаюсь внедрить код, который в основном создает новый экземпляр/объект класса, и, немного прочитав, я обнаружил, что это может быть достигнуто с помощью INVOKESPECIAL (надеюсь, я правильно понял INVOKESPECIAL «INVOKESPECIAL для частных методов и конструкторов»).

Ниже приведен фрагмент кода, который я использовал для создания экземпляра

visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(_type);
visitor.visitVarInsn(ALOAD, metanamevarindex);

eventObject = newLocal(Type.getType("com/vish/RequestTrackerEvent"));

visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/vish/RequestTrackerEvent", "<init>",
                            "(JJLjava/lang/String;Ljava/lang/String;)V");

visitor.visitVarInsn(ASTORE, eventObject);

Конструктор класса принимает 4 аргумента (long, long, String, String). Но всякий раз, когда я это делаю, я получаю исключение, как показано ниже.

java.lang.VerifyError: JVMVRFY036 stack underflow;
    at java.lang.J9VMInternals.verifyImpl(Native Method)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:72)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:70)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:134)

Может ли кто-нибудь помочь мне понять, правильно ли мое использование/понимание INVOKESPECIAL, если правильно, то где я делаю неправильно?

Спасибо


person VishwanathB    schedule 05.09.2013    source источник


Ответы (2)


Ответ на вопрос типа "как сгенерировать {некоторый код Java} с помощью ASM" был дан в FAQ по ASM. :

Если вы хотите знать, как сгенерировать синхронизированный блок, блок try-catch, оператор finally или любую другую конструкцию Java, напишите код Java, который вы хотите сгенерировать, во временном классе, скомпилируйте его с помощью javac, а затем используйте ASMifier. чтобы получить код ASM, который сгенерирует этот класс (см. "10. Как получить байт-код существующего класса?").

Вы можете пойти еще дальше, сравнив выходные данные ASMifier до и после преобразования, как описано в этой статье< /а>.

person Eugene Kuleshov    schedule 05.09.2013
comment
Спасибо, Евгений, эти ссылки были действительно полезны. Кроме того, в javadocs для OPCODES ClassVisitor и MethodVisitor нет описания того, что делает каждый метод, или указано, что делают разные OPCODES... Есть ли ссылка или документация, где я могу получить более подробную информацию об ASM? API?? - person VishwanathB; 06.09.2013
comment
Это был бы другой вопрос с отдельным ответом... :) - person Eugene Kuleshov; 06.09.2013
comment
Спасибо Евгений откроет еще один вопрос: P - person VishwanathB; 10.09.2013

Я точно не помню, что делает newLocal(), но я знаю, что метод не вставляет в байт-код инструкцию NEW. Он просто резервирует место в некоторых внутренних механизмах обработки локальных переменных ASM.

Попробуйте вместо этого использовать что-то вроде

visitor.visitTypeInst(Opcodes.NEW, "com/vish/RequestTrackerEvent");

Удачи

person ruediste    schedule 05.09.2013
comment
Спасибо, ruediste, я новичок в манипулировании ASM и ByteCode, я попробую то, что вы предложили. - person VishwanathB; 05.09.2013
comment
Я прочитал статью, написанную Евгением Кулешовым, и в ней говорилось об этом примечании, что это преобразование нельзя использовать для перехвата конструкции класса (новое в языке Java). В байт-коде объектная конструкция представлена ​​двумя отдельными инструкциями, которые могут быть далеко друг от друга в потоке событий. Первый — это НОВЫЙ код операции, который создает неинициализированный экземпляр объекта указанного типа. Прежде чем этот экземпляр можно будет использовать, необходимо вызвать метод ‹init› этого экземпляра с использованием кода операции INVOKESPECIAL. Я использовал ваше предложение вместе с INVOKESPECIAL, после чего я смог создать новый экземпляр с аргументами. - person VishwanathB; 05.09.2013
comment
Спасибо большое за вашу помощь - person VishwanathB; 05.09.2013