1 package serp.bytecode;
2
3 import serp.bytecode.lowlevel.*;
4 import serp.bytecode.visitor.*;
5
6
7
8
9
10
11
12
13
14
15
16 public class StackInstruction extends TypedInstruction {
17 StackInstruction(Code owner, int opcode) {
18 super(owner, opcode);
19 }
20
21 public int getStackChange() {
22 switch (getOpcode()) {
23 case Constants.POP:
24 return -1;
25 case Constants.POP2:
26 return -2;
27 case Constants.DUP:
28 case Constants.DUPX1:
29 case Constants.DUPX2:
30 return 1;
31 case Constants.DUP2:
32 case Constants.DUP2X1:
33 case Constants.DUP2X2:
34 return 2;
35 default:
36 return 0;
37 }
38 }
39
40
41
42
43
44 public String getTypeName() {
45 return null;
46 }
47
48 public TypedInstruction setType(String type) {
49 type = getProject().getNameCache().getExternalForm(type, false);
50 return setWide(long.class.getName().equals(type)
51 || double.class.getName().equals(type));
52 }
53
54
55
56
57
58 public boolean isWide() {
59 switch (getOpcode()) {
60 case Constants.POP2:
61 case Constants.DUP2:
62 case Constants.DUP2X1:
63 case Constants.DUP2X2:
64 return true;
65 default:
66 return false;
67 }
68 }
69
70
71
72
73
74
75
76 public StackInstruction setWide(boolean wide) {
77 switch (getOpcode()) {
78 case Constants.POP:
79 if (wide)
80 setOpcode(Constants.POP2);
81 break;
82 case Constants.POP2:
83 if (!wide)
84 setOpcode(Constants.POP);
85 break;
86 case Constants.DUP:
87 if (wide)
88 setOpcode(Constants.DUP2);
89 break;
90 case Constants.DUP2:
91 if (!wide)
92 setOpcode(Constants.DUP);
93 break;
94 case Constants.DUPX1:
95 if (wide)
96 setOpcode(Constants.DUP2X1);
97 break;
98 case Constants.DUP2X1:
99 if (!wide)
100 setOpcode(Constants.DUPX1);
101 break;
102 case Constants.DUPX2:
103 if (wide)
104 setOpcode(Constants.DUP2X2);
105 break;
106 case Constants.DUP2X2:
107 if (!wide)
108 setOpcode(Constants.DUPX2);
109 break;
110 }
111 return this;
112 }
113
114 public void acceptVisit(BCVisitor visit) {
115 visit.enterStackInstruction(this);
116 visit.exitStackInstruction(this);
117 }
118 }