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.JcfaOperandStackNode;
import jp.igapyon.jcfa.vo.JcfaUnit;
+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(
*
* @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(".")) {
}
}
- writeToBuffer(jcfaClass.getComment(), result);
+ writeComment(jcfaClass.getComment(), result);
result.append(jcfaClass.getAccess());
result.append(" class " + jcfaClass.getLocalName());
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("}");
* @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());
* @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() + "() {");
+ result.append("public " + jcfaClass.getLocalName() + "(");
} else {
result.append("public " + jcfaMethod.getType() + " "
- + jcfaMethod.getName() + "() {");
+ + jcfaMethod.getName() + "(");
+ }
+
+ int argNo = 0;
+ for (String argumentType : jcfaMethod.getArugumentTypeList()) {
+ if (argNo != 0) {
+ result.append(", ");
+ }
+ result.append(argumentType);
+ result.append(" arg" + argNo);
}
+ 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: {
+ jcfaCode.getComment()
+ .getCommentList()
+ .add(jcfaMethod.getFrame().getLocalVariableList()
+ .get(0).getName());
+ final JcfaOperandStackNode operandStackNode = new JcfaOperandStackNode();
+ jcfaMethod.getFrame().getOperandStack().push(operandStackNode);
+ operandStackNode.setName(jcfaMethod.getFrame()
+ .getLocalVariableList().get(0).getName());
+ break;
+ }
+ case Constants.RETURN: {
+ break;
+ }
+ case Constants.GETSTATIC: {
+ jcfaCode.getComment()
+ .getCommentList()
+ .add(JcfaUtil.getConstantFieldrefString(jc, codes[1],
+ codes[2]));
+ 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));
+ }
+ 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/** ");