Code_attribute.java revision 3827:44bdefe64114
1169689Skan/* 2169689Skan * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3169689Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4169689Skan * 5169689Skan * This code is free software; you can redistribute it and/or modify it 6169689Skan * under the terms of the GNU General Public License version 2 only, as 7169689Skan * published by the Free Software Foundation. Oracle designates this 8169689Skan * particular file as subject to the "Classpath" exception as provided 9169689Skan * by Oracle in the LICENSE file that accompanied this code. 10169689Skan * 11169689Skan * This code is distributed in the hope that it will be useful, but WITHOUT 12169689Skan * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13169689Skan * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14169689Skan * version 2 for more details (a copy is included in the LICENSE file that 15169689Skan * accompanied this code). 16169689Skan * 17169689Skan * You should have received a copy of the GNU General Public License version 18169689Skan * 2 along with this work; if not, write to the Free Software Foundation, 19169689Skan * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20169689Skan * 21169689Skan * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22169689Skan * or visit www.oracle.com if you need additional information or have any 23169689Skan * questions. 24169689Skan */ 25169689Skan 26169689Skanpackage com.sun.tools.classfile; 27169689Skan 28169689Skanimport java.io.IOException; 29169689Skanimport java.util.Iterator; 30169689Skanimport java.util.NoSuchElementException; 31169689Skan 32169689Skan/** 33169689Skan * See JVMS, section 4.8.3. 34169689Skan * 35169689Skan * <p><b>This is NOT part of any supported API. 36169689Skan * If you write code that depends on this, you do so at your own risk. 37169689Skan * This code and its internal interfaces are subject to change or 38169689Skan * deletion without notice.</b> 39169689Skan */ 40169689Skanpublic class Code_attribute extends Attribute { 41169689Skan public static class InvalidIndex extends AttributeException { 42169689Skan private static final long serialVersionUID = -8904527774589382802L; 43169689Skan InvalidIndex(int index) { 44169689Skan this.index = index; 45169689Skan } 46169689Skan 47169689Skan @Override 48169689Skan public String getMessage() { 49169689Skan // i18n 50169689Skan return "invalid index " + index + " in Code attribute"; 51169689Skan } 52169689Skan 53169689Skan public final int index; 54169689Skan } 55169689Skan 56169689Skan Code_attribute(ClassReader cr, int name_index, int length) 57169689Skan throws IOException, ConstantPoolException { 58169689Skan super(name_index, length); 59169689Skan max_stack = cr.readUnsignedShort(); 60169689Skan max_locals = cr.readUnsignedShort(); 61169689Skan code_length = cr.readInt(); 62169689Skan code = new byte[code_length]; 63169689Skan cr.readFully(code); 64169689Skan exception_table_length = cr.readUnsignedShort(); 65169689Skan exception_table = new Exception_data[exception_table_length]; 66169689Skan for (int i = 0; i < exception_table_length; i++) 67169689Skan exception_table[i] = new Exception_data(cr); 68169689Skan attributes = new Attributes(cr); 69169689Skan } 70169689Skan 71169689Skan public int getByte(int offset) throws InvalidIndex { 72169689Skan if (offset < 0 || offset >= code.length) 73169689Skan throw new InvalidIndex(offset); 74169689Skan return code[offset]; 75169689Skan } 76169689Skan 77169689Skan public int getUnsignedByte(int offset) throws InvalidIndex { 78169689Skan if (offset < 0 || offset >= code.length) 79169689Skan throw new InvalidIndex(offset); 80169689Skan return code[offset] & 0xff; 81169689Skan } 82169689Skan 83169689Skan public int getShort(int offset) throws InvalidIndex { 84169689Skan if (offset < 0 || offset + 1 >= code.length) 85169689Skan throw new InvalidIndex(offset); 86169689Skan return (code[offset] << 8) | (code[offset + 1] & 0xFF); 87169689Skan } 88169689Skan 89169689Skan public int getUnsignedShort(int offset) throws InvalidIndex { 90169689Skan if (offset < 0 || offset + 1 >= code.length) 91169689Skan throw new InvalidIndex(offset); 92169689Skan return ((code[offset] << 8) | (code[offset + 1] & 0xFF)) & 0xFFFF; 93169689Skan } 94169689Skan 95169689Skan public int getInt(int offset) throws InvalidIndex { 96169689Skan if (offset < 0 || offset + 3 >= code.length) 97169689Skan throw new InvalidIndex(offset); 98169689Skan return (getShort(offset) << 16) | (getShort(offset + 2) & 0xFFFF); 99169689Skan } 100169689Skan 101169689Skan public <R, D> R accept(Visitor<R, D> visitor, D data) { 102169689Skan return visitor.visitCode(this, data); 103169689Skan } 104169689Skan 105169689Skan public Iterable<Instruction> getInstructions() { 106169689Skan return () -> new Iterator<Instruction>() { 107169689Skan 108169689Skan public boolean hasNext() { 109169689Skan return (next != null); 110169689Skan } 111169689Skan 112169689Skan public Instruction next() { 113169689Skan if (next == null) 114169689Skan throw new NoSuchElementException(); 115169689Skan 116169689Skan current = next; 117169689Skan pc += current.length(); 118169689Skan next = (pc < code.length ? new Instruction(code, pc) : null); 119169689Skan return current; 120169689Skan } 121169689Skan 122169689Skan public void remove() { 123169689Skan throw new UnsupportedOperationException("Not supported."); 124169689Skan } 125169689Skan 126169689Skan Instruction current = null; 127169689Skan int pc = 0; 128169689Skan Instruction next = new Instruction(code, pc); 129169689Skan 130169689Skan }; 131169689Skan } 132169689Skan 133169689Skan public final int max_stack; 134169689Skan public final int max_locals; 135169689Skan public final int code_length; 136169689Skan public final byte[] code; 137169689Skan public final int exception_table_length; 138169689Skan public final Exception_data[] exception_table; 139169689Skan public final Attributes attributes; 140169689Skan 141169689Skan public static class Exception_data { 142169689Skan Exception_data(ClassReader cr) throws IOException { 143169689Skan start_pc = cr.readUnsignedShort(); 144169689Skan end_pc = cr.readUnsignedShort(); 145169689Skan handler_pc = cr.readUnsignedShort(); 146169689Skan catch_type = cr.readUnsignedShort(); 147169689Skan } 148169689Skan 149169689Skan public final int start_pc; 150169689Skan public final int end_pc; 151169689Skan public final int handler_pc; 152169689Skan public final int catch_type; 153169689Skan } 154169689Skan} 155169689Skan