/******************************************************************************* * Copyright (c) 2002,2006 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.wala.shrikeCT; /** * This attribute reader reads Code attributes from methods. */ public final class CodeReader extends AttributeReader { final private int codeLen; final private int exnTableLen; public CodeReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { super(iter, "Code"); int offset = attr + 6; checkSize(offset, 8); codeLen = cr.getInt(offset + 4); offset += 8; checkSize(offset, codeLen + 2); offset += codeLen; exnTableLen = cr.getUShort(offset); offset += 2; checkSize(offset, exnTableLen * 8 + 2); offset += exnTableLen * 8; int attrCount = cr.getUShort(offset); offset += 2; for (int i = 0; i < attrCount; i++) { checkSize(offset, 6); int len = cr.getInt(offset + 2); offset += 6; checkSize(offset, len); offset += len; } } /** * @return the maximum stack size used by the code, in words */ public int getMaxStack() { return cr.getUShort(attr + 6); } /** * @return the maximum local variable size used by the code, in words */ public int getMaxLocals() { return cr.getUShort(attr + 8); } /** * @return the length of the bytecode array, in bytes */ public int getBytecodeLength() { return codeLen; } /** * @return the bytecode bytes */ public byte[] getBytecode() { byte[] r = new byte[codeLen]; System.arraycopy(cr.getBytes(), attr + 14, r, 0, r.length); return r; } /** * @return the raw exception handler data, a flattened sequence of (startPC, endPC, catchClassIndex, catchPC) tuples */ public int[] getRawHandlers() { int[] r = new int[exnTableLen * 4]; int offset = attr + 14 + codeLen + 2; for (int i = 0; i < r.length; i++) { r[i] = cr.getUShort(offset); offset += 2; } return r; } /** * Point iter at the list of attributes for this code. * * @throws IllegalArgumentException if iter is null */ public void initAttributeIterator(ClassReader.AttrIterator iter) { if (iter == null) { throw new IllegalArgumentException("iter is null"); } iter.init(cr, attr + 14 + codeLen + 2 + exnTableLen * 8); } }