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(
*
* @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(")");
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/** ");