View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  
17  
18  package org.apache.jdo.impl.enhancer.classfile;
19  
20  
21  import java.io.PrintStream;
22  import java.util.Stack;
23  
24  /***
25   * An instruction which requires a single branch offset
26   * as an immediate operand .
27   */
28  public class InsnTargetOp extends Insn {
29      /* The branch target */
30      InsnTarget targetOp;
31  
32      /* public accessors */
33  
34      public int nStackArgs() {
35          return VMOp.ops[opcode()].nStackArgs();
36      }
37  
38      public int nStackResults() {
39          return VMOp.ops[opcode()].nStackResults();
40      }
41  
42      public String argTypes() {
43          return VMOp.ops[opcode()].argTypes();
44      }
45  
46      public String resultTypes() {
47          return VMOp.ops[opcode()].resultTypes();
48      }
49  
50      public boolean branches() {
51          return true;
52      }
53  
54      /***
55       * Mark possible branch targets
56       */
57      public void markTargets() {
58          targetOp.setBranchTarget();
59      }
60  
61      /***
62       * Return the branch target which is the immediate operand
63       */
64      public InsnTarget target() {
65          return targetOp;
66      }
67      
68      /***
69       * Compares this instance with another for structural equality.
70       */
71      //@olsen: added method
72      public boolean isEqual(Stack msg, Object obj) {
73          if (!(obj instanceof InsnTargetOp)) {
74              msg.push("obj/obj.getClass() = "
75                       + (obj == null ? null : obj.getClass()));
76              msg.push("this.getClass() = "
77                       + this.getClass());
78              return false;
79          }
80          InsnTargetOp other = (InsnTargetOp)obj;
81  
82          if (!super.isEqual(msg, other)) {
83              return false;
84          }
85  
86          if (!this.targetOp.isEqual(msg, other.targetOp)) {
87              msg.push(String.valueOf("targetOp = "
88                                      + other.targetOp));
89              msg.push(String.valueOf("targetOp = "
90                                      + this.targetOp));
91              return false;
92          }
93          return true;
94      }
95  
96      /* package local methods *//package-summary/html">class="comment"> package local methods *//package-summary.html">/* package local methods *//package-summary.html">class="comment"> package local methods */
97  
98      void print (PrintStream out, int indent) {
99          ClassPrint.spaces(out, indent);
100         /* print offset in non-relative form for readability */
101         out.println(offset() + "  " + opName(opcode()) + "  " + 
102                     targetOp.offset());
103     }
104 
105     int store(byte[] buf, int index) {
106         buf[index++] = (byte) opcode();
107         int off = targetOp.offset() - offset();
108         if (opcode() == opc_goto_w || opcode() == opc_jsr_w)
109             return storeInt(buf, index, off);
110         else
111             return storeShort(buf, index, (short)off);
112     }
113 
114     int size() {
115         if (opcode() == opc_goto_w || opcode() == opc_jsr_w)
116             return 5;
117         return 3;
118     }
119 
120     InsnTargetOp (int theOpcode, InsnTarget theOperand, int pc) {
121         super(theOpcode, pc);
122         targetOp = theOperand;
123     }
124 
125     InsnTargetOp (int theOpcode, InsnTarget theOperand) {
126         super(theOpcode, NO_OFFSET);
127 
128         targetOp = theOperand;
129 
130         switch(theOpcode) {
131         case opc_ifeq:
132         case opc_ifne:
133         case opc_iflt:
134         case opc_ifge:
135         case opc_ifgt:
136         case opc_ifle:
137         case opc_if_icmpeq:
138         case opc_if_icmpne:
139         case opc_if_icmplt:
140         case opc_if_icmpge:
141         case opc_if_icmpgt:
142         case opc_if_icmple:
143         case opc_if_acmpeq:
144         case opc_if_acmpne:
145         case opc_goto:
146         case opc_jsr:
147         case opc_ifnull:
148         case opc_ifnonnull:
149         case opc_goto_w:
150         case opc_jsr_w:
151             /* Target */
152             if (theOperand == null)
153                 throw new InsnError ("attempt to create an " + opName(theOpcode) +
154                                      " with a null Target operand");
155             break;
156 
157         default:
158             throw new InsnError ("attempt to create an " + opName(theOpcode) +
159                                  " with an InsnTarget operand");
160         }
161     }
162 }