--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <parent>\r
+ <artifactId>plugins</artifactId>\r
+ <groupId>jp.sourceforge.stigmata</groupId>\r
+ <version>1.0</version>\r
+ </parent>\r
+ <groupId>jp.sourceforge.stigmata.plugins</groupId>\r
+ <artifactId>opcodes</artifactId>\r
+ <version>1.0.0</version>\r
+ <name>opcodes</name>\r
+ <url>http://stigmata.sourceforge.jp/stigmata/plugins/opcodes/</url>\r
+\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>jp.sourceforge</groupId>\r
+ <artifactId>stigmata</artifactId>\r
+ <version>2.0.0</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>asm</groupId>\r
+ <artifactId>asm-all</artifactId>\r
+ <version>3.1</version>\r
+ <scope>compile</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>junit</groupId>\r
+ <artifactId>junit</artifactId>\r
+ <version>4.8.1</version>\r
+ <scope>test</scope>\r
+ </dependency>\r
+ </dependencies>\r
+\r
+ <build>\r
+ <plugins>\r
+ <plugin>\r
+ <artifactId>maven-release-plugin</artifactId>\r
+ <configuration>\r
+ <tagBase>svn+ssh://tama3@svn.sourceforge.jp/svnroot/stigmata/plugins/trunk/opcodes/</tagBase>\r
+ </configuration>\r
+ </plugin>\r
+\r
+ <plugin>\r
+ <groupId>org.apache.maven.plugins</groupId>\r
+ <artifactId>maven-dependency-plugin</artifactId>\r
+ <executions>\r
+ <execution>\r
+ <id>copy-dependencies</id>\r
+ <phase>compile</phase>\r
+ <goals>\r
+ <goal>copy-dependencies</goal>\r
+ </goals>\r
+ <configuration>\r
+ <outputDirectory>${project.build.directory}</outputDirectory>\r
+ <includeScope>runtime</includeScope>\r
+ </configuration>\r
+ </execution>\r
+ </executions>\r
+ </plugin>\r
+ </plugins>\r
+ </build>\r
+\r
+ <scm>\r
+ <connection>scm:svn:http://svn.sourceforge.jp/svnroot/stigmata/plugins/trunk/opcodes/opcodes-1.0.0</connection>\r
+ <developerConnection>scm:svn:svn+ssh://tama3@svn.sourceforge.jp/svnroot/stigmata/plugins/trunk/opcodes/opcodes-1.0.0</developerConnection>\r
+ <url>http://svn.sourceforge.jp/svnroot/stigmata/plugins/trunk/opcodes/opcodes-1.0.0</url>\r
+ </scm>\r
+</project>\r
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.util.List;
+
+import jp.sourceforge.stigmata.BirthmarkContext;
+import jp.sourceforge.stigmata.BirthmarkElement;
+
+/**
+ *
+ *
+ * @author tamada
+ * @version $Revision$
+ */
+public interface BirthmarkElementBuilder {
+ public BirthmarkElement[] buildElements(List<Opcode> opcodes, BirthmarkContext context);
+}
+
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import org.objectweb.asm.Label;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class LabelOpcode extends Opcode{
+ private static final long serialVersionUID = -346783431316464L;
+
+ private Label label;
+
+ public LabelOpcode(Label label){
+ super(-1, "targeter", 0, 0, Category.TARGETER);
+ this.label = label;
+ }
+
+ public Label getLabel(){
+ return label;
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.objectweb.asm.Label;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class Opcode implements Serializable{
+ private static final long serialVersionUID = -2349834745416345564L;
+
+ public static enum Category{
+ NORMAL, BRANCH, OBJECT, INVOKE, TARGETER,
+ };
+ private int opcode;
+ private String name;
+ private int argumentCount;
+ private int act;
+ private Category category;
+ private List<Label> labels = new ArrayList<Label>();
+
+ public Opcode(Opcode opcode){
+ this(opcode.getOpcode(), opcode.getName(), opcode.getArgumentCount(), opcode.getAct(), opcode.getCategory());
+ }
+
+ public Opcode(int opcode, String name, int argumentCount, int act, String category){
+ this(opcode, name, argumentCount, act, Category.valueOf(category));
+ }
+
+ public Opcode(int opcode, String name, int argumentCount, int act, Category category){
+ this.opcode = opcode;
+ this.name = name;
+ this.argumentCount = argumentCount;
+ this.act = act;
+ this.category = category;
+ }
+
+ public int getOpcode(){
+ return opcode;
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public int getArgumentCount(){
+ return argumentCount;
+ }
+
+ public void addLabel(Label label){
+ if(label == null){
+ throw new NullPointerException();
+ }
+ if(category != Category.BRANCH){
+ throw new IllegalStateException("this method allows only branch category");
+ }
+ labels.add(label);
+ }
+
+ public void setLabels(Label[] labelArray){
+ if(labelArray == null){
+ throw new NullPointerException();
+ }
+ if(category != Category.BRANCH){
+ throw new IllegalStateException("this method allows only branch category");
+ }
+ labels.clear();
+ for(Label label: labelArray){
+ if(label == null){
+ throw new NullPointerException();
+ }
+ labels.add(label);
+ }
+ }
+
+ public Label getLabel(int index){
+ return labels.get(index);
+ }
+
+ public Iterator<Label> labels(){
+ return Collections.unmodifiableList(labels).iterator();
+ }
+
+ public void setAct(int act){
+ if(category != Category.OBJECT && category != Category.INVOKE){
+ throw new IllegalStateException("setAct can be called only object and invoke category.");
+ }
+ this.act = act;
+ }
+
+ public int getAct(){
+ return act;
+ }
+
+ public Category getCategory(){
+ return category;
+ }
+
+ public String toString(){
+ return String.format("%d:%s:%f(%s)", getOpcode(), getName(), getAct(), getCategory());
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.util.List;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public interface OpcodeExtractListener{
+ public void extractOpcodesFinished(List<Opcode> opcodes);
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ *
+ * @author Haruaki TAMADA
+ * @version $Revision$
+ */
+public class OpcodeExtractMethodVisitor extends MethodAdapter{
+ private List<Opcode> opcodes;
+ private OpcodeManager manager = OpcodeManager.getInstance();
+ private List<OpcodeExtractListener> listeners = new ArrayList<OpcodeExtractListener>();
+
+ public OpcodeExtractMethodVisitor(MethodVisitor visitor){
+ this(visitor, new ArrayList<Opcode>());
+ }
+
+ public OpcodeExtractMethodVisitor(MethodVisitor visitor, List<Opcode> opcodes){
+ super(visitor);
+ this.opcodes = opcodes;
+ }
+
+ public void addOpcodeExtractListener(OpcodeExtractListener listener){
+ listeners.add(listener);
+ }
+
+ public void removeOpcodeExtractListener(OpcodeExtractListener listener){
+ listeners.add(listener);
+ }
+
+ @Override
+ public void visitFieldInsn(int opcode, String owner, String name, String desc){
+ Opcode field = manager.getOpcode(opcode);
+ Opcode o = new Opcode(field);
+ int size = Type.getType(desc).getSize();
+ switch(opcode){
+ case Opcodes.PUTFIELD:
+ size = -1 - size;
+ break;
+ case Opcodes.PUTSTATIC:
+ size = 0 - size;
+ break;
+ case Opcodes.GETFIELD:
+ size = -1 + size;
+ break;
+ case Opcodes.GETSTATIC:
+ size = 0 + size;
+ break;
+ }
+ o.setAct(size);
+ opcodes.add(o);
+ super.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ @Override
+ public void visitIincInsn(int var, int increment){
+ opcodes.add(manager.getOpcode(Opcodes.IINC));
+ super.visitIincInsn(var, increment);
+ }
+
+ @Override
+ public void visitInsn(int opcode){
+ opcodes.add(manager.getOpcode(opcode));
+ super.visitInsn(opcode);
+ }
+
+ @Override
+ public void visitLabel(Label label){
+ opcodes.add(new LabelOpcode(label));
+ }
+
+ @Override
+ public void visitIntInsn(int opcode, int operand){
+ opcodes.add(manager.getOpcode(opcode));
+ super.visitIntInsn(opcode, operand);
+ }
+
+ @Override
+ public void visitJumpInsn(int opcode, Label label){
+ Opcode o = manager.getOpcode(opcode);
+ o.addLabel(label);
+ opcodes.add(o);
+ super.visitJumpInsn(opcode, label);
+ }
+
+ @Override
+ public void visitLdcInsn(Object value){
+ opcodes.add(manager.getOpcode(Opcodes.LDC));
+ super.visitLdcInsn(value);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(int min, int max, Label defaultLabel, Label[] labels){
+ Opcode tableSwitch = new Opcode(manager.getOpcode(Opcodes.TABLESWITCH));
+ tableSwitch.setLabels(labels);
+ tableSwitch.addLabel(defaultLabel);
+
+ opcodes.add(tableSwitch);
+ super.visitTableSwitchInsn(min, max, defaultLabel, labels);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(Label defaultHandle, int[] keys, Label[] labels){
+ Opcode lookupSwitch = new Opcode(manager.getOpcode(Opcodes.LOOKUPSWITCH));
+ lookupSwitch.setLabels(labels);
+ lookupSwitch.addLabel(defaultHandle);
+
+ opcodes.add(lookupSwitch);
+ super.visitLookupSwitchInsn(defaultHandle, keys, labels);
+ }
+
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String desc){
+ Opcode methodOpcode = new Opcode(manager.getOpcode(opcode));
+ Type[] types = Type.getArgumentTypes(desc);
+ int argumentSize = 0;
+ for(Type type: types) argumentSize = type.getSize();
+ int size = Type.getReturnType(desc).getSize();
+ switch(opcode){
+ case Opcodes.INVOKESTATIC:
+ size = size - argumentSize;
+ break;
+ case Opcodes.INVOKEINTERFACE:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKEVIRTUAL:
+ size = size - argumentSize - 1;
+ break;
+ }
+ methodOpcode.setAct(size);
+
+ opcodes.add(methodOpcode);
+ super.visitMethodInsn(opcode, owner, name, desc);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(String desc, int dims){
+ opcodes.add(manager.getOpcode(Opcodes.MULTIANEWARRAY));
+ super.visitMultiANewArrayInsn(desc, dims);
+ }
+
+ @Override
+ public void visitTypeInsn(int opcode, String desc){
+ opcodes.add(manager.getOpcode(opcode));
+ super.visitTypeInsn(opcode, desc);
+ }
+
+ @Override
+ public void visitVarInsn(int opcode, int var){
+ opcodes.add(manager.getOpcode(opcode));
+ super.visitVarInsn(opcode, var);
+ }
+
+ @Override
+ public void visitEnd(){
+ for(OpcodeExtractListener listener: listeners){
+ listener.extractOpcodesFinished(opcodes);
+ }
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.stigmata.Birthmark;
+import jp.sourceforge.stigmata.BirthmarkContext;
+import jp.sourceforge.stigmata.BirthmarkElement;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ *
+ *
+ * @author tamada
+ * @version $Revision$
+ */
+public class OpcodeExtractVisitor extends BirthmarkExtractVisitor{
+ private List<Opcode> opcodeList = new ArrayList<Opcode>();
+ private BirthmarkElementBuilder builder;
+
+ public OpcodeExtractVisitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkContext context, BirthmarkElementBuilder builder){
+ super(visitor, birthmark, context);
+ this.builder = builder;
+ }
+
+ public void visitEnd(){
+ BirthmarkElement[] elements = builder.buildElements(opcodeList, getContext());
+ for(BirthmarkElement element: elements){
+ addElement(element);
+ }
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4){
+ MethodVisitor visitor = super.visitMethod(arg0, arg1, arg2, arg3, arg4);
+ OpcodeExtractMethodVisitor opcodeVisitor = new OpcodeExtractMethodVisitor(visitor, opcodeList);
+
+ return opcodeVisitor;
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import jp.sourceforge.talisman.csvio.CsvLine;
+import jp.sourceforge.talisman.csvio.CsvParser;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class OpcodeManager{
+ private Map<Integer, Opcode> opcodeMap = new HashMap<Integer, Opcode>();
+ private static OpcodeManager manager = new OpcodeManager();
+
+ /**
+ * private constructor for singleton pattern.
+ */
+ private OpcodeManager(){
+ try{
+ URL location = OpcodeManager.class.getResource("/META-INF/bytecode.def");
+ BufferedReader in = new BufferedReader(new InputStreamReader(location.openStream()));
+ CsvParser parser = new CsvParser(in);
+ while(parser.hasNext()){
+ CsvLine line = parser.next();
+ String[] values = line.getValues();
+ if(values.length == 5){
+ Opcode def = new Opcode(
+ Integer.parseInt(values[0]), values[1],
+ Integer.parseInt(values[2]),
+ Integer.parseInt(values[3]), values[4]
+ );
+ opcodeMap.put(def.getOpcode(), def);
+ }
+ }
+ } catch(Exception e){
+ throw new InternalError(e.getMessage());
+ }
+ }
+
+ public static OpcodeManager getInstance(){
+ return manager;
+ }
+
+ public Opcode getOpcode(int opcode){
+ return opcodeMap.get(opcode);
+ }
+}
--- /dev/null
+0,nop,0,0,NORMAL\r
+1,aconst_null,0,1,NORMAL\r
+2,iconst_m1,0,1,NORMAL\r
+3,iconst_0,0,1,NORMAL\r
+4,iconst_1,0,1,NORMAL\r
+5,iconst_2,0,1,NORMAL\r
+6,iconst_3,0,1,NORMAL\r
+7,iconst_4,0,1,NORMAL\r
+8,iconst_5,0,1,NORMAL\r
+9,lconst_0,0,2,NORMAL\r
+10,lconst_1,0,2,NORMAL\r
+11,fconst_0,0,1,NORMAL\r
+12,fconst_1,0,1,NORMAL\r
+13,fconst_2,0,1,NORMAL\r
+14,dconst_0,0,2,NORMAL\r
+15,dconst_1,0,2,NORMAL\r
+16,bipush,1,1,NORMAL\r
+17,sipush,2,1,NORMAL\r
+18,ldc,1,1,NORMAL\r
+19,ldc_w,2,1,NORMAL\r
+20,ldc2_w,2,2,NORMAL\r
+21,iload,1,1,NORMAL\r
+22,lload,1,2,NORMAL\r
+23,fload,1,1,NORMAL\r
+24,dload,1,2,NORMAL\r
+25,aload,1,1,NORMAL\r
+26,iload_0,0,1,NORMAL\r
+27,iload_1,0,1,NORMAL\r
+28,iload_2,0,1,NORMAL\r
+29,iload_3,0,1,NORMAL\r
+30,lload_0,0,2,NORMAL\r
+31,lload_1,0,2,NORMAL\r
+32,lload_2,0,2,NORMAL\r
+33,lload_3,0,2,NORMAL\r
+34,fload_0,0,1,NORMAL\r
+35,fload_1,0,1,NORMAL\r
+36,fload_2,0,1,NORMAL\r
+37,fload_3,0,1,NORMAL\r
+38,dload_0,0,2,NORMAL\r
+39,dload_1,0,2,NORMAL\r
+40,dload_2,0,2,NORMAL\r
+41,dload_3,0,2,NORMAL\r
+42,aload_0,0,1,NORMAL\r
+43,aload_1,0,1,NORMAL\r
+44,aload_2,0,1,NORMAL\r
+45,aload_3,0,1,NORMAL\r
+46,iaload,0,-1,NORMAL\r
+47,laload,0,0,NORMAL\r
+48,faload,0,-1,NORMAL\r
+49,daload,0,0,NORMAL\r
+50,aaload,0,-1,NORMAL\r
+51,baload,0,-1,NORMAL\r
+52,caload,0,-1,NORMAL\r
+53,saload,0,-1,NORMAL\r
+54,istore,1,-1,NORMAL\r
+55,lstore,1,-2,NORMAL\r
+56,fstore,1,-1,NORMAL\r
+57,dstore,1,-2,NORMAL\r
+58,astore,1,-1,NORMAL\r
+59,istore_0,0,-1,NORMAL\r
+60,istore_1,0,-1,NORMAL\r
+61,istore_2,0,-1,NORMAL\r
+62,istore_3,0,-1,NORMAL\r
+63,lstore_0,0,-2,NORMAL\r
+64,lstore_1,0,-2,NORMAL\r
+65,lstore_2,0,-2,NORMAL\r
+66,lstore_3,0,-2,NORMAL\r
+67,fstore_0,0,-1,NORMAL\r
+68,fstore_1,0,-1,NORMAL\r
+69,fstore_2,0,-1,NORMAL\r
+70,fstore_3,0,-1,NORMAL\r
+71,dstore_0,0,-2,NORMAL\r
+72,dstore_1,0,-2,NORMAL\r
+73,dstore_2,0,-2,NORMAL\r
+74,dstore_3,0,-2,NORMAL\r
+75,astore_0,0,-1,NORMAL\r
+76,astore_1,0,-1,NORMAL\r
+77,astore_2,0,-1,NORMAL\r
+78,astore_3,0,-1,NORMAL\r
+79,iastore,0,-3,NORMAL\r
+80,lastore,0,-3,NORMAL\r
+81,fastore,0,-3,NORMAL\r
+82,dastore,0,-3,NORMAL\r
+83,aastore,0,-3,NORMAL\r
+84,bastore,0,-3,NORMAL\r
+85,castore,0,-3,NORMAL\r
+86,sastore,0,-3,NORMAL\r
+87,pop,0,-1,NORMAL\r
+88,pop2,0,-2,NORMAL\r
+89,dup,0,1,NORMAL\r
+90,dup_x1,0,1,NORMAL\r
+91,dup_x2,0,1,NORMAL\r
+92,dup2,0,2,NORMAL\r
+93,dup2_x1,0,2,NORMAL\r
+94,dup2_x2,0,2,NORMAL\r
+95,swap,0,0,NORMAL\r
+96,iadd,0,-1,NORMAL\r
+97,ladd,0,-2,NORMAL\r
+98,fadd,0,-1,NORMAL\r
+99,dadd,0,-2,NORMAL\r
+100,isub,0,-1,NORMAL\r
+101,lsub,0,-2,NORMAL\r
+102,fsub,0,-1,NORMAL\r
+103,dsub,0,-2,NORMAL\r
+104,imul,0,-1,NORMAL\r
+105,lmul,0,-2,NORMAL\r
+106,fmul,0,-1,NORMAL\r
+107,dmul,0,-2,NORMAL\r
+108,idiv,0,-1,NORMAL\r
+109,ldiv,0,-2,NORMAL\r
+110,fdiv,0,-1,NORMAL\r
+111,ddiv,0,-2,NORMAL\r
+112,irem,0,-1,NORMAL\r
+113,lrem,0,-2,NORMAL\r
+114,frem,0,-1,NORMAL\r
+115,drem,0,-2,NORMAL\r
+116,ineg,0,0,NORMAL\r
+117,lneg,0,0,NORMAL\r
+118,fneg,0,0,NORMAL\r
+119,dneg,0,0,NORMAL\r
+120,ishl,0,-1,NORMAL\r
+121,lshl,0,-1,NORMAL\r
+122,ishr,0,-1,NORMAL\r
+123,lshr,0,-1,NORMAL\r
+124,iushr,0,-1,NORMAL\r
+125,lushr,0,-2,NORMAL\r
+126,iand,0,-1,NORMAL\r
+127,land,0,-2,NORMAL\r
+128,ior,0,-1,NORMAL\r
+129,lor,0,-2,NORMAL\r
+130,ixor,0,-1,NORMAL\r
+131,lxor,0,-2,NORMAL\r
+132,iinc,2,0,NORMAL\r
+133,i2l,0,1,NORMAL\r
+134,i2f,0,0,NORMAL\r
+135,i2d,0,1,NORMAL\r
+136,l2i,0,-1,NORMAL\r
+137,l2f,0,-1,NORMAL\r
+138,l2d,0,0,NORMAL\r
+139,f2i,0,0,NORMAL\r
+140,f2l,0,1,NORMAL\r
+141,f2d,0,1,NORMAL\r
+142,d2i,0,-1,NORMAL\r
+143,d2l,0,0,NORMAL\r
+144,d2f,0,-1,NORMAL\r
+145,i2b,0,0,NORMAL\r
+146,i2c,0,0,NORMAL\r
+147,i2s,0,0,NORMAL\r
+148,lcmp,0,-3,NORMAL\r
+149,fcmpl,0,-1,NORMAL\r
+150,fcmpg,0,-1,NORMAL\r
+151,dcmpl,0,-3,NORMAL\r
+152,dcmpg,0,-3,NORMAL\r
+153,ifeq,2,-1,BRANCH\r
+154,ifne,2,-1,BRANCH\r
+155,iflt,2,-1,BRANCH\r
+156,ifge,2,-1,BRANCH\r
+157,ifgt,2,-1,BRANCH\r
+158,ifle,2,-1,BRANCH\r
+159,if_icmpeq,2,-2,BRANCH\r
+160,if_icmpne,2,-2,BRANCH\r
+161,if_icmplt,2,-2,BRANCH\r
+162,if_icmpge,2,-2,BRANCH\r
+163,if_icmpgt,2,-2,BRANCH\r
+164,if_icmple,2,-2,BRANCH\r
+165,if_acmpeq,2,-2,BRANCH\r
+166,if_acmpne,2,-2,BRANCH\r
+167,goto,2,-1,BRANCH\r
+168,jsr,2,-1,BRANCH\r
+169,ret,1,0,NORMAL\r
+170,tableswitch,-1,-1,BRANCH\r
+171,lookupswitch,-1,-1,BRANCH\r
+172,ireturn,0,-1,NORMAL\r
+173,lreturn,0,-2,NORMAL\r
+174,freturn,0,-1,NORMAL\r
+175,dreturn,0,-2,NORMAL\r
+176,areturn,0,-1,NORMAL\r
+177,return,0,0,NORMAL\r
+178,getstatic,2,0,OBJECT\r
+179,putstatic,2,0,OBJECT\r
+180,getfield,2,0,OBJECT\r
+181,putfield,2,0,OBJECT\r
+182,invokevirtual,2,0,INVOKE\r
+183,invokespecial,2,0,INVOKE\r
+184,invokestatic,2,0,INVOKE\r
+185,invokeinterface,2,0,INVOKE\r
+186,__unused,0\r
+187,new,2,1,NORMAL\r
+188,newarray,1,0,NORMAL\r
+189,anewarray,2,0,NORMAL\r
+190,arraylength,0,0,NORMAL\r
+191,athrow,0,-1,NORMAL\r
+192,checkcast,2,0,NORMAL\r
+193,instanceof,2,0,NORMAL\r
+194,monitorenter,0,-1,NORMAL\r
+195,monitorexit,0,-1,NORMAL\r
+196,wide,-1,0,NORMAL\r
+197,multianewarray,3,-1,NORMAL\r
+198,ifnull,2,-1,BRANCH\r
+199,ifnonnull,2,-1,BRANCH\r
+200,goto_w,4,-1,BRANCH\r
+201,jsr_w,4,-1,BRANCH\r
+202,breakpoint,0\r
+203,ldc_quick,1\r
+204,__unused,0\r
+205,ldc2_w_quick,2\r
+206,getfield_quick,2\r
+207,putfield_quick,2\r
+208,getfield2_quick,2\r
+209,putfield2_quick,2\r
+210,__unused,0\r
+211,putstatic_quick,2\r
+212,getstatic2_quick,2\r
+213,putstatic2_quick,2\r
+214,invokevirtual_quick,2\r
+215,invokenonvirtual_quick,2\r
+216,invokesuper_quick,2\r
+217,invokestatic_quick,2\r
+218,invokeinterface_quick,2\r
+219,invokevirtualobject_quick,2\r
+220,__unused,0\r
+221,new_quick,2\r
+222,anewarray_quick,2\r
+223,multianewarray_quick,3\r
+224,checkcast_quick,2\r
+225,instanceof_quick,2\r
+226,invokevirtual_quick_w,4\r
+227,getfield_quick_w,4\r
+228,putfield_quick_w,4\r
+229,__unused,0\r
+230,__unused,0\r
+231,__unused,0\r
+232,__unused,0\r
+233,__unused,0\r
+234,__unused,0\r
+235,__unused,0\r
+236,__unused,0\r
+237,__unused,0\r
+238,__unused,0\r
+239,__unused,0\r
+240,__unused,0\r
+241,__unused,0\r
+242,__unused,0\r
+243,__unused,0\r
+244,__unused,0\r
+245,__unused,0\r
+246,__unused,0\r
+247,__unused,0\r
+248,__unused,0\r
+249,__unused,0\r
+250,__unused,0\r
+251,__unused,0\r
+252,__unused,0\r
+253,__unused,0\r
+254,impdep1,0\r
+255,impdep2,0\r
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Label;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class LabelOpcodeTest{
+ private LabelOpcode opcode;
+ private Label label;
+
+ @Before
+ public void setup(){
+ label = new Label();
+ opcode = new LabelOpcode(label);
+ }
+
+ @Test
+ public void testBasic(){
+ Assert.assertEquals(Opcode.Category.TARGETER, opcode.getCategory());
+ Assert.assertEquals(-1, opcode.getOpcode());
+ Assert.assertEquals("targeter", opcode.getName());
+ Assert.assertEquals(label, opcode.getLabel());
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class OpcodeManagerTest{
+ @Test
+ public void testBasic(){
+ Assert.assertNotNull(OpcodeManager.getInstance());
+
+ Opcode opcode = OpcodeManager.getInstance().getOpcode(182);
+
+ Assert.assertEquals(182, opcode.getOpcode());
+ Assert.assertEquals("invokevirtual", opcode.getName());
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks;
+
+/*
+ * $Id$
+ */
+
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Label;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class OpcodeTest{
+ private Opcode opcode;
+
+ @Before
+ public void setup(){
+ opcode = new Opcode(26, "iload_0", 0, 1, Opcode.Category.NORMAL);
+ }
+
+ @Test
+ public void testBasic(){
+ Assert.assertEquals(26, opcode.getOpcode());
+ Assert.assertEquals("iload_0", opcode.getName());
+ Assert.assertEquals(0, opcode.getArgumentCount());
+ Assert.assertEquals(1, opcode.getAct());
+ Assert.assertEquals(Opcode.Category.NORMAL, opcode.getCategory());
+ }
+
+ @Test
+ public void testSelfConstructor(){
+ Opcode o = new Opcode(opcode);
+ Assert.assertEquals(26, o.getOpcode());
+ Assert.assertEquals("iload_0", o.getName());
+ Assert.assertEquals(0, o.getArgumentCount());
+ Assert.assertEquals(1, o.getAct());
+ Assert.assertEquals(Opcode.Category.NORMAL, o.getCategory());
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void testSetActThrowException(){
+ opcode.setAct(1);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void testAddLabelThrowException(){
+ opcode.addLabel(new Label());
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void testAddLabelNullPointer(){
+ opcode.addLabel(null);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void testSetLabelsThrowException(){
+ opcode.setLabels(new Label[] { new Label() });
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void testSetLabelsNullPointer1(){
+ opcode.setLabels(null);
+ }
+
+ @Test
+ public void testAddLabel(){
+ opcode = new Opcode(154, "ifne", 2, -1, "BRANCH");
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+
+ opcode.addLabel(label1);
+ opcode.addLabel(label2);
+ opcode.addLabel(label3);
+
+ Assert.assertEquals(label1, opcode.getLabel(0));
+ Assert.assertEquals(label2, opcode.getLabel(1));
+ Assert.assertEquals(label3, opcode.getLabel(2));
+
+ Iterator<Label> iterator = opcode.labels();
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(label1, iterator.next());
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(label2, iterator.next());
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(label3, iterator.next());
+ Assert.assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ public void testSetLabels(){
+ opcode = new Opcode(154, "ifne", 2, -1, "BRANCH");
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+
+ opcode.addLabel(label1);
+ opcode.setLabels(new Label[] { label1, label2, label3, });
+
+ Assert.assertEquals(label1, opcode.getLabel(0));
+ Assert.assertEquals(label2, opcode.getLabel(1));
+ Assert.assertEquals(label3, opcode.getLabel(2));
+
+ Iterator<Label> iterator = opcode.labels();
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(label1, iterator.next());
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(label2, iterator.next());
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(label3, iterator.next());
+ Assert.assertFalse(iterator.hasNext());
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void testSetLabelsThrownNullPointerException(){
+ opcode = new Opcode(154, "ifne", 2, -1, "BRANCH");
+
+ opcode.setLabels(new Label[] { null, });
+ }
+
+ /**
+ * this test will be thrown IllegalStateException.
+ * Because, IllegalStateException is checked before null check of array elements.
+ */
+ @Test(expected=IllegalStateException.class)
+ public void testSetLabelsNullPointer2(){
+ opcode.setLabels(new Label[] { null, });
+ }
+
+ @Test
+ public void testSetAct() throws Exception{
+ opcode = new Opcode(182, "invokevirtual", 2, 0, "INVOKE");
+ opcode.setAct(4);
+ }
+}