joker 2016 - bytecode 101

121
Байткод для любознательных @antonarhipov Joker 2016, СПб

Upload: anton-arhipov

Post on 16-Jan-2017

134 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Joker 2016 - Bytecode 101

Байткод для любознательных

@antonarhipovJoker 2016, СПб

Page 2: Joker 2016 - Bytecode 101

@antonarhipov

Антон Архипов

Page 3: Joker 2016 - Bytecode 101

Зачем?

Page 4: Joker 2016 - Bytecode 101

Зачем?

• Знай свою платформу!

Page 5: Joker 2016 - Bytecode 101

Зачем?

• Знай свою платформу!

• Хотите написать свой компилятор?

Page 6: Joker 2016 - Bytecode 101

Зачем?

• Знай свою платформу!

• Хотите написать свой компилятор?

• Фреймворки (AOP, ORM)

Page 7: Joker 2016 - Bytecode 101

Зачем?

• Знай свою платформу!

• Хотите написать свой компилятор?

• Фреймворки (AOP, ORM)

• Всевозможные инструменты (см. JRebel)

Page 8: Joker 2016 - Bytecode 101

Зачем?

• Знай свою платформу!

• Хотите написать свой компилятор?

• Фреймворки (AOP, ORM)

• Всевозможные инструменты (см. JRebel)

• … ну или может просто скучно?

Page 9: Joker 2016 - Bytecode 101

Основы Java-байткода

Инструментарий

ObjectWeb ASM

Page 10: Joker 2016 - Bytecode 101

1 + 2

Page 11: Joker 2016 - Bytecode 101

1 + 2

1 2 +

Page 12: Joker 2016 - Bytecode 101

1 + 2

1 2 +

Page 13: Joker 2016 - Bytecode 101

1 + 2

1 2 + PUSH 1 1

Page 14: Joker 2016 - Bytecode 101

1 + 2

1 2 + PUSH 1 PUSH 2 2

1

Page 15: Joker 2016 - Bytecode 101

1 + 2

1 2 + PUSH 1 PUSH 2 ADD

3

Page 16: Joker 2016 - Bytecode 101

1 + 2

1 2 + ICONST_1 ICONST_2 IADD

3

Page 17: Joker 2016 - Bytecode 101

? = 1 + 2

Page 18: Joker 2016 - Bytecode 101

Таксономия

Page 19: Joker 2016 - Bytecode 101

Работа со стеком

Таксономия

Page 20: Joker 2016 - Bytecode 101

Работа со стеком

Инструкции управления

Таксономия

Page 21: Joker 2016 - Bytecode 101

Работа со стеком

Инструкции управления

Работа с объектами

Таксономия

Page 22: Joker 2016 - Bytecode 101

Работа со стеком

Инструкции управления

Арифметика Работа с объектами

Таксономия

Page 23: Joker 2016 - Bytecode 101

Работа со стеком

Инструкции управления

Арифметика Работа с объектами

monitorenter monitorexit

Таксономия

Page 24: Joker 2016 - Bytecode 101

Байт-код

Page 25: Joker 2016 - Bytecode 101

Байт-код

• Одно-байтные инструкции

Page 26: Joker 2016 - Bytecode 101

Байт-код

• Одно-байтные инструкции

• 256 возможных вариантов

Page 27: Joker 2016 - Bytecode 101

Байт-код

• Одно-байтные инструкции

• 256 возможных вариантов

• Используется 200+

Page 28: Joker 2016 - Bytecode 101

Байт-код

• Одно-байтные инструкции

• 256 возможных вариантов

• Используется 200+

• Google: “Java bytecode instructions listings”

Page 29: Joker 2016 - Bytecode 101

Байт-код

• Одно-байтные инструкции

• 256 возможных вариантов

• Используется 200+

• Google: “Java bytecode instructions listings”

• https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

Page 30: Joker 2016 - Bytecode 101

ОПЕРАЦИЯТИП

Page 31: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a

ОПЕРАЦИЯТИП

Page 32: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)

ОПЕРАЦИЯТИП

Page 33: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)• Локальные переменные и стек (load/store)

ОПЕРАЦИЯТИП

Page 34: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)• Локальные переменные и стек (load/store)• Операции с массивами (aaload, aastore)

ОПЕРАЦИЯТИП

Page 35: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)• Локальные переменные и стек (load/store)• Операции с массивами (aaload, aastore)• Арифметика (add, sub, mul, div)

ОПЕРАЦИЯТИП

Page 36: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)• Локальные переменные и стек (load/store)• Операции с массивами (aaload, aastore)• Арифметика (add, sub, mul, div)• Булевые/битовые операции (iand, ixor)

ОПЕРАЦИЯТИП

Page 37: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)• Локальные переменные и стек (load/store)• Операции с массивами (aaload, aastore)• Арифметика (add, sub, mul, div)• Булевые/битовые операции (iand, ixor)• Сравнения (cmpg, cmpl, ifne, ifeq)

ОПЕРАЦИЯТИП

Page 38: Joker 2016 - Bytecode 101

• <тип> ::= b, s, c, i, l, f, d, a• Константы (ldc, iconst_1)• Локальные переменные и стек (load/store)• Операции с массивами (aaload, aastore)• Арифметика (add, sub, mul, div)• Булевые/битовые операции (iand, ixor)• Сравнения (cmpg, cmpl, ifne, ifeq)• Преобразования (l2d, i2l)

ОПЕРАЦИЯТИП

Page 39: Joker 2016 - Bytecode 101
Page 40: Joker 2016 - Bytecode 101

JVM процесс

Page 41: Joker 2016 - Bytecode 101

Thread 1

Thread 2

Thread 3

Thread 4

Page 42: Joker 2016 - Bytecode 101
Page 43: Joker 2016 - Bytecode 101

• JVM работает со стеком

• У каждого потока есть стек

• Стек сохраняет “фреймы”

• Новый “фрейм” создаётся при вызове метода

• “Фрейм” состоит из:

– Стек операций

– Массив локальных переменных

Стековая машина

Page 44: Joker 2016 - Bytecode 101

Стек операций

Локальные переменные

20 1 N…

Константы#1

Page 45: Joker 2016 - Bytecode 101

Работа со стеком и локальными переменными

Page 46: Joker 2016 - Bytecode 101

AB

dup pop swap dup_x1 dup2_x1

Page 47: Joker 2016 - Bytecode 101

A

B

dup pop swap dup_x1 dup2_x1

A

Page 48: Joker 2016 - Bytecode 101

dup pop swap dup_x1 dup2_x1

AB

Page 49: Joker 2016 - Bytecode 101

dup pop swap dup_x1 dup2_x1

AB

Page 50: Joker 2016 - Bytecode 101

dup pop swap dup_x1 dup2_x1

AB

B

Page 51: Joker 2016 - Bytecode 101

dup pop swap dup_x1 dup2_x1

AB

BBA

Page 52: Joker 2016 - Bytecode 101

ldc "Hello" astore_0 iconst_1 astore_1 aload_0

глубина значение

Стекпеременная значение

Локальные переменные

0

1

2

3

4

0

1

2

3

4

Page 53: Joker 2016 - Bytecode 101

ldc "Hello" astore_0 iconst_1 astore_1 aload_0

"Hello"0

1

2

3

4

0

1

2

3

4

глубина значениепеременная значение

СтекЛокальные переменные

Page 54: Joker 2016 - Bytecode 101

ldc "Hello" astore_0 iconst_1 astore_1 aload_0

"Hello"0

1

2

3

4

0

1

2

3

4

глубина значениепеременная значение

СтекЛокальные переменные

Page 55: Joker 2016 - Bytecode 101

ldc "Hello" astore_0 iconst_1 astore_1 aload_0

"Hello"0

1

2

3

4

0

1

2

3

4

1

глубина значениепеременная значение

СтекЛокальные переменные

Page 56: Joker 2016 - Bytecode 101

ldc "Hello" astore_0 iconst_1 astore_1 aload_0

"Hello"0

1

2

3

4

0

1

2

3

4

1

глубина значениепеременная значение

СтекЛокальные переменные

Page 57: Joker 2016 - Bytecode 101

ldc "Hello" astore_0 iconst_1 astore_1 aload_0

"Hello"0

1

2

3

4

0

1

2

3

4

1

"Hello"

глубина значениепеременная значение

СтекЛокальные переменные

Page 58: Joker 2016 - Bytecode 101

СтекТаблица

локальных переменных

store

load

Page 59: Joker 2016 - Bytecode 101

Вызовы методов

Page 60: Joker 2016 - Bytecode 101

invokeXXX

• invokestatic • invokespecial

• invokevirtual • invokeinterface • invokedynamic

Page 61: Joker 2016 - Bytecode 101

invokestatic

• invokestatic • invokespecial

• invokevirtual • invokeinterface • invokedynamic

Integer.valueOf(“42”)

Page 62: Joker 2016 - Bytecode 101

invokespecial

• invokestatic • invokespecial

• invokevirtual • invokeinterface • invokedynamic

<init>

private void foo();

super.method();

Page 63: Joker 2016 - Bytecode 101

• invokestatic • invokespecial

• invokevirtual • invokeinterface • invokedynamic

invokevirtual

class A

class B

A/method1 A/method2

A/method1 B/method2 B/method3

Page 64: Joker 2016 - Bytecode 101

invokeinterface

• invokestatic • invokespecial

• invokevirtual • invokeinterface • invokedynamic

Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless, Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01

class A

class B impl X

A/method1 A/method2

A/method1 B/method2 B/method3 X/methodX

D impl XD/method1 X/methodX

Page 65: Joker 2016 - Bytecode 101

Вызов метода

Page 66: Joker 2016 - Bytecode 101

obj.method(param1, param2);

Вызов метода

Page 67: Joker 2016 - Bytecode 101

obj.method(param1, param2);

Вызов метода

Page 68: Joker 2016 - Bytecode 101

obj.method(param1, param2);

push obj push param1 push param2 call method

Вызов метода

Page 69: Joker 2016 - Bytecode 101

obj.method(param1, param2);

push obj push param1 push param2 call method

obj

Вызов метода

Page 70: Joker 2016 - Bytecode 101

obj.method(param1, param2);

push obj push param1 push param2 call method

objparam1

Вызов метода

Page 71: Joker 2016 - Bytecode 101

obj.method(param1, param2);

push obj push param1 push param2 call method

objparam1param2

Вызов метода

Page 72: Joker 2016 - Bytecode 101

obj.method(param1, param2);

push obj push param1 push param2 call method

obj?

Вызов метода

Page 73: Joker 2016 - Bytecode 101

this.add(1, 2);0: aload_0 1: iconst_1 2: iconst_2 3: invokevirtual #2; //Method add:(II)I

Вызов метода

Page 74: Joker 2016 - Bytecode 101

Стек

pop push

Page 75: Joker 2016 - Bytecode 101

СтекТаблица

локальных переменных

store

load

pop push

Page 76: Joker 2016 - Bytecode 101

СтекТаблица

локальных переменных

store

load

pop push

Page 77: Joker 2016 - Bytecode 101

СтекТаблица

локальных переменных

store

load

pop push

СтекТаблица

локальных переменных

store

load

pop push

invoke

Page 78: Joker 2016 - Bytecode 101
Page 79: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 80: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c Hello

Дезассемблировать Hello

Page 81: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c Hello

javap

• Дизассемблер Java класс-файлов

• По-умолчанию показывает только структуру класса

– Методы, супер-класс, интерфейсы, итд

• -c покажет байткод методов

• -private покажет все приватные поля и методы

• -s покажет сигнатуры

• -l покажет номера строк и таблицу локальных переменных

Page 82: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

Page 83: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

Конструктор по-умолчанию

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 84: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

Выложить this на стек

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 85: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

Вызвать <init> для Object

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 86: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

Page 87: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

Page 88: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

Обратиться к статическому полю

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 89: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

Загрузить строковую константу в стек

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 90: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

Вызвать метод с параметром

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 91: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

Page 92: Joker 2016 - Bytecode 101

> javap -c Hello Compiled from "Hello.java" public class Hello extends java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

Что такое #1,#2, итд ?

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}

Page 93: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello

Page 94: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello Compiled from "Hello.java“ public class Hello extends java.lang.Object SourceFile: "Hello.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #6.#20; // java/lang/Object."<init>":()V const #2 = Field #21.#22; // java/lang/System.out:Ljava/io/PrintStream; const #3 = String #23; // Hello, World! const #4 = Method #24.#25; // java/io/PrintStream.println:(Ljava/lang/String;)V const #5 = class #26; // Hello const #6 = class #27; // java/lang/Object const #7 = Asciz <init>;

Page 95: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello Compiled from "Hello.java“ public class Hello extends java.lang.Object SourceFile: "Hello.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #6.#20; // java/lang/Object."<init>":()V const #2 = Field #21.#22; // java/lang/System.out:Ljava/io/PrintStream; const #3 = String #23; // Hello, World! const #4 = Method #24.#25; // java/io/PrintStream.println:(Ljava/lang/String;)V const #5 = class #26; // Hello const #6 = class #27; // java/lang/Object const #7 = Asciz <init>;

Page 96: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello public class Hello extends java.lang.Object … public Hello(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;

Page 97: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello public class Hello extends java.lang.Object … public Hello(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;

Page 98: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello public class Hello extends java.lang.Object … public Hello(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;

Page 99: Joker 2016 - Bytecode 101

public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); }}> javap -c -verbose Hello public class Hello extends java.lang.Object … public Hello(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;

Page 100: Joker 2016 - Bytecode 101
Page 101: Joker 2016 - Bytecode 101

Java Bytecode Editor — http://set.ee/jbe/

Page 102: Joker 2016 - Bytecode 101

IntelliJ IDEA: ASM Bytecode Outline plugin

Page 103: Joker 2016 - Bytecode 101

public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet;

public class Get { String name; public String getName() { return name; }}

Page 104: Joker 2016 - Bytecode 101

aload_0 getfield 00 02 areturn

0 1 2 3 4

public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet;

Page 105: Joker 2016 - Bytecode 101

2A B4

public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet;

00 02

0 1 2 3 4

B0

Page 106: Joker 2016 - Bytecode 101

public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet;

Page 107: Joker 2016 - Bytecode 101
Page 108: Joker 2016 - Bytecode 101

ObjectWeb ASM

• Низкоуровневый фреймворк для манипуляций и анализа Java-байткода

• Стандарт de facto

• http://asm.ow2.org

Page 109: Joker 2016 - Bytecode 101
Page 110: Joker 2016 - Bytecode 101

Зачем манипулировать байткодом (ещё раз)

• Профилировщики

• Агенты для мониторинга

• Дебаггеры

• Фреймворки

• JRebel

Page 111: Joker 2016 - Bytecode 101

Зачем манипулировать байткодом (ещё раз)

• Профилировщики

• Агенты для мониторинга

• Дебаггеры

• Фреймворки

• JRebel

Требуется внедрение функциональности в работающий код

Page 112: Joker 2016 - Bytecode 101

ASM: общий сценарий

Создать ClassWriter

Скомпановать visitor-ы:

аннотации, поля, методы, итд

Генерировать новый байткод

12

3

Page 113: Joker 2016 - Bytecode 101

Class Reader

Class Visitor

Page 114: Joker 2016 - Bytecode 101

Class Writer

Class Visitor

Class Visitor

Class Reader

Page 115: Joker 2016 - Bytecode 101

Class Writer

Class Visitor

Class Visitor

Class Reader

Class Visitor

Class Visitor

Page 116: Joker 2016 - Bytecode 101

Class Writer

Class Visitor

Class Visitor

Class Reader

Class Visitor

Class Visitor

Class Visitor

Class Visitor

Class Visitor

Class Visitor

Class Visitor

Class Reader

Class Writer

Page 117: Joker 2016 - Bytecode 101

ClassVisitor

visitvisitSource

visitOuterClassvisitAnnotationvisitAttributevisitInnerClass

visitFieldvisitMethod

visitEnd

ClassReader

Page 118: Joker 2016 - Bytecode 101

ClassVisitor

visitvisitSource

visitOuterClassvisitAnnotation

visitAttributevisitInnerClass

visitFieldvisitMethod

visitEnd

AnnotationVisitor

FieldVisitorMethodVisitor

ClassReader

Page 119: Joker 2016 - Bytecode 101
Page 120: Joker 2016 - Bytecode 101

https://github.com/antonarhipov/asmdemo

Page 121: Joker 2016 - Bytecode 101