OSDN Git Service

バイトコードの定義ファイルをより細かくバイトコードを分類するように変更した.
[stigmata/cflib.git] / src / main / java / jp / sourceforge / stigmata / cflib / Opcode.java
1 package jp.sourceforge.stigmata.cflib;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import org.objectweb.asm.Label;
10
11 /**
12  *
13  * @author Haruaki Tamada
14  */
15 public class Opcode implements Serializable, Iterable<Label>{
16     private static final long serialVersionUID = -2349834745416345564L;
17
18     public static enum Category{
19         CONSTANT, LOAD, STORE, ARRAY, STACK, ADD, SUBTRACT, MULTIPLY, DIVIDE, REMAIN,
20         NEGATE, SHIFT_LEFT, SHIFT_RIGHT, USHIFT_RIGHT, AND, OR, XOR, CAST, COMPARE,
21         BRANCH, RETURN, FIELD, INVOKE, NEW, THROW, TARGETER, OTHERS,
22     };
23     private int opcode;
24     private String name;
25     private int argumentCount;
26     private int act;
27     private Category category;
28     private List<Label> labels = new ArrayList<Label>();
29
30     public Opcode(Opcode opcode){
31         this(opcode.getOpcode(), opcode.getName(), opcode.getArgumentCount(), opcode.getAct(), opcode.getCategory());
32     }
33
34     public Opcode(int opcode, String name, int argumentCount, int act, String category){
35         this(opcode, name, argumentCount, act, Category.valueOf(category));
36     }
37
38     public Opcode(int opcode, String name, int argumentCount, int act, Category category){
39         this.opcode = opcode;
40         this.name = name;
41         this.argumentCount = argumentCount;
42         this.act = act;
43         this.category = category;
44     }
45
46     public final int getOpcode(){
47         return opcode;
48     }
49
50     public final String getName(){
51         return name;
52     }
53
54     public int getArgumentCount(){
55         return argumentCount;
56     }
57
58     public void addLabel(Label label){
59         if(label == null){
60             throw new NullPointerException();
61         }
62         if(!(category == Category.TARGETER && labels.size() == 0) 
63                 && category != Category.BRANCH){
64             throw new IllegalStateException("this method allows only branch category");
65         }
66         labels.add(label);
67     }
68
69     public void setLabels(Label[] labelArray){
70         if(labelArray == null){
71             throw new NullPointerException();
72         }
73         if(category != Category.BRANCH){
74             throw new IllegalStateException("this method allows only branch category");
75         }
76         labels.clear();
77         for(Label label: labelArray){
78             if(label == null){
79                 throw new NullPointerException();
80             }
81             labels.add(label);
82         }
83     }
84
85     public boolean hasLabel(Label label){
86         return labels.contains(label);
87     }
88
89     public Label getLabel(int index){
90         return labels.get(index);
91     }
92
93     public synchronized Label[] getLabels(){
94         return labels.toArray(new Label[labels.size()]);
95     }
96
97     @Override
98     public Iterator<Label> iterator(){
99         return Collections.unmodifiableList(labels).iterator();
100     }
101
102     public void setAct(int act){
103         if(category != Category.FIELD && category != Category.INVOKE){
104             throw new IllegalStateException("setAct can be called only object and invoke category.");
105         }
106         this.act = act;
107     }
108
109     public int getAct(){
110         return act;
111     }
112
113     public Category getCategory(){
114         return category;
115     }
116
117     @Override
118     public String toString(){
119         StringBuilder sb = new StringBuilder();
120         sb.append(String.format("%d:%s:%d(%s)", getOpcode(), getName(), getAct(), getCategory()));
121
122         if(getCategory() == Category.BRANCH || getCategory() == Category.TARGETER){
123             sb.append(labels);
124         }
125
126         return new String(sb);
127     }
128 }