1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.bcel.internal.classfile; 23 24 25 import com.sun.org.apache.bcel.internal.Constants; 26 import java.io.*; 27 28 /** 29 * This class represents a stack map entry recording the types of 30 * local variables and the the of stack items at a given byte code offset. 31 * See CLDC specification 5.3.1.2 32 * 33 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 34 * @see StackMap 35 * @see StackMapType 36 */ 37 public final class StackMapEntry implements Cloneable { 38 private int byte_code_offset; 39 private int number_of_locals; 40 private StackMapType[] types_of_locals; 41 private int number_of_stack_items; 42 private StackMapType[] types_of_stack_items; 43 private ConstantPool constant_pool; 44 45 /** 46 * Construct object from file stream. 47 * @param file Input stream 48 * @throws IOException 49 */ 50 StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException 51 { 52 this(file.readShort(), file.readShort(), null, -1, null, constant_pool); 53 54 types_of_locals = new StackMapType[number_of_locals]; 55 for(int i=0; i < number_of_locals; i++) 56 types_of_locals[i] = new StackMapType(file, constant_pool); 57 58 number_of_stack_items = file.readShort(); 59 types_of_stack_items = new StackMapType[number_of_stack_items]; 60 for(int i=0; i < number_of_stack_items; i++) 61 types_of_stack_items[i] = new StackMapType(file, constant_pool); 62 } 63 64 public StackMapEntry(int byte_code_offset, int number_of_locals, 65 StackMapType[] types_of_locals, 66 int number_of_stack_items, 67 StackMapType[] types_of_stack_items, 68 ConstantPool constant_pool) { 69 this.byte_code_offset = byte_code_offset; 70 this.number_of_locals = number_of_locals; 71 this.types_of_locals = types_of_locals; 72 this.number_of_stack_items = number_of_stack_items; 73 this.types_of_stack_items = types_of_stack_items; 74 this.constant_pool = constant_pool; 75 } 76 77 /** 78 * Dump stack map entry 79 * 80 * @param file Output file stream 81 * @throws IOException 82 */ 83 public final void dump(DataOutputStream file) throws IOException 84 { 85 file.writeShort(byte_code_offset); 86 87 file.writeShort(number_of_locals); 88 for(int i=0; i < number_of_locals; i++) 89 types_of_locals[i].dump(file); 90 91 file.writeShort(number_of_stack_items); 92 for(int i=0; i < number_of_stack_items; i++) 93 types_of_stack_items[i].dump(file); 94 } 95 96 /** 97 * @return String representation. 98 */ 99 public final String toString() { 100 StringBuffer buf = new StringBuffer("(offset=" + byte_code_offset); 101 102 if(number_of_locals > 0) { 103 buf.append(", locals={"); 104 105 for(int i=0; i < number_of_locals; i++) { 106 buf.append(types_of_locals[i]); 107 if(i < number_of_locals - 1) 108 buf.append(", "); 109 } 110 111 buf.append("}"); 112 } 113 114 if(number_of_stack_items > 0) { 115 buf.append(", stack items={"); 116 117 for(int i=0; i < number_of_stack_items; i++) { 118 buf.append(types_of_stack_items[i]); 119 if(i < number_of_stack_items - 1) 120 buf.append(", "); 121 } 122 123 buf.append("}"); 124 } 125 126 buf.append(")"); 127 128 return buf.toString(); 129 } 130 131 132 public void setByteCodeOffset(int b) { byte_code_offset = b; } 133 public int getByteCodeOffset() { return byte_code_offset; } 134 public void setNumberOfLocals(int n) { number_of_locals = n; } 135 public int getNumberOfLocals() { return number_of_locals; } 136 public void setTypesOfLocals(StackMapType[] t) { types_of_locals = t; } 137 public StackMapType[] getTypesOfLocals() { return types_of_locals; } 138 public void setNumberOfStackItems(int n) { number_of_stack_items = n; } 139 public int getNumberOfStackItems() { return number_of_stack_items; } 140 public void setTypesOfStackItems(StackMapType[] t) { types_of_stack_items = t; } 141 public StackMapType[] getTypesOfStackItems() { return types_of_stack_items; } 142 143 /** 144 * @return deep copy of this object 145 */ 146 public StackMapEntry copy() { 147 try { 148 return (StackMapEntry)clone(); 149 } catch(CloneNotSupportedException e) {} 150 151 return null; 152 } 153 154 /** 155 * Called by objects that are traversing the nodes of the tree implicitely 156 * defined by the contents of a Java class. I.e., the hierarchy of methods, 157 * fields, attributes, etc. spawns a tree of objects. 158 * 159 * @param v Visitor object 160 */ 161 public void accept(Visitor v) { 162 v.visitStackMapEntry(this); 163 } 164 165 /** 166 * @return Constant pool used by this object. 167 */ 168 public final ConstantPool getConstantPool() { return constant_pool; } 169 170 /** 171 * @param constant_pool Constant pool to be used for this object. 172 */ 173 public final void setConstantPool(ConstantPool constant_pool) { 174 this.constant_pool = constant_pool; 175 } 176 }