OSDN Git Service

save
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / util / JcfaWriteUtil.java
index b765466..4fc730b 100644 (file)
@@ -6,17 +6,24 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 
 import jp.igapyon.jcfa.vo.JcfaClass;
+import jp.igapyon.jcfa.vo.JcfaCode;
 import jp.igapyon.jcfa.vo.JcfaComment;
 import jp.igapyon.jcfa.vo.JcfaField;
 import jp.igapyon.jcfa.vo.JcfaMethod;
 import jp.igapyon.jcfa.vo.JcfaUnit;
+import jp.igapyon.jcfa.vo.operandstack.JcfaOSLocalVariable;
+import jp.igapyon.jcfa.vo.operandstack.JcfaOSNode;
+import jp.igapyon.jcfa.vo.operandstack.JcfaOSRef;
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.JavaClass;
 
 public class JcfaWriteUtil {
        public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
                final StringBuffer result = new StringBuffer();
 
                for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
-                       writeToBuffer(jcfaClass, result);
+                       writeClass(jcfaClass, result);
                }
 
                final BufferedWriter writer = new BufferedWriter(
@@ -31,9 +38,10 @@ public class JcfaWriteUtil {
         * 
         * @param jcfaClass
         * @param result
+        * @throws IOException
         */
-       public static void writeToBuffer(final JcfaClass jcfaClass,
-                       final StringBuffer result) {
+       public static void writeClass(final JcfaClass jcfaClass,
+                       final StringBuffer result) throws IOException {
 
                if (jcfaClass.isMainClass()) {
                        if (jcfaClass.getName().contains(".")) {
@@ -43,7 +51,7 @@ public class JcfaWriteUtil {
                        }
                }
 
-               writeToBuffer(jcfaClass.getComment(), result);
+               writeComment(jcfaClass.getComment(), result);
 
                result.append(jcfaClass.getAccess());
                result.append(" class " + jcfaClass.getLocalName());
@@ -55,11 +63,11 @@ public class JcfaWriteUtil {
                result.append("{");
 
                for (JcfaField jcfaField : jcfaClass.getFieldList()) {
-                       writeToBuffer(jcfaField, result);
+                       writeField(jcfaField, result);
                }
 
                for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
-                       writeToBuffer(jcfaClass, jcfaMethod, result);
+                       writeMethod(jcfaClass, jcfaMethod, result);
                }
 
                result.append("}");
@@ -71,9 +79,9 @@ public class JcfaWriteUtil {
         * @param jcfaField
         * @param result
         */
-       public static void writeToBuffer(final JcfaField jcfaField,
+       public static void writeField(final JcfaField jcfaField,
                        final StringBuffer result) {
-               writeToBuffer(jcfaField.getComment(), result);
+               writeComment(jcfaField.getComment(), result);
 
                result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
                                + " " + jcfaField.getName());
@@ -90,11 +98,13 @@ public class JcfaWriteUtil {
         * @param jcfaClass
         * @param jcfaMethod
         * @param result
+        * @throws IOException
         */
-       public static void writeToBuffer(final JcfaClass jcfaClass,
-                       final JcfaMethod jcfaMethod, final StringBuffer result) {
+       public static void writeMethod(final JcfaClass jcfaClass,
+                       final JcfaMethod jcfaMethod, final StringBuffer result)
+                       throws IOException {
 
-               writeToBuffer(jcfaMethod.getComment(), result);
+               writeComment(jcfaMethod.getComment(), result);
 
                if (jcfaMethod.getName().equals("<init>")) {
                        result.append("public " + jcfaClass.getLocalName() + "(");
@@ -115,16 +125,128 @@ public class JcfaWriteUtil {
                result.append(")");
 
                result.append("{");
+
+               writeCodes(jcfaClass, jcfaMethod, result);
+
                result.append("}");
        }
 
+       public static void writeCodes(final JcfaClass jcfaClass,
+                       final JcfaMethod jcfaMethod, final StringBuffer result)
+                       throws IOException {
+               for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
+                       final byte[] codes = jcfaCode.getCodes();
+                       final JavaClass jc = jcfaCode.getJavaClass();
+
+                       switch (jcfaCode.getOpcode()) {
+                       case Constants.ALOAD_0: {
+                               final JcfaOSLocalVariable osLocalVariable = new JcfaOSLocalVariable();
+                               jcfaMethod.getFrame().getOperandStack().push(osLocalVariable);
+                               osLocalVariable.setLocalVariable(jcfaMethod.getFrame()
+                                               .getLocalVariableList().get(0));
+
+                               jcfaCode.getComment().getCommentList()
+                                               .add(osLocalVariable.getLocalVariable().getName());
+
+                               break;
+                       }
+                       case Constants.RETURN: {
+                               break;
+                       }
+                       case Constants.GETSTATIC: {
+                               final JcfaOSRef osRef = new JcfaOSRef();
+                               jcfaMethod.getFrame().getOperandStack().push(osRef);
+                               osRef.setClassName(JcfaUtil.getConstantFieldrefString(jc,
+                                               codes[1], codes[2]));
+
+                               jcfaCode.getComment().getCommentList()
+                                               .add(osRef.getClassName());
+                               break;
+                       }
+                       case Constants.LDC: {
+                               jcfaCode.getComment().getCommentList()
+                                               .add(JcfaUtil.getConstantString(jc, codes[1]));
+                       }
+                               break;
+                       case Constants.INVOKEVIRTUAL:
+                       case Constants.INVOKESPECIAL: {
+                               final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
+                                               codes[2]);
+                               jcfaCode.getComment().getCommentList()
+                                               .add(JcfaUtil.getConstantMethodRefString(jc, operand));
+
+                               jcfaCode.getComment().getCommentList()
+                                               .add("TODO get args count from signature.");
+                               // get n args.
+                               final JcfaOSNode osNodeArg0 = jcfaMethod.getFrame()
+                                               .getOperandStack().pop();
+
+                               // final JcfaOSRef osRef = (JcfaOSRef) jcfaMethod.getFrame()
+                               // .getOperandStack().pop();
+
+                               jcfaCode.getComment().getCommentList()
+                                               .add("" + osNodeArg0.toString());
+
+                       }
+                               break;
+                       case Constants.LOOKUPSWITCH:
+                               if (true) {
+                                       jcfaCode.getComment().getCommentList()
+                                                       .add("  TODO temporary disabled.");
+                                       break;
+                               }
+                               int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
+                                               codes[4]);
+
+                               jcfaCode.getComment().getCommentList()
+                                               .add("  TODO skipping bytes: " + (skipBytes));
+
+                               int lookupOp = 5;
+
+                               short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
+                               jcfaCode.getComment().getCommentList()
+                                               .add("  TODO skipping bytes: " + (diff));
+
+                               int loopCount = JcfaUtil
+                                               .byte2Int(codes[lookupOp++], codes[lookupOp++],
+                                                               codes[lookupOp++], codes[lookupOp++]);
+                               for (int index = 0; index < loopCount; index++) {
+                                       jcfaCode.getComment()
+                                                       .getCommentList()
+                                                       .add(JcfaUtil.byte2Int(codes[lookupOp++],
+                                                                       codes[lookupOp++], codes[lookupOp++],
+                                                                       codes[lookupOp++])
+                                                                       + ":"
+                                                                       + (JcfaUtil.byte2Int(codes[lookupOp++],
+                                                                                       codes[lookupOp++],
+                                                                                       codes[lookupOp++],
+                                                                                       codes[lookupOp++])));
+                               }
+
+                               short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
+                               jcfaCode.getComment().getCommentList()
+                                               .add("  TODO skipping bytes: " + (diff2));
+
+                               break;
+                       default:
+                               jcfaCode.getComment().getCommentList()
+                                               .add("TODO unsupported opcode");
+                               break;
+                       }
+
+                       writeComment(jcfaCode.getComment(), result);
+
+                       // TODO and code...
+               }
+       }
+
        /**
         * Write comment.
         * 
         * @param jcfaComment
         * @param result
         */
-       public static void writeToBuffer(final JcfaComment jcfaComment,
+       public static void writeComment(final JcfaComment jcfaComment,
                        final StringBuffer result) {
                if (jcfaComment.isJavaDoc()) {
                        result.append("\n/** ");