001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.generic; 019 020import java.io.DataOutputStream; 021import java.io.IOException; 022 023import org.apache.bcel.util.ByteSequence; 024 025/** 026 * IINC - Increment local variable by constant 027 * 028 * @version $Id: IINC.java 1747278 2016-06-07 17:28:43Z britter $ 029 */ 030public class IINC extends LocalVariableInstruction { 031 032 private boolean wide; 033 private int c; 034 035 036 /** 037 * Empty constructor needed for the Class.newInstance() statement in 038 * Instruction.readInstruction(). Not to be used otherwise. 039 */ 040 IINC() { 041 } 042 043 044 /** 045 * @param n index of local variable 046 * @param c increment factor 047 */ 048 public IINC(final int n, final int c) { 049 super(); // Default behaviour of LocalVariableInstruction causes error 050 super.setOpcode(org.apache.bcel.Const.IINC); 051 super.setLength((short) 3); 052 setIndex(n); // May set wide as side effect 053 setIncrement(c); 054 } 055 056 057 /** 058 * Dump instruction as byte code to stream out. 059 * @param out Output stream 060 */ 061 @Override 062 public void dump( final DataOutputStream out ) throws IOException { 063 if (wide) { 064 out.writeByte(org.apache.bcel.Const.WIDE); 065 } 066 out.writeByte(super.getOpcode()); 067 if (wide) { 068 out.writeShort(super.getIndex()); 069 out.writeShort(c); 070 } else { 071 out.writeByte(super.getIndex()); 072 out.writeByte(c); 073 } 074 } 075 076 077 private void setWide() { 078 wide = (super.getIndex() > org.apache.bcel.Const.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE); 079 if (wide) { 080 super.setLength(6); // wide byte included 081 } else { 082 super.setLength(3); 083 } 084 } 085 086 087 /** 088 * Read needed data (e.g. index) from file. 089 */ 090 @Override 091 protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { 092 this.wide = wide; 093 if (wide) { 094 super.setLength(6); 095 super.setIndexOnly(bytes.readUnsignedShort()); 096 c = bytes.readShort(); 097 } else { 098 super.setLength(3); 099 super.setIndexOnly(bytes.readUnsignedByte()); 100 c = bytes.readByte(); 101 } 102 } 103 104 105 /** 106 * @return mnemonic for instruction 107 */ 108 @Override 109 public String toString( final boolean verbose ) { 110 return super.toString(verbose) + " " + c; 111 } 112 113 114 /** 115 * Set index of local variable. 116 */ 117 @Override 118 public final void setIndex( final int n ) { 119 if (n < 0) { 120 throw new ClassGenException("Negative index value: " + n); 121 } 122 super.setIndexOnly(n); 123 setWide(); 124 } 125 126 127 /** 128 * @return increment factor 129 */ 130 public final int getIncrement() { 131 return c; 132 } 133 134 135 /** 136 * Set increment factor. 137 */ 138 public final void setIncrement( final int c ) { 139 this.c = c; 140 setWide(); 141 } 142 143 144 /** @return int type 145 */ 146 @Override 147 public Type getType( final ConstantPoolGen cp ) { 148 return Type.INT; 149 } 150 151 152 /** 153 * Call corresponding visitor method(s). The order is: 154 * Call visitor methods of implemented interfaces first, then 155 * call methods according to the class hierarchy in descending order, 156 * i.e., the most specific visitXXX() call comes last. 157 * 158 * @param v Visitor object 159 */ 160 @Override 161 public void accept( final Visitor v ) { 162 v.visitLocalVariableInstruction(this); 163 v.visitIINC(this); 164 } 165}