169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataInputStream; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataOutputStream; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.List; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.ArrayList; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Iterator; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Code_attribute</code>. 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To browse the <code>code</code> field of 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a <code>Code_attribute</code> structure, 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * use <code>CodeIterator</code>. 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see CodeIterator 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class CodeAttribute extends AttributeInfo implements Opcode { 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The name of this attribute <code>"Code"</code>. 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String tag = "Code"; 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // code[] is stored in AttributeInfo.info. 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int maxStack; 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int maxLocals; 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ExceptionTable exceptions; 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ArrayList attributes; 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a <code>Code_attribute</code>. 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp constant pool table 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param stack <code>max_stack</code> 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param locals <code>max_locals</code> 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param code <code>code[]</code> 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param etable <code>exception_table[]</code> 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CodeAttribute(ConstPool cp, int stack, int locals, byte[] code, 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ExceptionTable etable) 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, tag); 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxStack = stack; 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxLocals = locals; 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal info = code; 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exceptions = etable; 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes = new ArrayList(); 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a copy of <code>Code_attribute</code>. 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Specified class names are replaced during the copy. 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp constant pool table. 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param src source Code attribute. 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classnames pairs of replaced and substituted 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class names. 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private CodeAttribute(ConstPool cp, CodeAttribute src, Map classnames) 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, tag); 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxStack = src.getMaxStack(); 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxLocals = src.getMaxLocals(); 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exceptions = src.getExceptionTable().copy(cp, classnames); 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes = new ArrayList(); 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal List src_attr = src.getAttributes(); 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int num = src_attr.size(); 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < num; ++i) { 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo ai = (AttributeInfo)src_attr.get(i); 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes.add(ai.copy(cp, classnames)); 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal info = src.copyCode(cp, classnames, exceptions, this); 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CodeAttribute(ConstPool cp, int name_id, DataInputStream in) 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws IOException 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, name_id, (byte[])null); 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int attr_len = in.readInt(); 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxStack = in.readUnsignedShort(); 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxLocals = in.readUnsignedShort(); 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int code_len = in.readInt(); 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal info = new byte[code_len]; 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal in.readFully(info); 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exceptions = new ExceptionTable(cp, in); 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes = new ArrayList(); 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int num = in.readUnsignedShort(); 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < num; ++i) 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes.add(AttributeInfo.read(cp, in)); 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes a copy. Class names are replaced according to the 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * given <code>Map</code> object. 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param newCp the constant pool table used by the new copy. 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classnames pairs of replaced and substituted 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class names. 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @exception RuntimeCopyException if a <code>BadBytecode</code> 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * exception is thrown, it is 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * converted into 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>RuntimeCopyException</code>. 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return <code>CodeAttribute</code> object. 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public AttributeInfo copy(ConstPool newCp, Map classnames) 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws RuntimeCopyException 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new CodeAttribute(newCp, this, classnames); 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (BadBytecode e) { 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new RuntimeCopyException("bad bytecode. fatal?"); 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * An exception that may be thrown by <code>copy()</code> 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * in <code>CodeAttribute</code>. 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class RuntimeCopyException extends RuntimeException { 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs an exception. 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public RuntimeCopyException(String s) { 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(s); 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the length of this <code>attribute_info</code> 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The returned value is <code>attribute_length + 6</code>. 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int length() { 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return 18 + info.length + exceptions.size() * 8 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + AttributeInfo.getLength(attributes); 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void write(DataOutputStream out) throws IOException { 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(name); // attribute_name_index 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeInt(length() - 6); // attribute_length 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(maxStack); // max_stack 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(maxLocals); // max_locals 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeInt(info.length); // code_length 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.write(info); // code 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exceptions.write(out); 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(attributes.size()); // attributes_count 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo.writeAll(attributes, out); // attributes 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This method is not available. 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws java.lang.UnsupportedOperationException always thrown. 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public byte[] get() { 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new UnsupportedOperationException("CodeAttribute.get()"); 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This method is not available. 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws java.lang.UnsupportedOperationException always thrown. 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void set(byte[] newinfo) { 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new UnsupportedOperationException("CodeAttribute.set()"); 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void renameClass(String oldname, String newname) { 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo.renameClass(attributes, oldname, newname); 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void renameClass(Map classnames) { 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo.renameClass(attributes, classnames); 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void getRefClasses(Map classnames) { 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo.getRefClasses(attributes, classnames); 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the name of the class declaring the method including 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * this code attribute. 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getDeclaringClass() { 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPool cp = getConstPool(); 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cp.getClassName(); 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>max_stack</code>. 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getMaxStack() { 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return maxStack; 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets <code>max_stack</code>. 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setMaxStack(int value) { 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxStack = value; 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Computes the maximum stack size and sets <code>max_stack</code> 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the computed size. 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws BadBytecode if this method fails in computing. 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the newly computed value of <code>max_stack</code> 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int computeMaxStack() throws BadBytecode { 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxStack = new CodeAnalyzer(this).computeMaxStack(); 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return maxStack; 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>max_locals</code>. 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getMaxLocals() { 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return maxLocals; 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets <code>max_locals</code>. 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setMaxLocals(int value) { 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxLocals = value; 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>code_length</code>. 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getCodeLength() { 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return info.length; 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>code[]</code>. 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public byte[] getCode() { 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return info; 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets <code>code[]</code>. 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void setCode(byte[] newinfo) { super.set(newinfo); } 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes a new iterator for reading this code attribute. 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CodeIterator iterator() { 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new CodeIterator(this); 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>exception_table[]</code>. 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ExceptionTable getExceptionTable() { return exceptions; } 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>attributes[]</code>. 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It returns a list of <code>AttributeInfo</code>. 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A new element can be added to the returned list 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and an existing element can be removed from the list. 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see AttributeInfo 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public List getAttributes() { return attributes; } 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the attribute with the specified name. 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If it is not found, this method returns null. 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name attribute name 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return an <code>AttributeInfo</code> object or null. 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public AttributeInfo getAttribute(String name) { 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return AttributeInfo.lookup(attributes, name); 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a stack map table. If another copy of stack map table 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is already contained, the old one is removed. 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param smt the stack map table added to this code attribute. 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If it is null, a new stack map is not added. 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Only the old stack map is removed. 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setAttribute(StackMapTable smt) { 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo.remove(attributes, StackMapTable.tag); 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (smt != null) 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes.add(smt); 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a stack map table for J2ME (CLDC). If another copy of stack map table 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is already contained, the old one is removed. 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param sm the stack map table added to this code attribute. 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If it is null, a new stack map is not added. 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Only the old stack map is removed. 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.12 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setAttribute(StackMap sm) { 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AttributeInfo.remove(attributes, StackMap.tag); 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (sm != null) 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal attributes.add(sm); 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copies code. 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private byte[] copyCode(ConstPool destCp, Map classnames, 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ExceptionTable etable, CodeAttribute destCa) 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int len = getCodeLength(); 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] newCode = new byte[len]; 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal destCa.info = newCode; 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal LdcEntry ldc = copyCode(this.info, 0, len, this.getConstPool(), 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newCode, destCp, classnames); 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return LdcEntry.doit(newCode, ldc, etable, destCa); 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static LdcEntry copyCode(byte[] code, int beginPos, int endPos, 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPool srcCp, byte[] newcode, 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPool destCp, Map classnameMap) 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i2, index; 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal LdcEntry ldcEntry = null; 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = beginPos; i < endPos; i = i2) { 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal i2 = CodeIterator.nextOpcode(code, i); 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte c = code[i]; 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i] = c; 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (c & 0xff) { 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case LDC_W : 36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case LDC2_W : 36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case GETSTATIC : 36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case PUTSTATIC : 36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case GETFIELD : 37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case PUTFIELD : 37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKEVIRTUAL : 37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKESPECIAL : 37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKESTATIC : 37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case NEW : 37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case ANEWARRAY : 37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case CHECKCAST : 37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INSTANCEOF : 37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, 37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classnameMap); 38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case LDC : 38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = code[i + 1] & 0xff; 38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = srcCp.copy(index, destCp, classnameMap); 38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (index < 0x100) 38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i + 1] = (byte)index; 38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i] = NOP; 38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i + 1] = NOP; 38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal LdcEntry ldc = new LdcEntry(); 39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ldc.where = i; 39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ldc.index = index; 39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ldc.next = ldcEntry; 39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ldcEntry = ldc; 39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKEINTERFACE : 39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, 39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classnameMap); 39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i + 3] = code[i + 3]; 40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i + 4] = code[i + 4]; 40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case MULTIANEWARRAY : 40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, 40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classnameMap); 40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i + 3] = code[i + 3]; 40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal default : 40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (++i < i2) 40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i] = code[i]; 41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return ldcEntry; 41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void copyConstPoolInfo(int i, byte[] code, ConstPool srcCp, 41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] newcode, ConstPool destCp, 42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Map classnameMap) { 42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = ((code[i] & 0xff) << 8) | (code[i + 1] & 0xff); 42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = srcCp.copy(index, destCp, classnameMap); 42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i] = (byte)(index >> 8); 42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newcode[i + 1] = (byte)index; 42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static class LdcEntry { 42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal LdcEntry next; 42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int where; 43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index; 43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static byte[] doit(byte[] code, LdcEntry ldc, ExceptionTable etable, 43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CodeAttribute ca) 43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (ldc != null) 43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal code = CodeIterator.changeLdcToLdcW(code, etable, ca, ldc); 43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* The original code was the following: 44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (ldc != null) { 44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int where = ldc.where; 44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal code = CodeIterator.insertGapCore0(code, where, 1, false, etable, ca); 44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal code[where] = (byte)Opcode.LDC_W; 44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArray.write16bit(ldc.index, code, where + 1); 44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ldc = ldc.next; 44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal But this code does not support a large method > 32KB. 45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return code; 45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Changes the index numbers of the local variables 45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to append a new parameter. 45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This method does not update <code>LocalVariableAttribute</code>, 46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>StackMapTable</code>, or <code>StackMap</code>. 46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * These attributes must be explicitly updated. 46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param where the index of the new parameter. 46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param size the type size of the new parameter (1 or 2). 46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see LocalVariableAttribute#shiftIndex(int, int) 46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see StackMapTable#insertLocal(int, int, int) 46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see StackMap#insertLocal(int, int, int) 46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void insertLocalVar(int where, int size) throws BadBytecode { 47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CodeIterator ci = iterator(); 47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (ci.hasNext()) 47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal shiftIndex(ci, where, size); 47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal setMaxLocals(getMaxLocals() + size); 47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param lessThan If the index of the local variable is 48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * less than this value, it does not change. 48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Otherwise, the index is increased. 48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param delta the indexes of the local variables are 48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * increased by this value. 48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void shiftIndex(CodeIterator ci, int lessThan, int delta) throws BadBytecode { 48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = ci.next(); 48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int opcode = ci.byteAt(index); 48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (opcode < ILOAD) 48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode < IASTORE) { 49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (opcode < ILOAD_0) { 49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // iload, lload, fload, dload, aload 49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal shiftIndex8(ci, index, opcode, lessThan, delta); 49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode < IALOAD) { 49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // iload_0, ..., aload_3 49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal shiftIndex0(ci, index, opcode, lessThan, delta, ILOAD_0, ILOAD); 49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode < ISTORE) 50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode < ISTORE_0) { 50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // istore, lstore, ... 50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal shiftIndex8(ci, index, opcode, lessThan, delta); 50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // istore_0, ..., astore_3 50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal shiftIndex0(ci, index, opcode, lessThan, delta, ISTORE_0, ISTORE); 50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode == IINC) { 51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int var = ci.byteAt(index + 1); 51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < lessThan) 51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal var += delta; 51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < 0x100) 51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(var, index + 1); 51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int plus = (byte)ci.byteAt(index + 2); 52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int pos = ci.insertExGap(3); 52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(WIDE, pos - 3); 52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(IINC, pos - 2); 52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.write16bit(var, pos - 1); 52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.write16bit(plus, pos + 1); 52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode == RET) 52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal shiftIndex8(ci, index, opcode, lessThan, delta); 52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (opcode == WIDE) { 53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int var = ci.u16bitAt(index + 2); 53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < lessThan) 53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal var += delta; 53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.write16bit(var, index + 2); 53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void shiftIndex8(CodeIterator ci, int index, int opcode, 54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int lessThan, int delta) 54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int var = ci.byteAt(index + 1); 54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < lessThan) 54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal var += delta; 54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < 0x100) 54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(var, index + 1); 55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int pos = ci.insertExGap(2); 55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(WIDE, pos - 2); 55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(opcode, pos - 1); 55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.write16bit(var, pos); 55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void shiftIndex0(CodeIterator ci, int index, int opcode, 55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int lessThan, int delta, 56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int opcode_i_0, int opcode_i) 56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int var = (opcode - opcode_i_0) % 4; 56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < lessThan) 56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal var += delta; 56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < 4) 56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(opcode + delta, index); 57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal opcode = (opcode - opcode_i_0) / 4 + opcode_i; 57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (var < 0x100) { 57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int pos = ci.insertExGap(1); 57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(opcode, pos - 1); 57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(var, pos); 57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int pos = ci.insertExGap(3); 57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(WIDE, pos - 1); 58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.writeByte(opcode, pos); 58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.write16bit(var, pos + 1); 58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 586