$ cat Main.class ????3
<init>()VCodeLineNumberTablemain([Ljava/lang/String;)VSourceFile Main.java java/util/ArrayListHello Mainjava/lang/Objectadd(Ljava/lang/Object;)Z!*??
*?Y??W?
Compiled from "Main.java"public class Main { public Main(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object... 4: return
public static void main(java.lang.String[]); Code: 0: new #2 // class java/util/ArrayList 3: dup 4: invokespecial #3 // Method java/util/ArrayList... 7: ldc #4 // String Hello 9: invokevirtual #5 // Method java/util/ArrayList... 12: pop 13: return }
$ javac Main.java$ javap -c Main
[POSITION]: [OPERATION] [OPERAND]
Arguments to the operation. The number and type of these
depends on the operation in use.
...Constant pool: #1 = Methodref #7.#16 // java/lang/Object... #2 = Class #17 // java/util/ArrayList #3 = Methodref #2.#16 // java/util/ArrayList.”<init>” #4 = String #18 // Hello #5 = Methodref #2.#19 // java/util/ArrayList.add:(L... #6 = Class #20 // Main #7 = Class #21 // java/lang/Object #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 Main.java #16 = NameAndType #8:#9 // "<init>":()V #17 = Utf8 java/util/ArrayList
$ javap -v -c Main
Exception in thread "main" java.lang.NullPointerException at Printer.printString(Printer.java:13) at Printer.print(Printer.java:9) at Printer.main(Printer.java:19)
Stack Frame
Operand Stack
Local Variable
Array
Constant Pool #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
Stack Frame
Operand StackLocal Vars Constant Pool #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<ArrayList>
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<ArrayList>
invokespecial Used to invoke an initializer, private method, or superclass method
invokeinterface Used to invoke an interface method
invokestatic Used to invoke a class-level method (i.e. static methods)
invokevirtual Used to invoke an instance method
invokedynamic Used to invoke methods dynamically (new shiny)
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<ArrayList>
...Constant pool: #1 = Methodref #7.#16 // java/lang/Object... #2 = Class #17 // java/util/ArrayList #3 = Methodref #2.#16 // java/util/ArrayList.”<init>” #4 = String #18 // Hello #5 = Methodref #2.#19 // java/util/ArrayList.add:(L... #6 = Class #20 // Main #7 = Class #21 // java/lang/Object #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 Main.java #16 = NameAndType #8:#9 // "<init>":()V #17 = Utf8 java/util/ArrayList
$ javap -v -c Main
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<ArrayList>
Stack Frame
Operand StackLocal Vars Constant Pool #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
...Constant pool: #1 = Methodref #7.#16 // java/lang/Object... #2 = Class #17 // java/util/ArrayList #3 = Methodref #2.#16 // java/util/ArrayList.”<init>” #4 = String #18 // Hello #5 = Methodref #2.#19 // java/util/ArrayList.add:(L... #6 = Class #20 // Main #7 = Class #21 // java/lang/Object #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 Main.java #16 = NameAndType #8:#9 // "<init>":()V #17 = Utf8 java/util/ArrayList #18 = Utf8 Hello #19 = NameAndType #22:#23 // add:(Ljava/lang/Object;)Z
$ javap -v -c Main
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<“Hello”>
Stack Frame
Operand StackLocal Vars Constant Pool
<ArrayList>
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<“Hello”>
...Constant pool: #1 = Methodref #7.#16 // java/lang/Object... #2 = Class #17 // java/util/ArrayList #3 = Methodref #2.#16 // java/util/ArrayList.”<init>” #4 = String #18 // Hello #5 = Methodref #2.#19 // java/util/ArrayList.add:(L... #6 = Class #20 // Main #7 = Class #21 // java/lang/Object #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 Main.java #16 = NameAndType #8:#9 // "<init>":()V #17 = Utf8 java/util/ArrayList #18 = Utf8 Hello #19 = NameAndType #22:#23 // add:(Ljava/lang/Object;)Z
$ javap -v -c Main
java/util/ArrayList.add:(Ljava/lang/Object;)Z
B - byteC - charS - shortI - intJ - longF - floatD - doubleZ - booleanV - voidL - object
Stack Frame
Operand StackLocal Vars Constant Pool
ArrayList
ArrayList #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
“Hello”
Stack Frame
Operand StackLocal Vars Constant PoolArrayList #1 = Methodref
#2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
<ArrayList>
<“Hello”>
Stack Frame
Operand StackLocal Vars Constant Pool #1 = Methodref #2 = Class #3 = Methodref #4 = String #5 = Methodref ...
true
Stack Frame
Operand StackLocal Vars Constant PoolArrayList #1 = Methodref
#2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
true
Stack Frame
Operand StackLocal Vars Constant PoolArrayList #1 = Methodref
#2 = Class #3 = Methodref #4 = String #5 = Methodref ...
0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop13: return
000000B0: 73 01 00 0A 4C 43 6F 6D 70 69 6C 65 72 3B 01 00000000C0: 07 63 6F 6D 70 69 6C 65 01 00 32 28 5B 4C 6A 61000000D0: 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 000000E0: 4C 6D 65 2F 71 6D 78 2F 6A 69 74 65 73 63 72 69000000F0: 70 74 2F 4A 69 74 65 43 6C 61 73 73 3B 01 00 0600000100: 74 6F 6B 65 6E 73 01 00 13 5B 4C 6A 61 76 61 2F00000110: 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 04 6D00000120: 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 6100000130: 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 6100000140: 72 67 73 01 00 09 6A 69 74 65 43 6C 61 73 73 0100000150: 00 1D 4C 6D 65 2F 71 6D 78 2F 6A 69 74 65 73 6300000160: 72 69 70 74 2F 4A 69 74 65 43 6C 61 73 73 3B 0100000170: 00 06 6F 75 74 70 75 74 01 00 1A 4C 6A 61 76 61 00000180: 2F 69 6F 2F 46 69 6C 65 4F 75 74 70 75 74 53 7400000190: 72 65 61 6D 3B 01 00 0A 45 78 63 65 70 74 69 6F000001A0: 6E 73 07 00 3A 01 00 0A 53 6F 75 72 63 65 46 69000001B0: 6C 65 01 00 0A 43 6F 6D 70 69 6C 65 72 2E 6A 61000001C0: 76 61 0C 00 14 00 15 01 00 0A 43 6F 6D 70 69 6C000001D0: 65 72 24 31 01 00 04 4D 61 69 6E 0C 00 14 00 3B000001E0: 01 00 08 43 6F 6D 70 69 6C 65 72 0C 00 1B 00 1C
MethodVisitor mv = cv.visitMethod( Opcodes.ACC_PRIVATE, "setupLogger", "(Lorg/apache/maven/cli/MavenCli$CliRequest;)Lorg/codehaus/plexus/logging/Logger;", null, null);
mv.visitCode();mv.visitTypeInsn( Opcodes.NEW, "com/github/jcgay/maven/color/logger/AnsiColorLogger");
https://github.com/jcgay/maven-color
JiteClass
➤ CodeBlock
➤ CodeBlock
➤ CodeBlock
Compiled from "Main.java"public class Main { public Main(); Code: 0: aload_0 1: invokespecial #1 4: return
public static void main... Code: 0: new #2 3: dup 4: invokespecial #3 7: ldc #4 9: invokevirtual #5 12: pop 13: return }
new JiteClass("Main") {{ defineMethod("main", ACC_PUBLIC | ACC_STATIC, sig(void.class, String[].class), new CodeBlock() {{
// ...
}});}};
new JiteClass("Main") {{ defineMethod("main", ACC_PUBLIC | ACC_STATIC, sig(void.class, String[].class), new CodeBlock() {{ new(p(ArrayList.class)); dup(); invokestatic( p(ArrayList.class), ”<init>”, sig(void.class)); ldc(“Hello”) invokevirtual( p(ArrayList.class), “add”, sig(boolean.class, Object.class)); pop(); voidreturn(); }});}};
new JiteClass("Main") {{ defineMethod("main", ACC_PUBLIC | ACC_STATIC, sig(void.class, String[].class), new CodeBlock() {{ getstatic(p(System.class), "out", ci(PrintStream.class));
ldc(“42");
invokevirtual( p(PrintStream.class), "println", sig(void.class, Object.class));
voidreturn(); }});}};
new JiteClass("Main") {{ defineMethod("main", ACC_PUBLIC | ACC_STATIC, sig(void.class, String[].class), new CodeBlock() {{ getstatic(p(System.class), "out", ci(PrintStream.class));
ldc(“42");
invokevirtual( p(PrintStream.class), "println", sig(void.class, Object.class));
voidreturn(); }});}};
0: getstatic #13 3: ldc #15 5: invokevirtual #21 8: return
p
>
<
: print a variable
: push a 0 onto the stack
: pop the top value off of the stack
+
-
[
: increment a variable
: decrement a variable
: start a loop
] : end a loop
s : swap the top two values of the stack
public JiteClass compile(final String program) { return new JiteClass("Main") {{ defineMethod("main", ACC_PUBLIC | ACC_STATIC, sig(void.class, String[].class), new CodeBlock() {{
// ... }}); }};}
for (String cmd : program.split(“ “)) {
if ("p".equals(cmd)) {
} else if ("+".equals(cmd)) {
} else if ("-".equals(cmd)) {
} else if (">".equals(cmd)) {
} else if ("<".equals(cmd)) {
} else if ("s".equals(cmd)) {
} else if ("[".equals(cmd)) {
} else if ("]".equals(cmd)) {
}}
for (String cmd : program.split(“ “)) {
if ("p".equals(cmd)) {
} else if ("+".equals(cmd)) {
} else if ("-".equals(cmd)) {
} else if (">".equals(cmd)) {
} else if ("<".equals(cmd)) {
} else if ("s".equals(cmd)) {
} else if ("[".equals(cmd)) {
} else if ("]".equals(cmd)) {
}}
if ("p".equals(cmd)) {
dup();
invokestatic( p(String.class), "valueOf", sig(String.class, int.class));
getstatic(p(System.class), "out", ci(PrintStream.class));
swap();
invokevirtual( p(PrintStream.class), "print", sig(void.class, Object.class));
}
Stack<LabelNode[]> loopStack = new Stack<LabelNode[]>();
else if (“[“.equals(cmd)) {
LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); label(begin); dup(); ifeq(end);
loopStack.push(new LabelNode[] {begin, end});}
Stack<LabelNode[]> loopStack = new Stack<LabelNode[]>();
else if (“[“.equals(cmd)) {
LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); label(begin); dup(); ifeq(end);
loopStack.push(new LabelNode[] {begin, end});}
Stack<LabelNode[]> loopStack = new Stack<LabelNode[]>();
else if (“[“.equals(cmd)) {
LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); label(begin); dup(); ifeq(end);
loopStack.push(new LabelNode[] {begin, end});}
Stack<LabelNode[]> loopStack = new Stack<LabelNode[]>();
else if (“[“.equals(cmd)) {
LabelNode begin = new LabelNode(); LabelNode end = new LabelNode();
label(begin); dup(); ifeq(end);
loopStack.push(new LabelNode[] {begin, end});}
else if (“]“.equals(cmd)) {
LabelNode[] labelNodes = loopStack.pop();
LabelNode begin = labelNodes[0]; LabelNode end = labelNodes[1];
go_to(begin); label(end);
}
public class BrainCodeBlock extends CodeBlock {
public void brainPrint(String s) { /* ... */ }
public void brainPush(BrainObject o) { /* ... */ }
public BrainObject brainPop() { /* ... */ } public void brainLoop(Predicate<CodeBlock> b) {
// ... }
}
ClassPool pool = ClassPool.getDefault();CtClass cc = pool.get("test.Rectangle");cc.setSuperclass(pool.get("test.Point"));cc.writeFile();
class ThirdParty { public void run() { fetchData(); processData(); invokeService(); resolveConflicts(); finalize(); }}
ClassPool cp = ClassPool.getDefault();CtClass cc = cp.get(“ThirdParty");CtMethod m = cc.getDeclaredMethod(“fetchData");
m.addLocalVariable("t", CtClass.longType);m.insertBefore( "t = System.currentTimeMillis();");m.insertAfter( “{“ + “ t = System.currentTimeMillis() - t;” + “ System.out.println(\"Time (ms): \" + t);” + ”}"); byte[] byteCode = cc.toBytecode();cc.detach();
http://www.tomsquest.com/blog/2014/01/intro-java-agent-and-bytecode-manipulation/
Brainfu** (Jipsy)
List of JVM Bytecode Operations
http://github.com/jkutner/jipsy
http://docs.oracle.com/javase/specs/jvms/se8/html/
Jitescripthttps://github.com/qmx/jitescript