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 import java.io.DataInput; 25 import java.io.DataOutputStream; 26 import java.io.IOException; 27 28 import com.sun.org.apache.bcel.internal.Const; 29 30 /** 31 * This class represents a stack map attribute used for 32 * preverification of Java classes for the <a 33 * href="https://www.oracle.com/java/technologies/javameoverview.html">Java Platform, Micro Edition</a> 34 * (Java ME). This attribute is used by the <a 35 * href="https://www.oracle.com/technetwork/java/embedded/javame/java-mobile/kvmwp-150240.pdf">KVM</a> 36 * and contained within the Code attribute of a method. See CLDC specification 37 * 5.3.1.2 38 * 39 * @see Code 40 * @see StackMapEntry 41 * @see StackMapType 42 */ 43 public final class StackMap extends Attribute { 44 45 private StackMapEntry[] map; // Table of stack map entries 46 47 48 /* 49 * @param name_index Index of name 50 * @param length Content length in bytes 51 * @param map Table of stack map entries 52 * @param constant_pool Array of constants 53 */ 54 public StackMap(final int name_index, final int length, final StackMapEntry[] map, final ConstantPool constant_pool) { 55 super(Const.ATTR_STACK_MAP, name_index, length, constant_pool); 56 this.map = map; 57 } 58 59 60 /** 61 * Construct object from input stream. 62 * 63 * @param name_index Index of name 64 * @param length Content length in bytes 65 * @param input Input stream 66 * @param constant_pool Array of constants 67 * @throws IOException 68 */ 69 StackMap(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { 70 this(name_index, length, (StackMapEntry[]) null, constant_pool); 71 final int map_length = input.readUnsignedShort(); 72 map = new StackMapEntry[map_length]; 73 for (int i = 0; i < map_length; i++) { 74 map[i] = new StackMapEntry(input, constant_pool); 75 } 76 } 77 78 79 /** 80 * Dump stack map table attribute to file stream in binary format. 81 * 82 * @param file Output file stream 83 * @throws IOException 84 */ 85 @Override 86 public void dump( final DataOutputStream file ) throws IOException { 87 super.dump(file); 88 file.writeShort(map.length); 89 for (final StackMapEntry entry : map) { 90 entry.dump(file); 91 } 92 } 93 94 95 /** 96 * @return Array of stack map entries 97 */ 98 public StackMapEntry[] getStackMap() { 99 return map; 100 } 101 102 103 /** 104 * @param map Array of stack map entries 105 */ 106 public void setStackMap( final StackMapEntry[] map ) { 107 this.map = map; 108 int len = 2; // Length of 'number_of_entries' field prior to the array of stack maps 109 for (final StackMapEntry element : map) { 110 len += element.getMapEntrySize(); 111 } 112 setLength(len); 113 } 114 115 116 /** 117 * @return String representation. 118 */ 119 @Override 120 public String toString() { 121 final StringBuilder buf = new StringBuilder("StackMap("); 122 for (int i = 0; i < map.length; i++) { 123 buf.append(map[i]); 124 if (i < map.length - 1) { 125 buf.append(", "); 126 } 127 } 128 buf.append(')'); 129 return buf.toString(); 130 } 131 132 133 /** 134 * @return deep copy of this attribute 135 */ 136 @Override 137 public Attribute copy( final ConstantPool _constant_pool ) { 138 final StackMap c = (StackMap) clone(); 139 c.map = new StackMapEntry[map.length]; 140 for (int i = 0; i < map.length; i++) { 141 c.map[i] = map[i].copy(); 142 } 143 c.setConstantPool(_constant_pool); 144 return c; 145 } 146 147 148 /** 149 * Called by objects that are traversing the nodes of the tree implicitely 150 * defined by the contents of a Java class. I.e., the hierarchy of methods, 151 * fields, attributes, etc. spawns a tree of objects. 152 * 153 * @param v Visitor object 154 */ 155 @Override 156 public void accept( final Visitor v ) { 157 v.visitStackMap(this); 158 } 159 160 161 public int getMapLength() { 162 return map == null ? 0 : map.length; 163 } 164 }