summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java')
-rw-r--r--src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java151
1 files changed, 0 insertions, 151 deletions
diff --git a/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java b/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java
deleted file mode 100644
index fc2bac3..0000000
--- a/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java
+++ /dev/null
@@ -1,151 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.bytecode;
12
13import java.util.Iterator;
14
15import javassist.bytecode.BadBytecode;
16import javassist.bytecode.Bytecode;
17import javassist.bytecode.CodeAttribute;
18import javassist.bytecode.CodeIterator;
19import javassist.bytecode.Opcode;
20
21public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Index> {
22
23 public static class Index {
24
25 private CodeIterator m_iter;
26 private int m_pos;
27 private boolean m_isWide;
28
29 protected Index(CodeIterator iter, int pos, boolean isWide) {
30 m_iter = iter;
31 m_pos = pos;
32 m_isWide = isWide;
33 }
34
35 public int getIndex() {
36 if (m_isWide) {
37 return m_iter.s16bitAt(m_pos);
38 } else {
39 return m_iter.byteAt(m_pos);
40 }
41 }
42
43 public void setIndex(int val) throws BadBytecode {
44 if (m_isWide) {
45 m_iter.write16bit(val, m_pos);
46 } else {
47 if (val < 256) {
48 // we can write the byte
49 m_iter.writeByte(val, m_pos);
50 } else {
51 // we need to upgrade this instruction to LDC_W
52 assert (m_iter.byteAt(m_pos - 1) == Opcode.LDC);
53 m_iter.insertGap(m_pos - 1, 1);
54 m_iter.writeByte(Opcode.LDC_W, m_pos - 1);
55 m_iter.write16bit(val, m_pos);
56 m_isWide = true;
57
58 // move the iterator to the next opcode
59 m_iter.move(m_pos + 2);
60 }
61 }
62
63 // sanity check
64 assert (val == getIndex());
65 }
66
67 public boolean isValid(Bytecode bytecode) {
68 return getIndex() >= 0 && getIndex() < bytecode.getConstPool().getSize();
69 }
70 }
71
72 private Bytecode m_bytecode;
73 private CodeAttribute m_attribute;
74 private CodeIterator m_iter;
75 private Index m_next;
76
77 public BytecodeIndexIterator(Bytecode bytecode) throws BadBytecode {
78 m_bytecode = bytecode;
79 m_attribute = bytecode.toCodeAttribute();
80 m_iter = m_attribute.iterator();
81
82 m_next = getNext();
83 }
84
85 @Override
86 public boolean hasNext() {
87 return m_next != null;
88 }
89
90 @Override
91 public Index next() {
92 Index out = m_next;
93 try {
94 m_next = getNext();
95 } catch (BadBytecode ex) {
96 throw new Error(ex);
97 }
98 return out;
99 }
100
101 @Override
102 public void remove() {
103 throw new UnsupportedOperationException();
104 }
105
106 private Index getNext() throws BadBytecode {
107 while (m_iter.hasNext()) {
108 int pos = m_iter.next();
109 int opcode = m_iter.byteAt(pos);
110 switch (opcode) {
111
112 // for only these opcodes, the next two bytes are a const pool reference
113 case Opcode.ANEWARRAY:
114 case Opcode.CHECKCAST:
115 case Opcode.INSTANCEOF:
116 case Opcode.INVOKEDYNAMIC:
117 case Opcode.INVOKEINTERFACE:
118 case Opcode.INVOKESPECIAL:
119 case Opcode.INVOKESTATIC:
120 case Opcode.INVOKEVIRTUAL:
121 case Opcode.LDC_W:
122 case Opcode.LDC2_W:
123 case Opcode.MULTIANEWARRAY:
124 case Opcode.NEW:
125 case Opcode.PUTFIELD:
126 case Opcode.PUTSTATIC:
127 case Opcode.GETFIELD:
128 case Opcode.GETSTATIC:
129 return new Index(m_iter, pos + 1, true);
130
131 case Opcode.LDC:
132 return new Index(m_iter, pos + 1, false);
133 }
134 }
135
136 return null;
137 }
138
139 public Iterable<Index> indices() {
140 return new Iterable<Index>() {
141 @Override
142 public Iterator<Index> iterator() {
143 return BytecodeIndexIterator.this;
144 }
145 };
146 }
147
148 public void saveChangesToBytecode() {
149 BytecodeTools.setBytecode(m_bytecode, m_attribute.getCode());
150 }
151}