src/share/classes/com/sun/tools/classfile/StackMapTable_attribute.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 972
694ff82ca68e
parent 0
959103a6100f
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.classfile;
aoqi@0 27
aoqi@0 28 import java.io.IOException;
aoqi@0 29
aoqi@0 30 /**
aoqi@0 31 * See JVMS, section 4.8.4.
aoqi@0 32 *
aoqi@0 33 * <p><b>This is NOT part of any supported API.
aoqi@0 34 * If you write code that depends on this, you do so at your own risk.
aoqi@0 35 * This code and its internal interfaces are subject to change or
aoqi@0 36 * deletion without notice.</b>
aoqi@0 37 */
aoqi@0 38 public class StackMapTable_attribute extends Attribute {
aoqi@0 39 static class InvalidStackMap extends AttributeException {
aoqi@0 40 private static final long serialVersionUID = -5659038410855089780L;
aoqi@0 41 InvalidStackMap(String msg) {
aoqi@0 42 super(msg);
aoqi@0 43 }
aoqi@0 44 }
aoqi@0 45
aoqi@0 46 StackMapTable_attribute(ClassReader cr, int name_index, int length)
aoqi@0 47 throws IOException, InvalidStackMap {
aoqi@0 48 super(name_index, length);
aoqi@0 49 number_of_entries = cr.readUnsignedShort();
aoqi@0 50 entries = new stack_map_frame[number_of_entries];
aoqi@0 51 for (int i = 0; i < number_of_entries; i++)
aoqi@0 52 entries[i] = stack_map_frame.read(cr);
aoqi@0 53 }
aoqi@0 54
aoqi@0 55 public StackMapTable_attribute(ConstantPool constant_pool, stack_map_frame[] entries)
aoqi@0 56 throws ConstantPoolException {
aoqi@0 57 this(constant_pool.getUTF8Index(Attribute.StackMapTable), entries);
aoqi@0 58 }
aoqi@0 59
aoqi@0 60 public StackMapTable_attribute(int name_index, stack_map_frame[] entries) {
aoqi@0 61 super(name_index, length(entries));
aoqi@0 62 this.number_of_entries = entries.length;
aoqi@0 63 this.entries = entries;
aoqi@0 64 }
aoqi@0 65
aoqi@0 66 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 67 return visitor.visitStackMapTable(this, data);
aoqi@0 68 }
aoqi@0 69
aoqi@0 70 static int length(stack_map_frame[] entries) {
aoqi@0 71 int n = 2;
aoqi@0 72 for (stack_map_frame entry: entries)
aoqi@0 73 n += entry.length();
aoqi@0 74 return n;
aoqi@0 75 }
aoqi@0 76
aoqi@0 77 public final int number_of_entries;
aoqi@0 78 public final stack_map_frame entries[];
aoqi@0 79
aoqi@0 80 public static abstract class stack_map_frame {
aoqi@0 81 static stack_map_frame read(ClassReader cr)
aoqi@0 82 throws IOException, InvalidStackMap {
aoqi@0 83 int frame_type = cr.readUnsignedByte();
aoqi@0 84 if (frame_type <= 63)
aoqi@0 85 return new same_frame(frame_type);
aoqi@0 86 else if (frame_type <= 127)
aoqi@0 87 return new same_locals_1_stack_item_frame(frame_type, cr);
aoqi@0 88 else if (frame_type <= 246)
aoqi@0 89 throw new Error("unknown frame_type " + frame_type);
aoqi@0 90 else if (frame_type == 247)
aoqi@0 91 return new same_locals_1_stack_item_frame_extended(frame_type, cr);
aoqi@0 92 else if (frame_type <= 250)
aoqi@0 93 return new chop_frame(frame_type, cr);
aoqi@0 94 else if (frame_type == 251)
aoqi@0 95 return new same_frame_extended(frame_type, cr);
aoqi@0 96 else if (frame_type <= 254)
aoqi@0 97 return new append_frame(frame_type, cr);
aoqi@0 98 else
aoqi@0 99 return new full_frame(frame_type, cr);
aoqi@0 100 }
aoqi@0 101
aoqi@0 102 protected stack_map_frame(int frame_type) {
aoqi@0 103 this.frame_type = frame_type;
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 public int length() {
aoqi@0 107 return 1;
aoqi@0 108 }
aoqi@0 109
aoqi@0 110 public abstract int getOffsetDelta();
aoqi@0 111
aoqi@0 112 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
aoqi@0 113
aoqi@0 114 public final int frame_type;
aoqi@0 115
aoqi@0 116 public static interface Visitor<R,P> {
aoqi@0 117 R visit_same_frame(same_frame frame, P p);
aoqi@0 118 R visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, P p);
aoqi@0 119 R visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, P p);
aoqi@0 120 R visit_chop_frame(chop_frame frame, P p);
aoqi@0 121 R visit_same_frame_extended(same_frame_extended frame, P p);
aoqi@0 122 R visit_append_frame(append_frame frame, P p);
aoqi@0 123 R visit_full_frame(full_frame frame, P p);
aoqi@0 124 }
aoqi@0 125 }
aoqi@0 126
aoqi@0 127 public static class same_frame extends stack_map_frame {
aoqi@0 128 same_frame(int frame_type) {
aoqi@0 129 super(frame_type);
aoqi@0 130 }
aoqi@0 131
aoqi@0 132 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 133 return visitor.visit_same_frame(this, data);
aoqi@0 134 }
aoqi@0 135
aoqi@0 136 public int getOffsetDelta() {
aoqi@0 137 return frame_type;
aoqi@0 138 }
aoqi@0 139 }
aoqi@0 140
aoqi@0 141 public static class same_locals_1_stack_item_frame extends stack_map_frame {
aoqi@0 142 same_locals_1_stack_item_frame(int frame_type, ClassReader cr)
aoqi@0 143 throws IOException, InvalidStackMap {
aoqi@0 144 super(frame_type);
aoqi@0 145 stack = new verification_type_info[1];
aoqi@0 146 stack[0] = verification_type_info.read(cr);
aoqi@0 147 }
aoqi@0 148
aoqi@0 149 @Override
aoqi@0 150 public int length() {
aoqi@0 151 return super.length() + stack[0].length();
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 155 return visitor.visit_same_locals_1_stack_item_frame(this, data);
aoqi@0 156 }
aoqi@0 157
aoqi@0 158 public int getOffsetDelta() {
aoqi@0 159 return frame_type - 64;
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 public final verification_type_info[] stack;
aoqi@0 163 }
aoqi@0 164
aoqi@0 165 public static class same_locals_1_stack_item_frame_extended extends stack_map_frame {
aoqi@0 166 same_locals_1_stack_item_frame_extended(int frame_type, ClassReader cr)
aoqi@0 167 throws IOException, InvalidStackMap {
aoqi@0 168 super(frame_type);
aoqi@0 169 offset_delta = cr.readUnsignedShort();
aoqi@0 170 stack = new verification_type_info[1];
aoqi@0 171 stack[0] = verification_type_info.read(cr);
aoqi@0 172 }
aoqi@0 173
aoqi@0 174 @Override
aoqi@0 175 public int length() {
aoqi@0 176 return super.length() + 2 + stack[0].length();
aoqi@0 177 }
aoqi@0 178
aoqi@0 179 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 180 return visitor.visit_same_locals_1_stack_item_frame_extended(this, data);
aoqi@0 181 }
aoqi@0 182
aoqi@0 183 public int getOffsetDelta() {
aoqi@0 184 return offset_delta;
aoqi@0 185 }
aoqi@0 186
aoqi@0 187 public final int offset_delta;
aoqi@0 188 public final verification_type_info[] stack;
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 public static class chop_frame extends stack_map_frame {
aoqi@0 192 chop_frame(int frame_type, ClassReader cr) throws IOException {
aoqi@0 193 super(frame_type);
aoqi@0 194 offset_delta = cr.readUnsignedShort();
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 @Override
aoqi@0 198 public int length() {
aoqi@0 199 return super.length() + 2;
aoqi@0 200 }
aoqi@0 201
aoqi@0 202 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 203 return visitor.visit_chop_frame(this, data);
aoqi@0 204 }
aoqi@0 205
aoqi@0 206 public int getOffsetDelta() {
aoqi@0 207 return offset_delta;
aoqi@0 208 }
aoqi@0 209
aoqi@0 210 public final int offset_delta;
aoqi@0 211 }
aoqi@0 212
aoqi@0 213 public static class same_frame_extended extends stack_map_frame {
aoqi@0 214 same_frame_extended(int frame_type, ClassReader cr) throws IOException {
aoqi@0 215 super(frame_type);
aoqi@0 216 offset_delta = cr.readUnsignedShort();
aoqi@0 217 }
aoqi@0 218
aoqi@0 219 @Override
aoqi@0 220 public int length() {
aoqi@0 221 return super.length() + 2;
aoqi@0 222 }
aoqi@0 223
aoqi@0 224 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 225 return visitor.visit_same_frame_extended(this, data);
aoqi@0 226 }
aoqi@0 227
aoqi@0 228 public int getOffsetDelta() {
aoqi@0 229 return offset_delta;
aoqi@0 230 }
aoqi@0 231
aoqi@0 232 public final int offset_delta;
aoqi@0 233 }
aoqi@0 234
aoqi@0 235 public static class append_frame extends stack_map_frame {
aoqi@0 236 append_frame(int frame_type, ClassReader cr)
aoqi@0 237 throws IOException, InvalidStackMap {
aoqi@0 238 super(frame_type);
aoqi@0 239 offset_delta = cr.readUnsignedShort();
aoqi@0 240 locals = new verification_type_info[frame_type - 251];
aoqi@0 241 for (int i = 0; i < locals.length; i++)
aoqi@0 242 locals[i] = verification_type_info.read(cr);
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 @Override
aoqi@0 246 public int length() {
aoqi@0 247 int n = super.length() + 2;
aoqi@0 248 for (verification_type_info local: locals)
aoqi@0 249 n += local.length();
aoqi@0 250 return n;
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 254 return visitor.visit_append_frame(this, data);
aoqi@0 255 }
aoqi@0 256
aoqi@0 257 public int getOffsetDelta() {
aoqi@0 258 return offset_delta;
aoqi@0 259 }
aoqi@0 260
aoqi@0 261 public final int offset_delta;
aoqi@0 262 public final verification_type_info[] locals;
aoqi@0 263 }
aoqi@0 264
aoqi@0 265 public static class full_frame extends stack_map_frame {
aoqi@0 266 full_frame(int frame_type, ClassReader cr)
aoqi@0 267 throws IOException, InvalidStackMap {
aoqi@0 268 super(frame_type);
aoqi@0 269 offset_delta = cr.readUnsignedShort();
aoqi@0 270 number_of_locals = cr.readUnsignedShort();
aoqi@0 271 locals = new verification_type_info[number_of_locals];
aoqi@0 272 for (int i = 0; i < locals.length; i++)
aoqi@0 273 locals[i] = verification_type_info.read(cr);
aoqi@0 274 number_of_stack_items = cr.readUnsignedShort();
aoqi@0 275 stack = new verification_type_info[number_of_stack_items];
aoqi@0 276 for (int i = 0; i < stack.length; i++)
aoqi@0 277 stack[i] = verification_type_info.read(cr);
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 @Override
aoqi@0 281 public int length() {
aoqi@0 282 int n = super.length() + 2;
aoqi@0 283 for (verification_type_info local: locals)
aoqi@0 284 n += local.length();
aoqi@0 285 n += 2;
aoqi@0 286 for (verification_type_info item: stack)
aoqi@0 287 n += item.length();
aoqi@0 288 return n;
aoqi@0 289 }
aoqi@0 290
aoqi@0 291 public <R, D> R accept(Visitor<R, D> visitor, D data) {
aoqi@0 292 return visitor.visit_full_frame(this, data);
aoqi@0 293 }
aoqi@0 294
aoqi@0 295 public int getOffsetDelta() {
aoqi@0 296 return offset_delta;
aoqi@0 297 }
aoqi@0 298
aoqi@0 299 public final int offset_delta;
aoqi@0 300 public final int number_of_locals;
aoqi@0 301 public final verification_type_info[] locals;
aoqi@0 302 public final int number_of_stack_items;
aoqi@0 303 public final verification_type_info[] stack;
aoqi@0 304 }
aoqi@0 305
aoqi@0 306 public static class verification_type_info {
aoqi@0 307 public static final int ITEM_Top = 0;
aoqi@0 308 public static final int ITEM_Integer = 1;
aoqi@0 309 public static final int ITEM_Float = 2;
aoqi@0 310 public static final int ITEM_Long = 4;
aoqi@0 311 public static final int ITEM_Double = 3;
aoqi@0 312 public static final int ITEM_Null = 5;
aoqi@0 313 public static final int ITEM_UninitializedThis = 6;
aoqi@0 314 public static final int ITEM_Object = 7;
aoqi@0 315 public static final int ITEM_Uninitialized = 8;
aoqi@0 316
aoqi@0 317 static verification_type_info read(ClassReader cr)
aoqi@0 318 throws IOException, InvalidStackMap {
aoqi@0 319 int tag = cr.readUnsignedByte();
aoqi@0 320 switch (tag) {
aoqi@0 321 case ITEM_Top:
aoqi@0 322 case ITEM_Integer:
aoqi@0 323 case ITEM_Float:
aoqi@0 324 case ITEM_Long:
aoqi@0 325 case ITEM_Double:
aoqi@0 326 case ITEM_Null:
aoqi@0 327 case ITEM_UninitializedThis:
aoqi@0 328 return new verification_type_info(tag);
aoqi@0 329
aoqi@0 330 case ITEM_Object:
aoqi@0 331 return new Object_variable_info(cr);
aoqi@0 332
aoqi@0 333 case ITEM_Uninitialized:
aoqi@0 334 return new Uninitialized_variable_info(cr);
aoqi@0 335
aoqi@0 336 default:
aoqi@0 337 throw new InvalidStackMap("unrecognized verification_type_info tag");
aoqi@0 338 }
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 protected verification_type_info(int tag) {
aoqi@0 342 this.tag = tag;
aoqi@0 343 }
aoqi@0 344
aoqi@0 345 public int length() {
aoqi@0 346 return 1;
aoqi@0 347 }
aoqi@0 348
aoqi@0 349 public final int tag;
aoqi@0 350 }
aoqi@0 351
aoqi@0 352 public static class Object_variable_info extends verification_type_info {
aoqi@0 353 Object_variable_info(ClassReader cr) throws IOException {
aoqi@0 354 super(ITEM_Object);
aoqi@0 355 cpool_index = cr.readUnsignedShort();
aoqi@0 356 }
aoqi@0 357
aoqi@0 358 @Override
aoqi@0 359 public int length() {
aoqi@0 360 return super.length() + 2;
aoqi@0 361 }
aoqi@0 362
aoqi@0 363 public final int cpool_index;
aoqi@0 364 }
aoqi@0 365
aoqi@0 366 public static class Uninitialized_variable_info extends verification_type_info {
aoqi@0 367 Uninitialized_variable_info(ClassReader cr) throws IOException {
aoqi@0 368 super(ITEM_Uninitialized);
aoqi@0 369 offset = cr.readUnsignedShort();
aoqi@0 370 }
aoqi@0 371
aoqi@0 372 @Override
aoqi@0 373 public int length() {
aoqi@0 374 return super.length() + 2;
aoqi@0 375 }
aoqi@0 376
aoqi@0 377 public final int offset;
aoqi@0 378
aoqi@0 379 }
aoqi@0 380 }

mercurial