OSDN Git Service

Creating field.
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / JavaClassFileAnalyzer.java
1 package jp.igapyon.jcfa;\r
2 \r
3 import java.io.IOException;\r
4 \r
5 import jp.igapyon.jcfa.util.JcfaUtil;\r
6 \r
7 import org.apache.bcel.Constants;\r
8 /**\r
9  * Apache Jakarta BCELを用いたクラスファイル(バイトコード)解析サンプル\r
10  */\r
11 import org.apache.bcel.classfile.ClassFormatException;\r
12 import org.apache.bcel.classfile.ClassParser;\r
13 import org.apache.bcel.classfile.Code;\r
14 import org.apache.bcel.classfile.Field;\r
15 import org.apache.bcel.classfile.JavaClass;\r
16 import org.apache.bcel.classfile.Method;\r
17 \r
18 public class JavaClassFileAnalyzer {\r
19         private static final String CLASS_MODULE = "./bin/test/TestJavaClass002.class";\r
20 \r
21         public static final void main(final String[] args) {\r
22                 new JavaClassFileAnalyzer().process();\r
23         }\r
24 \r
25         private final void process() {\r
26                 try {\r
27                         final JavaClass jc = new ClassParser(CLASS_MODULE).parse();\r
28                         System.out.println("Classname   : " + jc.getClassName());\r
29                         System.out.println("Parent class: " + jc.getSuperclassName());\r
30 \r
31                         final org.apache.bcel.classfile.Field[] fields = jc.getFields();\r
32                         for (int indexField = 0; indexField < fields.length; indexField++) {\r
33                                 final Field field = fields[indexField];\r
34                                 System.out.println("  Field:" + field.getName());\r
35                                 String access = "";\r
36                                 access += field.isPublic() ? "public " : "";\r
37                                 access += field.isAbstract() ? "abstract " : "";\r
38                                 access += field.isStatic() ? "static " : "";\r
39                                 access += field.isFinal() ? "final " : "";\r
40                                 System.out.println("    " + access);\r
41                                 System.out.println("    " + field.getSignature());\r
42                         }\r
43 \r
44                         final org.apache.bcel.classfile.Method[] methods = jc.getMethods();\r
45                         for (int indexMethod = 0; indexMethod < methods.length; indexMethod++) {\r
46                                 final Method method = methods[indexMethod];\r
47                                 System.out.println("  Method:" + method.getName());\r
48                                 final Code code = method.getCode();\r
49                                 if (code == null) {\r
50                                         continue;\r
51                                 }\r
52 \r
53                                 final byte[] codes = code.getCode();\r
54                                 for (int pc = 0; pc < codes.length; pc++) {\r
55                                         final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);\r
56                                         short operands = Constants.NO_OF_OPERANDS[opcode];\r
57                                         if (operands < 0) {\r
58                                                 System.out.println("  TODO negative value:"\r
59                                                                 + Constants.OPCODE_NAMES[opcode] + ": "\r
60                                                                 + operands);\r
61                                                 // break;\r
62                                         }\r
63 \r
64                                         switch (opcode) {\r
65                                         case Constants.RETURN: {\r
66                                                 System.out.println("    " + pc + ": "\r
67                                                                 + Constants.OPCODE_NAMES[opcode]);\r
68                                                 break;\r
69                                         }\r
70                                         case Constants.GETSTATIC: {\r
71                                                 System.out.println("    "\r
72                                                                 + pc\r
73                                                                 + ": "\r
74                                                                 + Constants.OPCODE_NAMES[opcode]\r
75                                                                 + ": "\r
76                                                                 + JcfaUtil.getConstantFieldrefString(jc,\r
77                                                                                 codes[pc + 1], codes[pc + 2]));\r
78                                                 break;\r
79                                         }\r
80                                         case Constants.LDC: {\r
81                                                 System.out\r
82                                                                 .println("    "\r
83                                                                                 + pc\r
84                                                                                 + ": "\r
85                                                                                 + Constants.OPCODE_NAMES[opcode]\r
86                                                                                 + ": "\r
87                                                                                 + JcfaUtil.getConstantString(jc,\r
88                                                                                                 codes[pc + 1]));\r
89                                         }\r
90                                                 break;\r
91                                         case Constants.INVOKEVIRTUAL:\r
92                                         case Constants.INVOKESPECIAL: {\r
93                                                 final int operand = JcfaUtil.byte2UnsignedShort(\r
94                                                                 codes[pc + 1], codes[pc + 2]);\r
95                                                 System.out.println("    "\r
96                                                                 + pc\r
97                                                                 + ": "\r
98                                                                 + Constants.OPCODE_NAMES[opcode]\r
99                                                                 + ": "\r
100                                                                 + JcfaUtil.getConstantMethodRefString(jc,\r
101                                                                                 operand));\r
102                                         }\r
103                                                 break;\r
104                                         case Constants.LOOKUPSWITCH:\r
105                                                 int result = JcfaUtil.byte2Int(codes[pc + 1],\r
106                                                                 codes[pc + 2], codes[pc + 3], codes[pc + 4]);\r
107                                                 System.out\r
108                                                                 .println("  TODO skipping bytes: " + (result));\r
109 \r
110                                                 int lookupOp = pc + 5;\r
111 \r
112                                                 short diff = JcfaUtil\r
113                                                                 .byte2UnsignedByte(codes[lookupOp++]);\r
114                                                 System.out.println("  TODO skipping bytes: " + (diff));\r
115 \r
116                                                 int loopCount = JcfaUtil.byte2Int(codes[lookupOp++],\r
117                                                                 codes[lookupOp++], codes[lookupOp++],\r
118                                                                 codes[lookupOp++]);\r
119                                                 for (int index = 0; index < loopCount; index++) {\r
120                                                         System.out.println("      "\r
121                                                                         + JcfaUtil.byte2Int(codes[lookupOp++],\r
122                                                                                         codes[lookupOp++],\r
123                                                                                         codes[lookupOp++],\r
124                                                                                         codes[lookupOp++])\r
125                                                                         + ":"\r
126                                                                         + (JcfaUtil.byte2Int(codes[lookupOp++],\r
127                                                                                         codes[lookupOp++],\r
128                                                                                         codes[lookupOp++],\r
129                                                                                         codes[lookupOp++]) + pc));\r
130                                                 }\r
131 \r
132                                                 short diff2 = JcfaUtil\r
133                                                                 .byte2UnsignedByte(codes[lookupOp++]);\r
134                                                 System.out.println("  TODO skipping bytes: " + (diff2));\r
135 \r
136                                                 operands += (lookupOp - pc);\r
137 \r
138                                                 break;\r
139                                         default: {\r
140                                                 System.out.println("    " + pc + ": "\r
141                                                                 + Constants.OPCODE_NAMES[opcode] + " ("\r
142                                                                 + operands + ")");\r
143                                         }\r
144                                                 break;\r
145                                         }\r
146                                         pc += operands;\r
147                                 }\r
148                         }\r
149                 } catch (ClassFormatException e) {\r
150                         e.printStackTrace();\r
151                 } catch (IOException e) {\r
152                         e.printStackTrace();\r
153                 }\r
154         }\r
155 }