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: package org.apache.harmony.pack200.bytecode.forms;
018:
019: /**
020: * This abstract class implements the common code for
021: * instructions which have variable lengths. This
022: * is currently the *switch instructions and some
023: * wide (_w) instructions.
024: */
025: public abstract class VariableInstructionForm extends ByteCodeForm {
026:
027: public VariableInstructionForm(int opcode, String name) {
028: super (opcode, name);
029: }
030:
031: public VariableInstructionForm(int opcode, String name,
032: int[] rewrite) {
033: super (opcode, name, rewrite);
034: }
035:
036: /**
037: * Given an int operand, set the rewrite bytes for
038: * the next available operand position and the three
039: * immediately following it to a highest-byte,
040: * mid-high, mid-low, low-byte encoding of the operand.
041: *
042: * Note that unlike the ByteCode setOperand* operations, this
043: * starts with an actual bytecode rewrite array (rather than
044: * a ByteCodeForm prototype rewrite array). Also, this method
045: * overwrites -1 values in the rewrite array - so if you start
046: * with an array that looks like:
047: * {100, -1, -1, -1, -1, 200, -1, -1, -1, -1} then calling
048: * setRewrite4Bytes(0, rewrite) the first time will convert
049: * it to:
050: * {100, 0, 0, 0, 0, 200, -1, -1, -1, -1}
051: * Calling setRewrite4Bytes(0, rewrite) a second time will
052: * convert it to:
053: * {100, 0, 0, 0, 0, 200, 0, 0, 0, 0}
054: *
055: * @param operand int to set the rewrite bytes to
056: * @param rewrite int[] bytes to rewrite
057: */
058: public void setRewrite4Bytes(int operand, int[] rewrite) {
059: int firstOperandPosition = -1;
060:
061: // Find the first -1 in the rewrite array
062: for (int index = 0; index < rewrite.length - 3; index++) {
063: if ((rewrite[index] == -1) && (rewrite[index + 1] == -1)
064: && (rewrite[index + 2] == -1)
065: && (rewrite[index + 3] == -1)) {
066: firstOperandPosition = index;
067: break;
068: }
069: }
070: setRewrite4Bytes(operand, firstOperandPosition, rewrite);
071: }
072:
073: /**
074: * Given an int operand, set the rewrite bytes for
075: * the next available operand position and the byte
076: * immediately following it to a high-byte,
077: * low-byte encoding of the operand.
078: *
079: * Note that unlike the ByteCode setOperand* operations, this
080: * starts with an actual bytecode rewrite array (rather than
081: * a ByteCodeForm prototype rewrite array). Also, this method
082: * overwrites -1 values in the rewrite array - so if you start
083: * with an array that looks like:
084: * {100, -1, -1, -1, -1, 200, -1, -1, -1, -1} then calling
085: * setRewrite2Bytes(0, rewrite) the first time will convert
086: * it to:
087: * {100, 0, 0, -1, -1, 200, -1, -1, -1, -1}
088: * Calling setRewrite2Bytes(0, rewrite) a second time will
089: * convert it to:
090: * {100, 0, 0, 0, 0, 200, -1, -1, -1, -1}
091: *
092: * @param operand int to set the rewrite bytes to
093: * @param rewrite int[] bytes to rewrite
094: */
095: public void setRewrite2Bytes(int operand, int[] rewrite) {
096: int firstOperandPosition = -1;
097:
098: // Find the first -1 in the rewrite array
099: for (int index = 0; index < rewrite.length - 3; index++) {
100: if ((rewrite[index] == -1) && (rewrite[index + 1] == -1)) {
101: firstOperandPosition = index;
102: break;
103: }
104: }
105: setRewrite2Bytes(operand, firstOperandPosition, rewrite);
106: }
107:
108: /**
109: * This method writes operand directly into the rewrite
110: * array at index position specified.
111: * @param operand value to write
112: * @param absPosition position in array to write. Note that
113: * this is absolute position in the array, so one can
114: * overwrite the bytecode if one isn't careful.
115: * @param rewrite array to write into
116: */
117: public void setRewrite4Bytes(int operand, int absPosition,
118: int[] rewrite) {
119: if (absPosition < 0) {
120: throw new Error("Trying to rewrite " + this
121: + " but there is no room for 4 bytes");
122: }
123:
124: int byteCodeRewriteLength = rewrite.length;
125:
126: if (absPosition + 3 > byteCodeRewriteLength) {
127: throw new Error("Trying to rewrite " + this
128: + " with an int at position " + absPosition
129: + " but this won't fit in the rewrite array");
130: }
131:
132: rewrite[absPosition] = ((0xFF000000) & operand) >> 24;
133: rewrite[absPosition + 1] = ((0x00FF0000) & operand) >> 16;
134: rewrite[absPosition + 2] = ((0x0000FF00) & operand) >> 8;
135: rewrite[absPosition + 3] = ((0x000000FF) & operand);
136: }
137:
138: /**
139: * This method writes operand directly into the rewrite
140: * array at index position specified.
141: * @param operand value to write
142: * @param absPosition position in array to write. Note that
143: * this is absolute position in the array, so one can
144: * overwrite the bytecode if one isn't careful.
145: * @param rewrite array to write into
146: */
147: public void setRewrite2Bytes(int operand, int absPosition,
148: int[] rewrite) {
149: if (absPosition < 0) {
150: throw new Error("Trying to rewrite " + this
151: + " but there is no room for 4 bytes");
152: }
153:
154: int byteCodeRewriteLength = rewrite.length;
155:
156: if (absPosition + 1 > byteCodeRewriteLength) {
157: throw new Error("Trying to rewrite " + this
158: + " with an int at position " + absPosition
159: + " but this won't fit in the rewrite array");
160: }
161:
162: rewrite[absPosition] = ((0xFF00) & operand) >> 8;
163: rewrite[absPosition + 1] = ((0x00FF) & operand);
164: }
165: }
|