1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.bcel.internal.generic; 23 24 import java.io.DataOutputStream; 25 import java.io.IOException; 26 27 import com.sun.org.apache.bcel.internal.util.ByteSequence; 28 29 /** 30 * IINC - Increment local variable by constant 31 * 32 */ 33 public class IINC extends LocalVariableInstruction { 34 35 private boolean wide; 36 private int c; 37 38 39 /** 40 * Empty constructor needed for Instruction.readInstruction. 41 * Not to be used otherwise. 42 */ IINC()43 IINC() { 44 } 45 46 47 /** 48 * @param n index of local variable 49 * @param c increment factor 50 */ IINC(final int n, final int c)51 public IINC(final int n, final int c) { 52 super(); // Default behavior of LocalVariableInstruction causes error 53 super.setOpcode(com.sun.org.apache.bcel.internal.Const.IINC); 54 super.setLength((short) 3); 55 setIndex(n); // May set wide as side effect 56 setIncrement(c); 57 } 58 59 60 /** 61 * Dump instruction as byte code to stream out. 62 * @param out Output stream 63 */ 64 @Override dump( final DataOutputStream out )65 public void dump( final DataOutputStream out ) throws IOException { 66 if (wide) { 67 out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); 68 } 69 out.writeByte(super.getOpcode()); 70 if (wide) { 71 out.writeShort(super.getIndex()); 72 out.writeShort(c); 73 } else { 74 out.writeByte(super.getIndex()); 75 out.writeByte(c); 76 } 77 } 78 79 setWide()80 private void setWide() { 81 wide = super.getIndex() > com.sun.org.apache.bcel.internal.Const.MAX_BYTE; 82 if (c > 0) { 83 wide = wide || (c > Byte.MAX_VALUE); 84 } else { 85 wide = wide || (c < Byte.MIN_VALUE); 86 } 87 if (wide) { 88 super.setLength(6); // wide byte included 89 } else { 90 super.setLength(3); 91 } 92 } 93 94 95 /** 96 * Read needed data (e.g. index) from file. 97 */ 98 @Override initFromFile( final ByteSequence bytes, final boolean wide )99 protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { 100 this.wide = wide; 101 if (wide) { 102 super.setLength(6); 103 super.setIndexOnly(bytes.readUnsignedShort()); 104 c = bytes.readShort(); 105 } else { 106 super.setLength(3); 107 super.setIndexOnly(bytes.readUnsignedByte()); 108 c = bytes.readByte(); 109 } 110 } 111 112 113 /** 114 * @return mnemonic for instruction 115 */ 116 @Override toString( final boolean verbose )117 public String toString( final boolean verbose ) { 118 return super.toString(verbose) + " " + c; 119 } 120 121 122 /** 123 * Set index of local variable. 124 */ 125 @Override setIndex( final int n )126 public final void setIndex( final int n ) { 127 if (n < 0) { 128 throw new ClassGenException("Negative index value: " + n); 129 } 130 super.setIndexOnly(n); 131 setWide(); 132 } 133 134 135 /** 136 * @return increment factor 137 */ getIncrement()138 public final int getIncrement() { 139 return c; 140 } 141 142 143 /** 144 * Set increment factor. 145 */ setIncrement( final int c )146 public final void setIncrement( final int c ) { 147 this.c = c; 148 setWide(); 149 } 150 151 152 /** @return int type 153 */ 154 @Override getType( final ConstantPoolGen cp )155 public Type getType( final ConstantPoolGen cp ) { 156 return Type.INT; 157 } 158 159 160 /** 161 * Call corresponding visitor method(s). The order is: 162 * Call visitor methods of implemented interfaces first, then 163 * call methods according to the class hierarchy in descending order, 164 * i.e., the most specific visitXXX() call comes last. 165 * 166 * @param v Visitor object 167 */ 168 @Override accept( final Visitor v )169 public void accept( final Visitor v ) { 170 v.visitLocalVariableInstruction(this); 171 v.visitIINC(this); 172 } 173 } 174