diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2008-05-01 10:47:59 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2008-05-01 10:47:59 +0000 |
commit | 664bfcc3db3aa02fb9abfc799de8ff274dd6f1da (patch) | |
tree | 64a85bb9d98e954262f9608ce64f7a1e005cd89d /src/main/javassist/bytecode/CodeAttribute.java | |
parent | bd6d4dcb4cc5a68c9c4d79d640567fd8b5cd8279 (diff) | |
download | javassist-664bfcc3db3aa02fb9abfc799de8ff274dd6f1da.tar.gz javassist-664bfcc3db3aa02fb9abfc799de8ff274dd6f1da.zip |
fixed JASSIST-47 and 60.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@435 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/bytecode/CodeAttribute.java')
-rw-r--r-- | src/main/javassist/bytecode/CodeAttribute.java | 159 |
1 files changed, 144 insertions, 15 deletions
diff --git a/src/main/javassist/bytecode/CodeAttribute.java b/src/main/javassist/bytecode/CodeAttribute.java index 35ab7ddd..f3ae8a1b 100644 --- a/src/main/javassist/bytecode/CodeAttribute.java +++ b/src/main/javassist/bytecode/CodeAttribute.java @@ -395,25 +395,154 @@ public class CodeAttribute extends AttributeInfo implements Opcode { newcode[i] = (byte)(index >> 8); newcode[i + 1] = (byte)index; } -} -final class LdcEntry { - LdcEntry next; - int where; - int index; + static class LdcEntry { + LdcEntry next; + int where; + int index; + + static byte[] doit(byte[] code, LdcEntry ldc, ExceptionTable etable, + CodeAttribute ca) + throws BadBytecode + { + while (ldc != null) { + int where = ldc.where; + code = CodeIterator.insertGap(code, where, 1, false, etable, ca); + code[where] = (byte)Opcode.LDC_W; + ByteArray.write16bit(ldc.index, code, where + 1); + ldc = ldc.next; + } - static byte[] doit(byte[] code, LdcEntry ldc, ExceptionTable etable, - CodeAttribute ca) - throws BadBytecode + return code; + } + } + + /** + * Changes the index numbers of the local variables + * to append a new parameter. + * This method does not update <code>LocalVariableAttribute</code> + * or <code>StackMapTable</code>. These attributes must be + * explicitly updated. + * + * @param where the index of the new parameter. + * @param size the type size of the new parameter (1 or 2). + * + * @see LocalVariableAttribute#shiftIndex(int, int) + * @see StackMapTable#insertLocal(int, int, int) + */ + public void insertLocalVar(int where, int size) throws BadBytecode { + CodeIterator ci = iterator(); + while (ci.hasNext()) + shiftIndex(ci, where, size); + + setMaxLocals(getMaxLocals() + size); + } + + /** + * @param lessThan If the index of the local variable is + * less than this value, it does not change. + * Otherwise, the index is increased. + * @param delta the indexes of the local variables are + * increased by this value. + */ + private static void shiftIndex(CodeIterator ci, int lessThan, int delta) throws BadBytecode { + int index = ci.next(); + int opcode = ci.byteAt(index); + if (opcode < ILOAD) + return; + else if (opcode < IASTORE) { + if (opcode < ILOAD_0) { + // iload, lload, fload, dload, aload + shiftIndex8(ci, index, opcode, lessThan, delta); + } + else if (opcode < IALOAD) { + // iload_0, ..., aload_3 + shiftIndex0(ci, index, opcode, lessThan, delta, ILOAD_0, ILOAD); + } + else if (opcode < ISTORE) + return; + else if (opcode < ISTORE_0) { + // istore, lstore, ... + shiftIndex8(ci, index, opcode, lessThan, delta); + } + else { + // istore_0, ..., astore_3 + shiftIndex0(ci, index, opcode, lessThan, delta, ISTORE_0, ISTORE); + } + } + else if (opcode == IINC) { + int var = ci.byteAt(index + 1); + if (var < lessThan) + return; + + var += delta; + if (var < 0x100) + ci.writeByte(var, index + 1); + else { + int plus = ci.byteAt(index + 2); + ci.insertExGap(3); + ci.writeByte(WIDE, index); + ci.writeByte(IINC, index + 1); + ci.write16bit(var, index + 2); + ci.write16bit(plus, index + 4); + } + } + else if (opcode == RET) + shiftIndex8(ci, index, opcode, lessThan, delta); + else if (opcode == WIDE) { + int var = ci.u16bitAt(index + 2); + if (var < lessThan) + return; + + var += delta; + ci.write16bit(var, index + 2); + } + } + + private static void shiftIndex8(CodeIterator ci, int index, int opcode, + int lessThan, int delta) + throws BadBytecode { - while (ldc != null) { - int where = ldc.where; - code = CodeIterator.insertGap(code, where, 1, false, etable, ca); - code[where] = (byte)Opcode.LDC_W; - ByteArray.write16bit(ldc.index, code, where + 1); - ldc = ldc.next; + int var = ci.byteAt(index + 1); + if (var < lessThan) + return; + + var += delta; + if (var < 0x100) + ci.writeByte(var, index + 1); + else { + ci.insertExGap(2); + ci.writeByte(WIDE, index); + ci.writeByte(opcode, index + 1); + ci.write16bit(var, index + 2); } + } - return code; + private static void shiftIndex0(CodeIterator ci, int index, int opcode, + int lessThan, int delta, + int opcode_i_0, int opcode_i) + throws BadBytecode + { + int var = (opcode - opcode_i_0) % 4; + if (var < lessThan) + return; + + var += delta; + if (var < 4) + ci.writeByte(opcode + delta, index); + else { + opcode = (opcode - opcode_i_0) / 4 + opcode_i; + if (var < 0x100) { + ci.insertExGap(1); + ci.writeByte(opcode, index); + ci.writeByte(var, index + 1); + } + else { + ci.insertExGap(3); + ci.writeByte(WIDE, index); + ci.writeByte(opcode, index + 1); + ci.write16bit(var, index + 2); + } + } } } |