package jp.igapyon.jcfa;\r
\r
+import java.io.ByteArrayOutputStream;\r
import java.io.File;\r
import java.io.IOException;\r
\r
import jp.igapyon.jcfa.util.JcfaUtil;\r
import jp.igapyon.jcfa.util.JcfaWriteUtil;\r
import jp.igapyon.jcfa.vo.JcfaClass;\r
+import jp.igapyon.jcfa.vo.JcfaCode;\r
import jp.igapyon.jcfa.vo.JcfaField;\r
import jp.igapyon.jcfa.vo.JcfaMethod;\r
import jp.igapyon.jcfa.vo.JcfaUnit;\r
}\r
\r
private final void process(final File inputFile, final File outputDir) {\r
+ parseUnit(inputFile, outputDir);\r
+ }\r
+\r
+ private void parseUnit(final File inputFile, final File outputDir) {\r
try {\r
final JavaClass jc = new ClassParser(inputFile.getCanonicalPath())\r
.parse();\r
}\r
}\r
\r
- analyzeFields(jc, jcfaClass);\r
- analyzeMethods(jc, jcfaClass);\r
+ parseFields(jc, jcfaClass);\r
+ parseMethods(jc, jcfaClass);\r
\r
jcfaUnit.setTargetFile(new File(actualyTargetDir,\r
split[split.length - 1] + ".jcfa"));\r
}\r
}\r
\r
- private void analyzeFields(final JavaClass jc, final JcfaClass jcfaClass) {\r
+ private void parseFields(final JavaClass jc, final JcfaClass jcfaClass) {\r
final org.apache.bcel.classfile.Field[] fields = jc.getFields();\r
for (int indexField = 0; indexField < fields.length; indexField++) {\r
final Field field = fields[indexField];\r
- analyzeField(jc, field, jcfaClass);\r
+ parseField(jc, field, jcfaClass);\r
}\r
}\r
\r
- private void analyzeField(final JavaClass jc, final Field field,\r
+ private void parseField(final JavaClass jc, final Field field,\r
final JcfaClass jcfaClass) {\r
final JcfaField jcfaField = new JcfaField();\r
jcfaField.setName(field.getName());\r
}\r
}\r
\r
- private void analyzeMethods(final JavaClass jc, final JcfaClass jcfaClass)\r
+ private void parseMethods(final JavaClass jc, final JcfaClass jcfaClass)\r
throws IOException {\r
final org.apache.bcel.classfile.Method[] methods = jc.getMethods();\r
for (int indexMethod = 0; indexMethod < methods.length; indexMethod++) {\r
final Method method = methods[indexMethod];\r
- analyzeMethod(jc, method, jcfaClass);\r
+ parseMethod(jc, method, jcfaClass);\r
\r
}\r
}\r
* @param jcfaClass\r
* @throws IOException\r
*/\r
- private void analyzeMethod(final JavaClass jc, final Method method,\r
+ private void parseMethod(final JavaClass jc, final Method method,\r
final JcfaClass jcfaClass) throws IOException {\r
final JcfaMethod jcfaMethod = new JcfaMethod();\r
jcfaClass.getMethodList().add(jcfaMethod);\r
\r
final byte[] codes = code.getCode();\r
for (int pc = 0; pc < codes.length; pc++) {\r
- final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);\r
- short operands = Constants.NO_OF_OPERANDS[opcode];\r
+ final int operands = parseCodes(jc, method, jcfaClass, jcfaMethod,\r
+ pc, codes);\r
if (operands < 0) {\r
- System.err.println(" TODO negative value:"\r
- + Constants.OPCODE_NAMES[opcode] + ": " + operands);\r
- // break;\r
- }\r
-\r
- switch (opcode) {\r
- case Constants.RETURN: {\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode]);\r
- break;\r
- }\r
- case Constants.GETSTATIC: {\r
- System.out.println(" "\r
- + pc\r
- + ": "\r
- + Constants.OPCODE_NAMES[opcode]\r
- + ": "\r
- + JcfaUtil.getConstantFieldrefString(jc, codes[pc + 1],\r
- codes[pc + 2]));\r
break;\r
}\r
- case Constants.LDC: {\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode] + ": "\r
- + JcfaUtil.getConstantString(jc, codes[pc + 1]));\r
- }\r
- break;\r
- case Constants.INVOKEVIRTUAL:\r
- case Constants.INVOKESPECIAL: {\r
- final int operand = JcfaUtil.byte2UnsignedShort(codes[pc + 1],\r
- codes[pc + 2]);\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode] + ": "\r
- + JcfaUtil.getConstantMethodRefString(jc, operand));\r
- }\r
- break;\r
- case Constants.LOOKUPSWITCH:\r
- int result = JcfaUtil.byte2Int(codes[pc + 1], codes[pc + 2],\r
- codes[pc + 3], codes[pc + 4]);\r
- System.out.println(" TODO skipping bytes: " + (result));\r
-\r
- int lookupOp = pc + 5;\r
-\r
- short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
- System.out.println(" TODO skipping bytes: " + (diff));\r
-\r
- int loopCount = JcfaUtil\r
- .byte2Int(codes[lookupOp++], codes[lookupOp++],\r
- codes[lookupOp++], codes[lookupOp++]);\r
- for (int index = 0; index < loopCount; index++) {\r
- System.out.println(" "\r
- + JcfaUtil.byte2Int(codes[lookupOp++],\r
- codes[lookupOp++], codes[lookupOp++],\r
- codes[lookupOp++])\r
- + ":"\r
- + (JcfaUtil.byte2Int(codes[lookupOp++],\r
- codes[lookupOp++], codes[lookupOp++],\r
- codes[lookupOp++]) + pc));\r
- }\r
\r
- short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
- System.out.println(" TODO skipping bytes: " + (diff2));\r
+ pc += operands;\r
+ }\r
+ }\r
+\r
+ private int parseCodes(final JavaClass jc, final Method method,\r
+ final JcfaClass jcfaClass, final JcfaMethod jcfaMethod,\r
+ final int pc, final byte[] codes) throws IOException {\r
+ final JcfaCode jcfaCode = new JcfaCode();\r
+ jcfaMethod.getCodeList().add(jcfaCode);\r
+ jcfaCode.setJavaClass(jc);\r
+\r
+ jcfaCode.setOpcode(JcfaUtil.byte2UnsignedByte(codes[pc]));\r
+ jcfaCode.getComment()\r
+ .getCommentList()\r
+ .add("" + pc + ": "\r
+ + Constants.OPCODE_NAMES[jcfaCode.getOpcode()]);\r
+\r
+ short operands = Constants.NO_OF_OPERANDS[jcfaCode.getOpcode()];\r
+ if (operands < 0) {\r
+ jcfaCode.getComment()\r
+ .getCommentList()\r
+ .add("FIXME NO_OF_OPERANDS has negative value:"\r
+ + Constants.OPCODE_NAMES[jcfaCode.getOpcode()]\r
+ + ": " + operands);\r
+ return operands;\r
+ }\r
\r
- operands += (lookupOp - pc);\r
+ switch (jcfaCode.getOpcode()) {\r
+ case Constants.RETURN:\r
+ break;\r
+ case Constants.GETSTATIC:\r
+ break;\r
+ case Constants.LDC:\r
+ break;\r
+ case Constants.INVOKEVIRTUAL:\r
+ case Constants.INVOKESPECIAL:\r
+ break;\r
+ case Constants.LOOKUPSWITCH: {\r
+ int result = JcfaUtil.byte2Int(codes[pc + 1], codes[pc + 2],\r
+ codes[pc + 3], codes[pc + 4]);\r
+ System.out.println(" TODO skipping bytes: " + (result));\r
+\r
+ int lookupOp = pc + 5;\r
+\r
+ short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
+ System.out.println(" TODO skipping bytes: " + (diff));\r
+\r
+ int loopCount = JcfaUtil.byte2Int(codes[lookupOp++],\r
+ codes[lookupOp++], codes[lookupOp++], codes[lookupOp++]);\r
+\r
+ short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
+ jcfaCode.getComment().getCommentList()\r
+ .add(" TODO skipping bytes: " + (diff2));\r
+\r
+ operands += (lookupOp - pc);\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
\r
- break;\r
- default: {\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode] + " (" + operands\r
- + ")");\r
- }\r
- break;\r
- }\r
- pc += operands;\r
+ {\r
+ final ByteArrayOutputStream outStream = new ByteArrayOutputStream();\r
+ outStream.write(codes, pc, operands + 1);\r
+ outStream.flush();\r
+ jcfaCode.setCodes(outStream.toByteArray());\r
}\r
+ return operands;\r
}\r
}
\ No newline at end of file