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 /** 28 * GOTO - Branch always (to relative offset, not absolute address) 29 * 30 */ 31 public class GOTO extends GotoInstruction implements VariableLengthInstruction { 32 33 /** 34 * Empty constructor needed for Instruction.readInstruction. 35 * Not to be used otherwise. 36 */ GOTO()37 GOTO() { 38 } 39 40 GOTO(final InstructionHandle target)41 public GOTO(final InstructionHandle target) { 42 super(com.sun.org.apache.bcel.internal.Const.GOTO, target); 43 } 44 45 46 /** 47 * Dump instruction as byte code to stream out. 48 * @param out Output stream 49 */ 50 @Override dump( final DataOutputStream out )51 public void dump( final DataOutputStream out ) throws IOException { 52 super.setIndex(getTargetOffset()); 53 final short _opcode = getOpcode(); 54 if (_opcode == com.sun.org.apache.bcel.internal.Const.GOTO) { 55 super.dump(out); 56 } else { // GOTO_W 57 super.setIndex(getTargetOffset()); 58 out.writeByte(_opcode); 59 out.writeInt(super.getIndex()); 60 } 61 } 62 63 64 /** 65 * Called in pass 2 of InstructionList.setPositions() in order to update 66 * the branch target, that may shift due to variable length instructions. 67 * 68 * @param offset additional offset caused by preceding (variable length) instructions 69 * @param max_offset the maximum offset that may be caused by these instructions 70 * @return additional offset caused by possible change of this instruction's length 71 */ 72 @Override updatePosition( final int offset, final int max_offset )73 protected int updatePosition( final int offset, final int max_offset ) { 74 final int i = getTargetOffset(); // Depending on old position value 75 setPosition(getPosition() + offset); // Position may be shifted by preceding expansions 76 if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) 77 super.setOpcode(com.sun.org.apache.bcel.internal.Const.GOTO_W); 78 final short old_length = (short) super.getLength(); 79 super.setLength(5); 80 return super.getLength() - old_length; 81 } 82 return 0; 83 } 84 85 86 /** 87 * Call corresponding visitor method(s). The order is: 88 * Call visitor methods of implemented interfaces first, then 89 * call methods according to the class hierarchy in descending order, 90 * i.e., the most specific visitXXX() call comes last. 91 * 92 * @param v Visitor object 93 */ 94 @Override accept( final Visitor v )95 public void accept( final Visitor v ) { 96 v.visitVariableLengthInstruction(this); 97 v.visitUnconditionalBranch(this); 98 v.visitBranchInstruction(this); 99 v.visitGotoInstruction(this); 100 v.visitGOTO(this); 101 } 102 } 103