View Javadoc

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