001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.classreader;
034:
035: import java.io.*;
036: import java.util.*;
037:
038: import org.apache.log4j.*;
039:
040: import com.jeantessier.text.*;
041:
042: public class Code_attribute extends Attribute_info {
043: private int maxStack;
044: private int maxLocals;
045: private byte[] code;
046: private Collection<ExceptionHandler> exceptionHandlers = new LinkedList<ExceptionHandler>();
047: private Collection<Attribute_info> attributes = new LinkedList<Attribute_info>();
048:
049: public Code_attribute(Classfile classfile, Visitable owner,
050: DataInputStream in) throws IOException {
051: super (classfile, owner);
052:
053: int byteCount = in.readInt();
054: Logger.getLogger(getClass()).debug(
055: "Attribute length: " + byteCount);
056:
057: maxStack = in.readUnsignedShort();
058: Logger.getLogger(getClass()).debug(
059: "Code max stack: " + maxStack);
060:
061: maxLocals = in.readUnsignedShort();
062: Logger.getLogger(getClass()).debug(
063: "Code max locals: " + maxLocals);
064:
065: int codeLength = in.readInt();
066: Logger.getLogger(getClass())
067: .debug("Code length: " + codeLength);
068:
069: code = new byte[codeLength];
070: int bytesRead = in.read(code);
071:
072: if (Logger.getLogger(getClass()).isDebugEnabled()) {
073: Logger.getLogger(getClass()).debug(
074: "Read " + bytesRead + " byte(s): "
075: + Hex.toString(code));
076:
077: Iterator ci = iterator();
078: while (ci.hasNext()) {
079: Instruction instr = (Instruction) ci.next();
080: int start = instr.getStart();
081: int index = instr.getIndex();
082:
083: switch (instr.getOpcode()) {
084: case 0x12: // ldc
085: case 0x13: // ldc_w
086: case 0x14: // ldc2_w
087: case 0xb2: // getstatic
088: case 0xb3: // putstatic
089: case 0xb4: // getfield
090: case 0xb5: // putfield
091: case 0xb6: // invokevirtual
092: case 0xb7: // invokespecial
093: case 0xb8: // invokestatic
094: case 0xb9: // invokeinterface
095: case 0xbb: // new
096: case 0xbd: // anewarray
097: case 0xc0: // checkcast
098: case 0xc1: // instanceof
099: case 0xc5: // multianewarray
100: Logger
101: .getLogger(getClass())
102: .debug(
103: " "
104: + start
105: + ": "
106: + instr
107: + " "
108: + index
109: + " ("
110: + instr
111: .getIndexedConstantPoolEntry()
112: + ")");
113: break;
114: default:
115: Logger.getLogger(getClass()).debug(
116: " " + start + ": " + instr + " ("
117: + instr.getLength() + " byte(s))");
118: break;
119: }
120: }
121: }
122:
123: int exceptionTableLength = in.readUnsignedShort();
124: Logger.getLogger(getClass()).debug(
125: "Reading " + exceptionTableLength
126: + " exception handler(s) ...");
127: for (int i = 0; i < exceptionTableLength; i++) {
128: Logger.getLogger(getClass()).debug(
129: "Exception handler " + i + ":");
130: exceptionHandlers.add(new ExceptionHandler(this , in));
131: }
132:
133: int attributeCount = in.readUnsignedShort();
134: Logger.getLogger(getClass()).debug(
135: "Reading " + attributeCount + " code attribute(s)");
136: for (int i = 0; i < attributeCount; i++) {
137: Logger.getLogger(getClass()).debug(
138: "code attribute " + i + ":");
139: attributes.add(AttributeFactory.create(getClassfile(),
140: this , in));
141: }
142: }
143:
144: public int getMaxStack() {
145: return maxStack;
146: }
147:
148: public int getMaxLocals() {
149: return maxLocals;
150: }
151:
152: public byte[] getCode() {
153: return code;
154: }
155:
156: public Iterator iterator() {
157: return new CodeIterator(this , code);
158: }
159:
160: public Collection<ExceptionHandler> getExceptionHandlers() {
161: return exceptionHandlers;
162: }
163:
164: public Collection<Attribute_info> getAttributes() {
165: return attributes;
166: }
167:
168: public String toString() {
169: return "Code";
170: }
171:
172: public void accept(Visitor visitor) {
173: visitor.visitCode_attribute(this);
174: }
175: }
|