summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/bytecode')
-rw-r--r--src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java121
-rw-r--r--src/cuchaz/enigma/bytecode/BytecodeTools.java269
-rw-r--r--src/cuchaz/enigma/bytecode/CheckCastIterator.java98
-rw-r--r--src/cuchaz/enigma/bytecode/ClassRenamer.java103
-rw-r--r--src/cuchaz/enigma/bytecode/ClassTranslator.java104
-rw-r--r--src/cuchaz/enigma/bytecode/ConstPoolEditor.java295
-rw-r--r--src/cuchaz/enigma/bytecode/InfoType.java347
-rw-r--r--src/cuchaz/enigma/bytecode/InnerClassWriter.java103
-rw-r--r--src/cuchaz/enigma/bytecode/MethodParameterWriter.java47
-rw-r--r--src/cuchaz/enigma/bytecode/MethodParametersAttribute.java65
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java58
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java181
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java90
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java90
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java90
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java58
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java90
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java58
-rw-r--r--src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java23
19 files changed, 920 insertions, 1370 deletions
diff --git a/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java b/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java
index aadbeb2..fc2bac3 100644
--- a/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java
+++ b/src/cuchaz/enigma/bytecode/BytecodeIndexIterator.java
@@ -18,67 +18,53 @@ import javassist.bytecode.CodeAttribute;
18import javassist.bytecode.CodeIterator; 18import javassist.bytecode.CodeIterator;
19import javassist.bytecode.Opcode; 19import javassist.bytecode.Opcode;
20 20
21public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Index> 21public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Index> {
22{ 22
23 public static class Index 23 public static class Index {
24 { 24
25 private CodeIterator m_iter; 25 private CodeIterator m_iter;
26 private int m_pos; 26 private int m_pos;
27 private boolean m_isWide; 27 private boolean m_isWide;
28 28
29 protected Index( CodeIterator iter, int pos, boolean isWide ) 29 protected Index(CodeIterator iter, int pos, boolean isWide) {
30 {
31 m_iter = iter; 30 m_iter = iter;
32 m_pos = pos; 31 m_pos = pos;
33 m_isWide = isWide; 32 m_isWide = isWide;
34 } 33 }
35 34
36 public int getIndex( ) 35 public int getIndex() {
37 { 36 if (m_isWide) {
38 if( m_isWide ) 37 return m_iter.s16bitAt(m_pos);
39 { 38 } else {
40 return m_iter.s16bitAt( m_pos ); 39 return m_iter.byteAt(m_pos);
41 }
42 else
43 {
44 return m_iter.byteAt( m_pos );
45 } 40 }
46 } 41 }
47 42
48 public void setIndex( int val ) 43 public void setIndex(int val) throws BadBytecode {
49 throws BadBytecode 44 if (m_isWide) {
50 { 45 m_iter.write16bit(val, m_pos);
51 if( m_isWide ) 46 } else {
52 { 47 if (val < 256) {
53 m_iter.write16bit( val, m_pos );
54 }
55 else
56 {
57 if( val < 256 )
58 {
59 // we can write the byte 48 // we can write the byte
60 m_iter.writeByte( val, m_pos ); 49 m_iter.writeByte(val, m_pos);
61 } 50 } else {
62 else
63 {
64 // we need to upgrade this instruction to LDC_W 51 // we need to upgrade this instruction to LDC_W
65 assert( m_iter.byteAt( m_pos - 1 ) == Opcode.LDC ); 52 assert (m_iter.byteAt(m_pos - 1) == Opcode.LDC);
66 m_iter.insertGap( m_pos - 1, 1 ); 53 m_iter.insertGap(m_pos - 1, 1);
67 m_iter.writeByte( Opcode.LDC_W, m_pos - 1 ); 54 m_iter.writeByte(Opcode.LDC_W, m_pos - 1);
68 m_iter.write16bit( val, m_pos ); 55 m_iter.write16bit(val, m_pos);
69 m_isWide = true; 56 m_isWide = true;
70 57
71 // move the iterator to the next opcode 58 // move the iterator to the next opcode
72 m_iter.move( m_pos + 2 ); 59 m_iter.move(m_pos + 2);
73 } 60 }
74 } 61 }
75 62
76 // sanity check 63 // sanity check
77 assert( val == getIndex() ); 64 assert (val == getIndex());
78 } 65 }
79 66
80 public boolean isValid( Bytecode bytecode ) 67 public boolean isValid(Bytecode bytecode) {
81 {
82 return getIndex() >= 0 && getIndex() < bytecode.getConstPool().getSize(); 68 return getIndex() >= 0 && getIndex() < bytecode.getConstPool().getSize();
83 } 69 }
84 } 70 }
@@ -88,9 +74,7 @@ public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Ind
88 private CodeIterator m_iter; 74 private CodeIterator m_iter;
89 private Index m_next; 75 private Index m_next;
90 76
91 public BytecodeIndexIterator( Bytecode bytecode ) 77 public BytecodeIndexIterator(Bytecode bytecode) throws BadBytecode {
92 throws BadBytecode
93 {
94 m_bytecode = bytecode; 78 m_bytecode = bytecode;
95 m_attribute = bytecode.toCodeAttribute(); 79 m_attribute = bytecode.toCodeAttribute();
96 m_iter = m_attribute.iterator(); 80 m_iter = m_attribute.iterator();
@@ -99,41 +83,32 @@ public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Ind
99 } 83 }
100 84
101 @Override 85 @Override
102 public boolean hasNext( ) 86 public boolean hasNext() {
103 {
104 return m_next != null; 87 return m_next != null;
105 } 88 }
106 89
107 @Override 90 @Override
108 public Index next( ) 91 public Index next() {
109 {
110 Index out = m_next; 92 Index out = m_next;
111 try 93 try {
112 {
113 m_next = getNext(); 94 m_next = getNext();
114 } 95 } catch (BadBytecode ex) {
115 catch( BadBytecode ex ) 96 throw new Error(ex);
116 {
117 throw new Error( ex );
118 } 97 }
119 return out; 98 return out;
120 } 99 }
121 100
122 @Override 101 @Override
123 public void remove( ) 102 public void remove() {
124 {
125 throw new UnsupportedOperationException(); 103 throw new UnsupportedOperationException();
126 } 104 }
127 105
128 private Index getNext( ) 106 private Index getNext() throws BadBytecode {
129 throws BadBytecode 107 while (m_iter.hasNext()) {
130 {
131 while( m_iter.hasNext() )
132 {
133 int pos = m_iter.next(); 108 int pos = m_iter.next();
134 int opcode = m_iter.byteAt( pos ); 109 int opcode = m_iter.byteAt(pos);
135 switch( opcode ) 110 switch (opcode) {
136 { 111
137 // for only these opcodes, the next two bytes are a const pool reference 112 // for only these opcodes, the next two bytes are a const pool reference
138 case Opcode.ANEWARRAY: 113 case Opcode.ANEWARRAY:
139 case Opcode.CHECKCAST: 114 case Opcode.CHECKCAST:
@@ -151,30 +126,26 @@ public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Ind
151 case Opcode.PUTSTATIC: 126 case Opcode.PUTSTATIC:
152 case Opcode.GETFIELD: 127 case Opcode.GETFIELD:
153 case Opcode.GETSTATIC: 128 case Opcode.GETSTATIC:
154 return new Index( m_iter, pos + 1, true ); 129 return new Index(m_iter, pos + 1, true);
155 130
156 case Opcode.LDC: 131 case Opcode.LDC:
157 return new Index( m_iter, pos + 1, false ); 132 return new Index(m_iter, pos + 1, false);
158 } 133 }
159 } 134 }
160 135
161 return null; 136 return null;
162 } 137 }
163 138
164 public Iterable<Index> indices( ) 139 public Iterable<Index> indices() {
165 { 140 return new Iterable<Index>() {
166 return new Iterable<Index>( )
167 {
168 @Override 141 @Override
169 public Iterator<Index> iterator( ) 142 public Iterator<Index> iterator() {
170 {
171 return BytecodeIndexIterator.this; 143 return BytecodeIndexIterator.this;
172 } 144 }
173 }; 145 };
174 } 146 }
175 147
176 public void saveChangesToBytecode( ) 148 public void saveChangesToBytecode() {
177 { 149 BytecodeTools.setBytecode(m_bytecode, m_attribute.getCode());
178 BytecodeTools.setBytecode( m_bytecode, m_attribute.getCode() );
179 } 150 }
180} 151}
diff --git a/src/cuchaz/enigma/bytecode/BytecodeTools.java b/src/cuchaz/enigma/bytecode/BytecodeTools.java
index 4407a90..2e456f4 100644
--- a/src/cuchaz/enigma/bytecode/BytecodeTools.java
+++ b/src/cuchaz/enigma/bytecode/BytecodeTools.java
@@ -34,256 +34,222 @@ import cuchaz.enigma.Util;
34import cuchaz.enigma.bytecode.BytecodeIndexIterator.Index; 34import cuchaz.enigma.bytecode.BytecodeIndexIterator.Index;
35import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; 35import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor;
36 36
37public class BytecodeTools 37public class BytecodeTools {
38{ 38
39 public static byte[] writeBytecode( Bytecode bytecode ) 39 public static byte[] writeBytecode(Bytecode bytecode) throws IOException {
40 throws IOException 40
41 {
42 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 41 ByteArrayOutputStream buf = new ByteArrayOutputStream();
43 DataOutputStream out = new DataOutputStream( buf ); 42 DataOutputStream out = new DataOutputStream(buf);
44 try 43
45 { 44 try {
46 // write the constant pool 45 // write the constant pool
47 new ConstPoolEditor( bytecode.getConstPool() ).writePool( out ); 46 new ConstPoolEditor(bytecode.getConstPool()).writePool(out);
48 47
49 // write metadata 48 // write metadata
50 out.writeShort( bytecode.getMaxStack() ); 49 out.writeShort(bytecode.getMaxStack());
51 out.writeShort( bytecode.getMaxLocals() ); 50 out.writeShort(bytecode.getMaxLocals());
52 out.writeShort( bytecode.getStackDepth() ); 51 out.writeShort(bytecode.getStackDepth());
53 52
54 // write the code 53 // write the code
55 out.writeShort( bytecode.getSize() ); 54 out.writeShort(bytecode.getSize());
56 out.write( bytecode.get() ); 55 out.write(bytecode.get());
57 56
58 // write the exception table 57 // write the exception table
59 int numEntries = bytecode.getExceptionTable().size(); 58 int numEntries = bytecode.getExceptionTable().size();
60 out.writeShort( numEntries ); 59 out.writeShort(numEntries);
61 for( int i=0; i<numEntries; i++ ) 60 for (int i = 0; i < numEntries; i++) {
62 { 61 out.writeShort(bytecode.getExceptionTable().startPc(i));
63 out.writeShort( bytecode.getExceptionTable().startPc( i ) ); 62 out.writeShort(bytecode.getExceptionTable().endPc(i));
64 out.writeShort( bytecode.getExceptionTable().endPc( i ) ); 63 out.writeShort(bytecode.getExceptionTable().handlerPc(i));
65 out.writeShort( bytecode.getExceptionTable().handlerPc( i ) ); 64 out.writeShort(bytecode.getExceptionTable().catchType(i));
66 out.writeShort( bytecode.getExceptionTable().catchType( i ) );
67 } 65 }
68 66
69 out.close(); 67 out.close();
70 return buf.toByteArray(); 68 return buf.toByteArray();
71 } 69 } catch (Exception ex) {
72 catch( Exception ex ) 70 Util.closeQuietly(out);
73 { 71 throw new Error(ex);
74 Util.closeQuietly( out );
75 throw new Error( ex );
76 } 72 }
77 } 73 }
78 74
79 public static Bytecode readBytecode( byte[] bytes ) 75 public static Bytecode readBytecode(byte[] bytes) throws IOException {
80 throws IOException 76
81 { 77 ByteArrayInputStream buf = new ByteArrayInputStream(bytes);
82 ByteArrayInputStream buf = new ByteArrayInputStream( bytes ); 78 DataInputStream in = new DataInputStream(buf);
83 DataInputStream in = new DataInputStream( buf ); 79
84 try 80 try {
85 {
86 // read the constant pool entries and update the class 81 // read the constant pool entries and update the class
87 ConstPool pool = ConstPoolEditor.readPool( in ); 82 ConstPool pool = ConstPoolEditor.readPool(in);
88 83
89 // read metadata 84 // read metadata
90 int maxStack = in.readShort(); 85 int maxStack = in.readShort();
91 int maxLocals = in.readShort(); 86 int maxLocals = in.readShort();
92 int stackDepth = in.readShort(); 87 int stackDepth = in.readShort();
93 88
94 Bytecode bytecode = new Bytecode( pool, maxStack, maxLocals ); 89 Bytecode bytecode = new Bytecode(pool, maxStack, maxLocals);
95 bytecode.setStackDepth( stackDepth ); 90 bytecode.setStackDepth(stackDepth);
96 91
97 // read the code 92 // read the code
98 int size = in.readShort(); 93 int size = in.readShort();
99 byte[] code = new byte[size]; 94 byte[] code = new byte[size];
100 in.read( code ); 95 in.read(code);
101 setBytecode( bytecode, code ); 96 setBytecode(bytecode, code);
102 97
103 // read the exception table 98 // read the exception table
104 int numEntries = in.readShort(); 99 int numEntries = in.readShort();
105 for( int i=0; i<numEntries; i++ ) 100 for (int i = 0; i < numEntries; i++) {
106 { 101 bytecode.getExceptionTable().add(in.readShort(), in.readShort(), in.readShort(), in.readShort());
107 bytecode.getExceptionTable().add( in.readShort(), in.readShort(), in.readShort(), in.readShort() );
108 } 102 }
109 103
110 in.close(); 104 in.close();
111 return bytecode; 105 return bytecode;
112 } 106 } catch (Exception ex) {
113 catch( Exception ex ) 107 Util.closeQuietly(in);
114 { 108 throw new Error(ex);
115 Util.closeQuietly( in );
116 throw new Error( ex );
117 } 109 }
118 } 110 }
119 111
120 public static Bytecode prepareMethodForBytecode( CtBehavior behavior, Bytecode bytecode ) 112 public static Bytecode prepareMethodForBytecode(CtBehavior behavior, Bytecode bytecode) throws BadBytecode {
121 throws BadBytecode 113
122 {
123 // update the destination class const pool 114 // update the destination class const pool
124 bytecode = copyBytecodeToConstPool( behavior.getMethodInfo().getConstPool(), bytecode ); 115 bytecode = copyBytecodeToConstPool(behavior.getMethodInfo().getConstPool(), bytecode);
125 116
126 // update method locals and stack 117 // update method locals and stack
127 CodeAttribute attribute = behavior.getMethodInfo().getCodeAttribute(); 118 CodeAttribute attribute = behavior.getMethodInfo().getCodeAttribute();
128 if( bytecode.getMaxLocals() > attribute.getMaxLocals() ) 119 if (bytecode.getMaxLocals() > attribute.getMaxLocals()) {
129 { 120 attribute.setMaxLocals(bytecode.getMaxLocals());
130 attribute.setMaxLocals( bytecode.getMaxLocals() );
131 } 121 }
132 if( bytecode.getMaxStack() > attribute.getMaxStack() ) 122 if (bytecode.getMaxStack() > attribute.getMaxStack()) {
133 { 123 attribute.setMaxStack(bytecode.getMaxStack());
134 attribute.setMaxStack( bytecode.getMaxStack() );
135 } 124 }
136 125
137 return bytecode; 126 return bytecode;
138 } 127 }
139 128
140 public static Bytecode copyBytecodeToConstPool( ConstPool dest, Bytecode bytecode ) 129 public static Bytecode copyBytecodeToConstPool(ConstPool dest, Bytecode bytecode) throws BadBytecode {
141 throws BadBytecode 130
142 {
143 // get the entries this bytecode needs from the const pool 131 // get the entries this bytecode needs from the const pool
144 Set<Integer> indices = Sets.newTreeSet(); 132 Set<Integer> indices = Sets.newTreeSet();
145 ConstPoolEditor editor = new ConstPoolEditor( bytecode.getConstPool() ); 133 ConstPoolEditor editor = new ConstPoolEditor(bytecode.getConstPool());
146 BytecodeIndexIterator iterator = new BytecodeIndexIterator( bytecode ); 134 BytecodeIndexIterator iterator = new BytecodeIndexIterator(bytecode);
147 for( Index index : iterator.indices() ) 135 for (Index index : iterator.indices()) {
148 { 136 assert (index.isValid(bytecode));
149 assert( index.isValid( bytecode ) ); 137 InfoType.gatherIndexTree(indices, editor, index.getIndex());
150 InfoType.gatherIndexTree( indices, editor, index.getIndex() );
151 } 138 }
152 139
153 Map<Integer,Integer> indexMap = Maps.newTreeMap(); 140 Map<Integer,Integer> indexMap = Maps.newTreeMap();
154 141
155 ConstPool src = bytecode.getConstPool(); 142 ConstPool src = bytecode.getConstPool();
156 ConstPoolEditor editorSrc = new ConstPoolEditor( src ); 143 ConstPoolEditor editorSrc = new ConstPoolEditor(src);
157 ConstPoolEditor editorDest = new ConstPoolEditor( dest ); 144 ConstPoolEditor editorDest = new ConstPoolEditor(dest);
158 145
159 // copy entries over in order of level so the index mapping is easier 146 // copy entries over in order of level so the index mapping is easier
160 for( InfoType type : InfoType.getSortedByLevel() ) 147 for (InfoType type : InfoType.getSortedByLevel()) {
161 { 148 for (int index : indices) {
162 for( int index : indices ) 149 ConstInfoAccessor entry = editorSrc.getItem(index);
163 {
164 ConstInfoAccessor entry = editorSrc.getItem( index );
165 150
166 // skip entries that aren't this type 151 // skip entries that aren't this type
167 if( entry.getType() != type ) 152 if (entry.getType() != type) {
168 {
169 continue; 153 continue;
170 } 154 }
171 155
172 // make sure the source entry is valid before we copy it 156 // make sure the source entry is valid before we copy it
173 assert( type.subIndicesAreValid( entry, editorSrc ) ); 157 assert (type.subIndicesAreValid(entry, editorSrc));
174 assert( type.selfIndexIsValid( entry, editorSrc ) ); 158 assert (type.selfIndexIsValid(entry, editorSrc));
175 159
176 // make a copy of the entry so we can modify it safely 160 // make a copy of the entry so we can modify it safely
177 ConstInfoAccessor entryCopy = editorSrc.getItem( index ).copy(); 161 ConstInfoAccessor entryCopy = editorSrc.getItem(index).copy();
178 assert( type.subIndicesAreValid( entryCopy, editorSrc ) ); 162 assert (type.subIndicesAreValid(entryCopy, editorSrc));
179 assert( type.selfIndexIsValid( entryCopy, editorSrc ) ); 163 assert (type.selfIndexIsValid(entryCopy, editorSrc));
180 164
181 // remap the indices 165 // remap the indices
182 type.remapIndices( indexMap, entryCopy ); 166 type.remapIndices(indexMap, entryCopy);
183 assert( type.subIndicesAreValid( entryCopy, editorDest ) ); 167 assert (type.subIndicesAreValid(entryCopy, editorDest));
184 168
185 // put the copy in the destination pool 169 // put the copy in the destination pool
186 int newIndex = editorDest.addItem( entryCopy.getItem() ); 170 int newIndex = editorDest.addItem(entryCopy.getItem());
187 entryCopy.setIndex( newIndex ); 171 entryCopy.setIndex(newIndex);
188 assert( type.selfIndexIsValid( entryCopy, editorDest ) ) : type + ", self: " + entryCopy + " dest: " + editorDest.getItem( entryCopy.getIndex() ); 172 assert (type.selfIndexIsValid(entryCopy, editorDest)) : type + ", self: " + entryCopy + " dest: " + editorDest.getItem(entryCopy.getIndex());
189 173
190 // make sure the source entry is unchanged 174 // make sure the source entry is unchanged
191 assert( type.subIndicesAreValid( entry, editorSrc ) ); 175 assert (type.subIndicesAreValid(entry, editorSrc));
192 assert( type.selfIndexIsValid( entry, editorSrc ) ); 176 assert (type.selfIndexIsValid(entry, editorSrc));
193 177
194 // add the index mapping so we can update the bytecode later 178 // add the index mapping so we can update the bytecode later
195 if( indexMap.containsKey( index ) ) 179 if (indexMap.containsKey(index)) {
196 { 180 throw new Error("Entry at index " + index + " already copied!");
197 throw new Error( "Entry at index " + index + " already copied!" );
198 } 181 }
199 indexMap.put( index, newIndex ); 182 indexMap.put(index, newIndex);
200 } 183 }
201 } 184 }
202 185
203 // make a new bytecode 186 // make a new bytecode
204 Bytecode newBytecode = new Bytecode( dest, bytecode.getMaxStack(), bytecode.getMaxLocals() ); 187 Bytecode newBytecode = new Bytecode(dest, bytecode.getMaxStack(), bytecode.getMaxLocals());
205 bytecode.setStackDepth( bytecode.getStackDepth() ); 188 bytecode.setStackDepth(bytecode.getStackDepth());
206 setBytecode( newBytecode, bytecode.get() ); 189 setBytecode(newBytecode, bytecode.get());
207 setExceptionTable( newBytecode, bytecode.getExceptionTable() ); 190 setExceptionTable(newBytecode, bytecode.getExceptionTable());
208 191
209 // apply the mappings to the bytecode 192 // apply the mappings to the bytecode
210 BytecodeIndexIterator iter = new BytecodeIndexIterator( newBytecode ); 193 BytecodeIndexIterator iter = new BytecodeIndexIterator(newBytecode);
211 for( Index index : iter.indices() ) 194 for (Index index : iter.indices()) {
212 {
213 int oldIndex = index.getIndex(); 195 int oldIndex = index.getIndex();
214 Integer newIndex = indexMap.get( oldIndex ); 196 Integer newIndex = indexMap.get(oldIndex);
215 if( newIndex != null ) 197 if (newIndex != null) {
216 {
217 // make sure this mapping makes sense 198 // make sure this mapping makes sense
218 InfoType typeSrc = editorSrc.getItem( oldIndex ).getType(); 199 InfoType typeSrc = editorSrc.getItem(oldIndex).getType();
219 InfoType typeDest = editorDest.getItem( newIndex ).getType(); 200 InfoType typeDest = editorDest.getItem(newIndex).getType();
220 assert( typeSrc == typeDest ); 201 assert (typeSrc == typeDest);
221 202
222 // apply the mapping 203 // apply the mapping
223 index.setIndex( newIndex ); 204 index.setIndex(newIndex);
224 } 205 }
225 } 206 }
226 iter.saveChangesToBytecode(); 207 iter.saveChangesToBytecode();
227 208
228 // make sure all the indices are valid 209 // make sure all the indices are valid
229 iter = new BytecodeIndexIterator( newBytecode ); 210 iter = new BytecodeIndexIterator(newBytecode);
230 for( Index index : iter.indices() ) 211 for (Index index : iter.indices()) {
231 { 212 assert (index.isValid(newBytecode));
232 assert( index.isValid( newBytecode ) );
233 } 213 }
234 214
235 return newBytecode; 215 return newBytecode;
236 } 216 }
237 217
238 public static void setBytecode( Bytecode dest, byte[] src ) 218 public static void setBytecode(Bytecode dest, byte[] src) {
239 { 219 if (src.length > dest.getSize()) {
240 if( src.length > dest.getSize() ) 220 dest.addGap(src.length - dest.getSize());
241 {
242 dest.addGap( src.length - dest.getSize() );
243 } 221 }
244 assert( dest.getSize() == src.length ); 222 assert (dest.getSize() == src.length);
245 for( int i=0; i<src.length; i++ ) 223 for (int i = 0; i < src.length; i++) {
246 { 224 dest.write(i, src[i]);
247 dest.write( i, src[i] );
248 } 225 }
249 } 226 }
250 227
251 public static void setExceptionTable( Bytecode dest, ExceptionTable src ) 228 public static void setExceptionTable(Bytecode dest, ExceptionTable src) {
252 { 229
253 // clear the dest exception table 230 // clear the dest exception table
254 int size = dest.getExceptionTable().size(); 231 int size = dest.getExceptionTable().size();
255 for( int i=size-1; i>=0; i-- ) 232 for (int i = size - 1; i >= 0; i--) {
256 { 233 dest.getExceptionTable().remove(i);
257 dest.getExceptionTable().remove( i );
258 } 234 }
259 235
260 // copy the exception table 236 // copy the exception table
261 for( int i=0; i<src.size(); i++ ) 237 for (int i = 0; i < src.size(); i++) {
262 { 238 dest.getExceptionTable().add(src.startPc(i), src.endPc(i), src.handlerPc(i), src.catchType(i));
263 dest.getExceptionTable().add(
264 src.startPc( i ),
265 src.endPc( i ),
266 src.handlerPc( i ),
267 src.catchType( i )
268 );
269 } 239 }
270 } 240 }
271 241
272 public static List<String> getParameterTypes( String signature ) 242 public static List<String> getParameterTypes(String signature) {
273 {
274 List<String> types = Lists.newArrayList(); 243 List<String> types = Lists.newArrayList();
275 for( int i=0; i<signature.length(); ) 244 for (int i = 0; i < signature.length();) {
276 { 245 char c = signature.charAt(i);
277 char c = signature.charAt( i );
278 246
279 // handle parens 247 // handle parens
280 if( c == '(' ) 248 if (c == '(') {
281 {
282 i++; 249 i++;
283 c = signature.charAt( i ); 250 c = signature.charAt(i);
284 } 251 }
285 if( c == ')' ) 252 if (c == ')') {
286 {
287 break; 253 break;
288 } 254 }
289 255
@@ -291,35 +257,30 @@ public class BytecodeTools
291 String type = null; 257 String type = null;
292 258
293 int arrayDim = 0; 259 int arrayDim = 0;
294 while( c == '[' ) 260 while (c == '[') {
295 {
296 // advance to array type 261 // advance to array type
297 arrayDim++; 262 arrayDim++;
298 i++; 263 i++;
299 c = signature.charAt( i ); 264 c = signature.charAt(i);
300 } 265 }
301 266
302 if( c == 'L' ) 267 if (c == 'L') {
303 {
304 // read class type 268 // read class type
305 int pos = signature.indexOf( ';', i + 1 ); 269 int pos = signature.indexOf(';', i + 1);
306 String className = signature.substring( i + 1, pos ); 270 String className = signature.substring(i + 1, pos);
307 type = "L" + className + ";"; 271 type = "L" + className + ";";
308 i = pos + 1; 272 i = pos + 1;
309 } 273 } else {
310 else
311 {
312 // read primitive type 274 // read primitive type
313 type = signature.substring( i, i + 1 ); 275 type = signature.substring(i, i + 1);
314 i++; 276 i++;
315 } 277 }
316 278
317 // was it an array? 279 // was it an array?
318 while( arrayDim-- > 0 ) 280 while (arrayDim-- > 0) {
319 {
320 type = "[" + type; 281 type = "[" + type;
321 } 282 }
322 types.add( type ); 283 types.add(type);
323 } 284 }
324 return types; 285 return types;
325 } 286 }
diff --git a/src/cuchaz/enigma/bytecode/CheckCastIterator.java b/src/cuchaz/enigma/bytecode/CheckCastIterator.java
index 7ed5d7f..b6efbd4 100644
--- a/src/cuchaz/enigma/bytecode/CheckCastIterator.java
+++ b/src/cuchaz/enigma/bytecode/CheckCastIterator.java
@@ -22,15 +22,14 @@ import cuchaz.enigma.bytecode.CheckCastIterator.CheckCast;
22import cuchaz.enigma.mapping.ClassEntry; 22import cuchaz.enigma.mapping.ClassEntry;
23import cuchaz.enigma.mapping.MethodEntry; 23import cuchaz.enigma.mapping.MethodEntry;
24 24
25public class CheckCastIterator implements Iterator<CheckCast> 25public class CheckCastIterator implements Iterator<CheckCast> {
26{ 26
27 public static class CheckCast 27 public static class CheckCast {
28 { 28
29 public String className; 29 public String className;
30 public MethodEntry prevMethodEntry; 30 public MethodEntry prevMethodEntry;
31 31
32 public CheckCast( String className, MethodEntry prevMethodEntry ) 32 public CheckCast(String className, MethodEntry prevMethodEntry) {
33 {
34 this.className = className; 33 this.className = className;
35 this.prevMethodEntry = prevMethodEntry; 34 this.prevMethodEntry = prevMethodEntry;
36 } 35 }
@@ -41,9 +40,7 @@ public class CheckCastIterator implements Iterator<CheckCast>
41 private CodeIterator m_iter; 40 private CodeIterator m_iter;
42 private CheckCast m_next; 41 private CheckCast m_next;
43 42
44 public CheckCastIterator( CodeAttribute codeAttribute ) 43 public CheckCastIterator(CodeAttribute codeAttribute) throws BadBytecode {
45 throws BadBytecode
46 {
47 m_constants = codeAttribute.getConstPool(); 44 m_constants = codeAttribute.getConstPool();
48 m_attribute = codeAttribute; 45 m_attribute = codeAttribute;
49 m_iter = m_attribute.iterator(); 46 m_iter = m_attribute.iterator();
@@ -52,52 +49,38 @@ public class CheckCastIterator implements Iterator<CheckCast>
52 } 49 }
53 50
54 @Override 51 @Override
55 public boolean hasNext( ) 52 public boolean hasNext() {
56 {
57 return m_next != null; 53 return m_next != null;
58 } 54 }
59 55
60 @Override 56 @Override
61 public CheckCast next( ) 57 public CheckCast next() {
62 {
63 CheckCast out = m_next; 58 CheckCast out = m_next;
64 try 59 try {
65 {
66 m_next = getNext(); 60 m_next = getNext();
67 } 61 } catch (BadBytecode ex) {
68 catch( BadBytecode ex ) 62 throw new Error(ex);
69 {
70 throw new Error( ex );
71 } 63 }
72 return out; 64 return out;
73 } 65 }
74 66
75 @Override 67 @Override
76 public void remove( ) 68 public void remove() {
77 {
78 throw new UnsupportedOperationException(); 69 throw new UnsupportedOperationException();
79 } 70 }
80 71
81 private CheckCast getNext( ) 72 private CheckCast getNext() throws BadBytecode {
82 throws BadBytecode
83 {
84 int prevPos = 0; 73 int prevPos = 0;
85 while( m_iter.hasNext() ) 74 while (m_iter.hasNext()) {
86 {
87 int pos = m_iter.next(); 75 int pos = m_iter.next();
88 int opcode = m_iter.byteAt( pos ); 76 int opcode = m_iter.byteAt(pos);
89 switch( opcode ) 77 switch (opcode) {
90 {
91 case Opcode.CHECKCAST: 78 case Opcode.CHECKCAST:
92 79
93 // get the type of this op code (next two bytes are a classinfo index) 80 // get the type of this op code (next two bytes are a classinfo index)
94 MethodEntry prevMethodEntry = getMethodEntry( prevPos ); 81 MethodEntry prevMethodEntry = getMethodEntry(prevPos);
95 if( prevMethodEntry != null ) 82 if (prevMethodEntry != null) {
96 { 83 return new CheckCast(m_constants.getClassInfo(m_iter.s16bitAt(pos + 1)), prevMethodEntry);
97 return new CheckCast(
98 m_constants.getClassInfo( m_iter.s16bitAt( pos + 1 ) ),
99 prevMethodEntry
100 );
101 } 84 }
102 break; 85 break;
103 } 86 }
@@ -106,43 +89,36 @@ public class CheckCastIterator implements Iterator<CheckCast>
106 return null; 89 return null;
107 } 90 }
108 91
109 private MethodEntry getMethodEntry( int pos ) 92 private MethodEntry getMethodEntry(int pos) {
110 { 93 switch (m_iter.byteAt(pos)) {
111 switch( m_iter.byteAt( pos ) )
112 {
113 case Opcode.INVOKEVIRTUAL: 94 case Opcode.INVOKEVIRTUAL:
114 case Opcode.INVOKESTATIC: 95 case Opcode.INVOKESTATIC:
115 case Opcode.INVOKEDYNAMIC: 96 case Opcode.INVOKEDYNAMIC:
116 case Opcode.INVOKESPECIAL: 97 case Opcode.INVOKESPECIAL: {
117 { 98 int index = m_iter.s16bitAt(pos + 1);
118 int index = m_iter.s16bitAt( pos + 1 );
119 return new MethodEntry( 99 return new MethodEntry(
120 new ClassEntry( Descriptor.toJvmName( m_constants.getMethodrefClassName( index ) ) ), 100 new ClassEntry(Descriptor.toJvmName(m_constants.getMethodrefClassName(index))),
121 m_constants.getMethodrefName( index ), 101 m_constants.getMethodrefName(index),
122 m_constants.getMethodrefType( index ) 102 m_constants.getMethodrefType(index)
123 ); 103 );
124 } 104 }
125 105
126 case Opcode.INVOKEINTERFACE: 106 case Opcode.INVOKEINTERFACE: {
127 { 107 int index = m_iter.s16bitAt(pos + 1);
128 int index = m_iter.s16bitAt( pos + 1 );
129 return new MethodEntry( 108 return new MethodEntry(
130 new ClassEntry( Descriptor.toJvmName( m_constants.getInterfaceMethodrefClassName( index ) ) ), 109 new ClassEntry(Descriptor.toJvmName(m_constants.getInterfaceMethodrefClassName(index))),
131 m_constants.getInterfaceMethodrefName( index ), 110 m_constants.getInterfaceMethodrefName(index),
132 m_constants.getInterfaceMethodrefType( index ) 111 m_constants.getInterfaceMethodrefType(index)
133 ); 112 );
134 } 113 }
135 } 114 }
136 return null; 115 return null;
137 } 116 }
138 117
139 public Iterable<CheckCast> casts( ) 118 public Iterable<CheckCast> casts() {
140 { 119 return new Iterable<CheckCast>() {
141 return new Iterable<CheckCast>( )
142 {
143 @Override 120 @Override
144 public Iterator<CheckCast> iterator( ) 121 public Iterator<CheckCast> iterator() {
145 {
146 return CheckCastIterator.this; 122 return CheckCastIterator.this;
147 } 123 }
148 }; 124 };
diff --git a/src/cuchaz/enigma/bytecode/ClassRenamer.java b/src/cuchaz/enigma/bytecode/ClassRenamer.java
index 849a323..f8e63d1 100644
--- a/src/cuchaz/enigma/bytecode/ClassRenamer.java
+++ b/src/cuchaz/enigma/bytecode/ClassRenamer.java
@@ -27,55 +27,43 @@ import cuchaz.enigma.mapping.ClassEntry;
27import cuchaz.enigma.mapping.SignatureUpdater; 27import cuchaz.enigma.mapping.SignatureUpdater;
28import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; 28import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater;
29 29
30public class ClassRenamer 30public class ClassRenamer {
31{ 31
32 public static void renameClasses( CtClass c, Map<ClassEntry,ClassEntry> map ) 32 public static void renameClasses(CtClass c, Map<ClassEntry,ClassEntry> map) {
33 { 33
34 // build the map used by javassist 34 // build the map used by javassist
35 ClassMap nameMap = new ClassMap(); 35 ClassMap nameMap = new ClassMap();
36 for( Map.Entry<ClassEntry,ClassEntry> entry : map.entrySet() ) 36 for (Map.Entry<ClassEntry,ClassEntry> entry : map.entrySet()) {
37 { 37 nameMap.put(entry.getKey().getName(), entry.getValue().getName());
38 nameMap.put( entry.getKey().getName(), entry.getValue().getName() );
39 } 38 }
40 39
41 c.replaceClassName( nameMap ); 40 c.replaceClassName(nameMap);
42 41
43 // replace simple names in the InnerClasses attribute too 42 // replace simple names in the InnerClasses attribute too
44 ConstPool constants = c.getClassFile().getConstPool(); 43 ConstPool constants = c.getClassFile().getConstPool();
45 InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute( InnerClassesAttribute.tag ); 44 InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag);
46 if( attr != null ) 45 if (attr != null) {
47 { 46 for (int i = 0; i < attr.tableLength(); i++) {
48 for( int i=0; i<attr.tableLength(); i++ ) 47 ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(attr.innerClass(i)));
49 { 48 if (attr.innerNameIndex(i) != 0) {
50 ClassEntry classEntry = new ClassEntry( Descriptor.toJvmName( attr.innerClass( i ) ) ); 49 attr.setInnerNameIndex(i, constants.addUtf8Info(classEntry.getInnerClassName()));
51 if( attr.innerNameIndex( i ) != 0 )
52 {
53 attr.setInnerNameIndex( i, constants.addUtf8Info( classEntry.getInnerClassName() ) );
54 } 50 }
55 51
56 /* DEBUG 52 /* DEBUG
57 System.out.println( String.format( "\tDEOBF: %s-> ATTR: %s,%s,%s", 53 System.out.println(String.format("\tDEOBF: %s-> ATTR: %s,%s,%s", classEntry, attr.outerClass(i), attr.innerClass(i), attr.innerName(i)));
58 classEntry,
59 attr.outerClass( i ),
60 attr.innerClass( i ),
61 attr.innerName( i )
62 ) );
63 */ 54 */
64 } 55 }
65 } 56 }
66 } 57 }
67 58
68 public static Set<ClassEntry> getAllClassEntries( final CtClass c ) 59 public static Set<ClassEntry> getAllClassEntries(final CtClass c) {
69 { 60
70 // get the classes that javassist knows about 61 // get the classes that javassist knows about
71 final Set<ClassEntry> entries = Sets.newHashSet(); 62 final Set<ClassEntry> entries = Sets.newHashSet();
72 ClassMap map = new ClassMap( ) 63 ClassMap map = new ClassMap() {
73 {
74 @Override 64 @Override
75 public Object get( Object obj ) 65 public Object get(Object obj) {
76 { 66 if (obj instanceof String) {
77 if( obj instanceof String )
78 {
79 String str = (String)obj; 67 String str = (String)obj;
80 68
81 // javassist throws a lot of weird things at this map 69 // javassist throws a lot of weird things at this map
@@ -83,69 +71,60 @@ public class ClassRenamer
83 // I'm opting to filter out the weirdness for now 71 // I'm opting to filter out the weirdness for now
84 72
85 // skip anything with generic arguments 73 // skip anything with generic arguments
86 if( str.indexOf( '<' ) >= 0 || str.indexOf( '>' ) >= 0 || str.indexOf( ';' ) >= 0 ) 74 if (str.indexOf('<') >= 0 || str.indexOf('>') >= 0 || str.indexOf(';') >= 0) {
87 {
88 return null; 75 return null;
89 } 76 }
90 77
91 // convert path/to/class.inner to path/to/class$inner 78 // convert path/to/class.inner to path/to/class$inner
92 str = str.replace( '.', '$' ); 79 str = str.replace('.', '$');
93 80
94 // remember everything else 81 // remember everything else
95 entries.add( new ClassEntry( str ) ); 82 entries.add(new ClassEntry(str));
96 } 83 }
97 return null; 84 return null;
98 } 85 }
86
99 private static final long serialVersionUID = -202160293602070641L; 87 private static final long serialVersionUID = -202160293602070641L;
100 }; 88 };
101 c.replaceClassName( map ); 89 c.replaceClassName(map);
102 90
103 return entries; 91 return entries;
104 } 92 }
105 93
106 public static void moveAllClassesOutOfDefaultPackage( CtClass c, String newPackageName ) 94 public static void moveAllClassesOutOfDefaultPackage(CtClass c, String newPackageName) {
107 { 95
108 // rename all classes 96 // rename all classes
109 Map<ClassEntry,ClassEntry> map = Maps.newHashMap(); 97 Map<ClassEntry,ClassEntry> map = Maps.newHashMap();
110 for( ClassEntry classEntry : ClassRenamer.getAllClassEntries( c ) ) 98 for (ClassEntry classEntry : ClassRenamer.getAllClassEntries(c)) {
111 { 99 if (classEntry.isInDefaultPackage()) {
112 if( classEntry.isInDefaultPackage() ) 100 map.put(classEntry, new ClassEntry(newPackageName + "/" + classEntry.getName()));
113 {
114 map.put( classEntry, new ClassEntry( newPackageName + "/" + classEntry.getName() ) );
115 } 101 }
116 } 102 }
117 ClassRenamer.renameClasses( c, map ); 103 ClassRenamer.renameClasses(c, map);
118 104
119 // TEMP 105 // TEMP
120 for( ClassEntry classEntry : ClassRenamer.getAllClassEntries( c ) ) 106 for (ClassEntry classEntry : ClassRenamer.getAllClassEntries(c)) {
121 { 107 if (classEntry.isInDefaultPackage()) {
122 if( classEntry.isInDefaultPackage() ) 108 throw new Error("!!! " + classEntry);
123 {
124 throw new Error( "!!! " + classEntry );
125 } 109 }
126 } 110 }
127 111
128 // TEMP 112 // TEMP
129 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 113 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
130 { 114 if (behavior.getSignature() == null) {
131 if( behavior.getSignature() == null )
132 {
133 continue; 115 continue;
134 } 116 }
135 117
136 SignatureUpdater.update( behavior.getSignature(), new ClassNameUpdater( ) 118 SignatureUpdater.update(behavior.getSignature(), new ClassNameUpdater() {
137 {
138 @Override 119 @Override
139 public String update( String className ) 120 public String update(String className) {
140 { 121 ClassEntry classEntry = new ClassEntry(className);
141 ClassEntry classEntry = new ClassEntry( className ); 122 if (classEntry.isInDefaultPackage()) {
142 if( classEntry.isInDefaultPackage() ) 123 throw new Error("!!! " + className);
143 {
144 throw new Error( "!!! " + className );
145 } 124 }
146 return className; 125 return className;
147 } 126 }
148 } ); 127 });
149 } 128 }
150 } 129 }
151} 130}
diff --git a/src/cuchaz/enigma/bytecode/ClassTranslator.java b/src/cuchaz/enigma/bytecode/ClassTranslator.java
index 181fadb..bc12405 100644
--- a/src/cuchaz/enigma/bytecode/ClassTranslator.java
+++ b/src/cuchaz/enigma/bytecode/ClassTranslator.java
@@ -28,116 +28,102 @@ import cuchaz.enigma.mapping.FieldEntry;
28import cuchaz.enigma.mapping.MethodEntry; 28import cuchaz.enigma.mapping.MethodEntry;
29import cuchaz.enigma.mapping.Translator; 29import cuchaz.enigma.mapping.Translator;
30 30
31public class ClassTranslator 31public class ClassTranslator {
32{ 32
33 private Translator m_translator; 33 private Translator m_translator;
34 34
35 public ClassTranslator( Translator translator ) 35 public ClassTranslator(Translator translator) {
36 {
37 m_translator = translator; 36 m_translator = translator;
38 } 37 }
39 38
40 public void translate( CtClass c ) 39 public void translate(CtClass c) {
41 {
42 // NOTE: the order of these translations is very important 40 // NOTE: the order of these translations is very important
43 41
44 // translate all the field and method references in the code by editing the constant pool 42 // translate all the field and method references in the code by editing the constant pool
45 ConstPool constants = c.getClassFile().getConstPool(); 43 ConstPool constants = c.getClassFile().getConstPool();
46 ConstPoolEditor editor = new ConstPoolEditor( constants ); 44 ConstPoolEditor editor = new ConstPoolEditor(constants);
47 for( int i=1; i<constants.getSize(); i++ ) 45 for (int i = 1; i < constants.getSize(); i++) {
48 { 46 switch (constants.getTag(i)) {
49 switch( constants.getTag( i ) ) 47 case ConstPool.CONST_Fieldref: {
50 {
51 case ConstPool.CONST_Fieldref:
52 {
53 // translate the name 48 // translate the name
54 FieldEntry entry = new FieldEntry( 49 FieldEntry entry = new FieldEntry(
55 new ClassEntry( Descriptor.toJvmName( constants.getFieldrefClassName( i ) ) ), 50 new ClassEntry(Descriptor.toJvmName(constants.getFieldrefClassName(i))),
56 constants.getFieldrefName( i ) 51 constants.getFieldrefName(i)
57 ); 52 );
58 FieldEntry translatedEntry = m_translator.translateEntry( entry ); 53 FieldEntry translatedEntry = m_translator.translateEntry(entry);
59 54
60 // translate the type 55 // translate the type
61 String type = constants.getFieldrefType( i ); 56 String type = constants.getFieldrefType(i);
62 String translatedType = m_translator.translateSignature( type ); 57 String translatedType = m_translator.translateSignature(type);
63 58
64 if( !entry.equals( translatedEntry ) || !type.equals( translatedType ) ) 59 if (!entry.equals(translatedEntry) || !type.equals(translatedType)) {
65 { 60 editor.changeMemberrefNameAndType(i, translatedEntry.getName(), translatedType);
66 editor.changeMemberrefNameAndType( i, translatedEntry.getName(), translatedType );
67 } 61 }
68 } 62 }
69 break; 63 break;
70 64
71 case ConstPool.CONST_Methodref: 65 case ConstPool.CONST_Methodref:
72 case ConstPool.CONST_InterfaceMethodref: 66 case ConstPool.CONST_InterfaceMethodref: {
73 {
74 // translate the name and type 67 // translate the name and type
75 BehaviorEntry entry = BehaviorEntryFactory.create( 68 BehaviorEntry entry = BehaviorEntryFactory.create(
76 Descriptor.toJvmName( editor.getMemberrefClassname( i ) ), 69 Descriptor.toJvmName(editor.getMemberrefClassname(i)),
77 editor.getMemberrefName( i ), 70 editor.getMemberrefName(i),
78 editor.getMemberrefType( i ) 71 editor.getMemberrefType(i)
79 ); 72 );
80 BehaviorEntry translatedEntry = m_translator.translateEntry( entry ); 73 BehaviorEntry translatedEntry = m_translator.translateEntry(entry);
81 74
82 if( !entry.getName().equals( translatedEntry.getName() ) || !entry.getSignature().equals( translatedEntry.getSignature() ) ) 75 if (!entry.getName().equals(translatedEntry.getName()) || !entry.getSignature().equals(translatedEntry.getSignature())) {
83 { 76 editor.changeMemberrefNameAndType(i, translatedEntry.getName(), translatedEntry.getSignature());
84 editor.changeMemberrefNameAndType( i, translatedEntry.getName(), translatedEntry.getSignature() );
85 } 77 }
86 } 78 }
87 break; 79 break;
88 } 80 }
89 } 81 }
90 82
91 ClassEntry classEntry = new ClassEntry( Descriptor.toJvmName( c.getName() ) ); 83 ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(c.getName()));
92 84
93 // translate all the fields 85 // translate all the fields
94 for( CtField field : c.getDeclaredFields() ) 86 for (CtField field : c.getDeclaredFields()) {
95 { 87
96 // translate the name 88 // translate the name
97 FieldEntry entry = new FieldEntry( classEntry, field.getName() ); 89 FieldEntry entry = new FieldEntry(classEntry, field.getName());
98 String translatedName = m_translator.translate( entry ); 90 String translatedName = m_translator.translate(entry);
99 if( translatedName != null ) 91 if (translatedName != null) {
100 { 92 field.setName(translatedName);
101 field.setName( translatedName );
102 } 93 }
103 94
104 // translate the type 95 // translate the type
105 String translatedType = m_translator.translateSignature( field.getFieldInfo().getDescriptor() ); 96 String translatedType = m_translator.translateSignature(field.getFieldInfo().getDescriptor());
106 field.getFieldInfo().setDescriptor( translatedType ); 97 field.getFieldInfo().setDescriptor(translatedType);
107 } 98 }
108 99
109 // translate all the methods and constructors 100 // translate all the methods and constructors
110 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 101 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
111 { 102 if (behavior instanceof CtMethod) {
112 if( behavior instanceof CtMethod )
113 {
114 CtMethod method = (CtMethod)behavior; 103 CtMethod method = (CtMethod)behavior;
115 104
116 // translate the name 105 // translate the name
117 MethodEntry entry = new MethodEntry( classEntry, method.getName(), method.getSignature() ); 106 MethodEntry entry = new MethodEntry(classEntry, method.getName(), method.getSignature());
118 String translatedName = m_translator.translate( entry ); 107 String translatedName = m_translator.translate(entry);
119 if( translatedName != null ) 108 if (translatedName != null) {
120 { 109 method.setName(translatedName);
121 method.setName( translatedName );
122 } 110 }
123 } 111 }
124 112
125 // translate the type 113 // translate the type
126 String translatedSignature = m_translator.translateSignature( behavior.getMethodInfo().getDescriptor() ); 114 String translatedSignature = m_translator.translateSignature(behavior.getMethodInfo().getDescriptor());
127 behavior.getMethodInfo().setDescriptor( translatedSignature ); 115 behavior.getMethodInfo().setDescriptor(translatedSignature);
128 } 116 }
129 117
130 // translate all the class names referenced in the code 118 // translate all the class names referenced in the code
131 // the above code only changed method/field/reference names and types, but not the class names themselves 119 // the above code only changed method/field/reference names and types, but not the class names themselves
132 Map<ClassEntry,ClassEntry> map = Maps.newHashMap(); 120 Map<ClassEntry,ClassEntry> map = Maps.newHashMap();
133 for( ClassEntry obfClassEntry : ClassRenamer.getAllClassEntries( c ) ) 121 for (ClassEntry obfClassEntry : ClassRenamer.getAllClassEntries(c)) {
134 { 122 ClassEntry deobfClassEntry = m_translator.translateEntry(obfClassEntry);
135 ClassEntry deobfClassEntry = m_translator.translateEntry( obfClassEntry ); 123 if (!obfClassEntry.equals(deobfClassEntry)) {
136 if( !obfClassEntry.equals( deobfClassEntry ) ) 124 map.put(obfClassEntry, deobfClassEntry);
137 {
138 map.put( obfClassEntry, deobfClassEntry );
139 } 125 }
140 } 126 }
141 ClassRenamer.renameClasses( c, map ); 127 ClassRenamer.renameClasses(c, map);
142 } 128 }
143} 129}
diff --git a/src/cuchaz/enigma/bytecode/ConstPoolEditor.java b/src/cuchaz/enigma/bytecode/ConstPoolEditor.java
index aa6149c..2dec3b7 100644
--- a/src/cuchaz/enigma/bytecode/ConstPoolEditor.java
+++ b/src/cuchaz/enigma/bytecode/ConstPoolEditor.java
@@ -23,8 +23,8 @@ import cuchaz.enigma.bytecode.accessors.ClassInfoAccessor;
23import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; 23import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor;
24import cuchaz.enigma.bytecode.accessors.MemberRefInfoAccessor; 24import cuchaz.enigma.bytecode.accessors.MemberRefInfoAccessor;
25 25
26public class ConstPoolEditor 26public class ConstPoolEditor {
27{ 27
28 private static Method m_getItem; 28 private static Method m_getItem;
29 private static Method m_addItem; 29 private static Method m_addItem;
30 private static Method m_addItem0; 30 private static Method m_addItem0;
@@ -36,264 +36,213 @@ public class ConstPoolEditor
36 private static Method m_methodWritePool; 36 private static Method m_methodWritePool;
37 private static Constructor<ConstPool> m_constructorPool; 37 private static Constructor<ConstPool> m_constructorPool;
38 38
39 static 39 static {
40 { 40 try {
41 try 41 m_getItem = ConstPool.class.getDeclaredMethod("getItem", int.class);
42 { 42 m_getItem.setAccessible(true);
43 m_getItem = ConstPool.class.getDeclaredMethod( "getItem", int.class );
44 m_getItem.setAccessible( true );
45 43
46 m_addItem = ConstPool.class.getDeclaredMethod( "addItem", Class.forName( "javassist.bytecode.ConstInfo" ) ); 44 m_addItem = ConstPool.class.getDeclaredMethod("addItem", Class.forName("javassist.bytecode.ConstInfo"));
47 m_addItem.setAccessible( true ); 45 m_addItem.setAccessible(true);
48 46
49 m_addItem0 = ConstPool.class.getDeclaredMethod( "addItem0", Class.forName( "javassist.bytecode.ConstInfo" ) ); 47 m_addItem0 = ConstPool.class.getDeclaredMethod("addItem0", Class.forName("javassist.bytecode.ConstInfo"));
50 m_addItem0.setAccessible( true ); 48 m_addItem0.setAccessible(true);
51 49
52 m_items = ConstPool.class.getDeclaredField( "items" ); 50 m_items = ConstPool.class.getDeclaredField("items");
53 m_items.setAccessible( true ); 51 m_items.setAccessible(true);
54 52
55 m_cache = ConstPool.class.getDeclaredField( "itemsCache" ); 53 m_cache = ConstPool.class.getDeclaredField("itemsCache");
56 m_cache.setAccessible( true ); 54 m_cache.setAccessible(true);
57 55
58 m_numItems = ConstPool.class.getDeclaredField( "numOfItems" ); 56 m_numItems = ConstPool.class.getDeclaredField("numOfItems");
59 m_numItems.setAccessible( true ); 57 m_numItems.setAccessible(true);
60 58
61 m_objects = Class.forName( "javassist.bytecode.LongVector" ).getDeclaredField( "objects" ); 59 m_objects = Class.forName("javassist.bytecode.LongVector").getDeclaredField("objects");
62 m_objects.setAccessible( true ); 60 m_objects.setAccessible(true);
63 61
64 m_elements = Class.forName( "javassist.bytecode.LongVector" ).getDeclaredField( "elements" ); 62 m_elements = Class.forName("javassist.bytecode.LongVector").getDeclaredField("elements");
65 m_elements.setAccessible( true ); 63 m_elements.setAccessible(true);
66 64
67 m_methodWritePool = ConstPool.class.getDeclaredMethod( "write", DataOutputStream.class ); 65 m_methodWritePool = ConstPool.class.getDeclaredMethod("write", DataOutputStream.class);
68 m_methodWritePool.setAccessible( true ); 66 m_methodWritePool.setAccessible(true);
69 67
70 m_constructorPool = ConstPool.class.getDeclaredConstructor( DataInputStream.class ); 68 m_constructorPool = ConstPool.class.getDeclaredConstructor(DataInputStream.class);
71 m_constructorPool.setAccessible( true ); 69 m_constructorPool.setAccessible(true);
72 } 70 } catch (Exception ex) {
73 catch( Exception ex ) 71 throw new Error(ex);
74 {
75 throw new Error( ex );
76 } 72 }
77 } 73 }
78 74
79 private ConstPool m_pool; 75 private ConstPool m_pool;
80 76
81 public ConstPoolEditor( ConstPool pool ) 77 public ConstPoolEditor(ConstPool pool) {
82 {
83 m_pool = pool; 78 m_pool = pool;
84 } 79 }
85 80
86 public void writePool( DataOutputStream out ) 81 public void writePool(DataOutputStream out) {
87 { 82 try {
88 try 83 m_methodWritePool.invoke(m_pool, out);
89 { 84 } catch (Exception ex) {
90 m_methodWritePool.invoke( m_pool, out ); 85 throw new Error(ex);
91 }
92 catch( Exception ex )
93 {
94 throw new Error( ex );
95 } 86 }
96 } 87 }
97 88
98 public static ConstPool readPool( DataInputStream in ) 89 public static ConstPool readPool(DataInputStream in) {
99 { 90 try {
100 try 91 return m_constructorPool.newInstance(in);
101 { 92 } catch (Exception ex) {
102 return m_constructorPool.newInstance( in ); 93 throw new Error(ex);
103 }
104 catch( Exception ex )
105 {
106 throw new Error( ex );
107 } 94 }
108 } 95 }
109 96
110 public String getMemberrefClassname( int memberrefIndex ) 97 public String getMemberrefClassname(int memberrefIndex) {
111 { 98 return Descriptor.toJvmName(m_pool.getClassInfo(m_pool.getMemberClass(memberrefIndex)));
112 return Descriptor.toJvmName( m_pool.getClassInfo( m_pool.getMemberClass( memberrefIndex ) ) );
113 } 99 }
114 100
115 public String getMemberrefName( int memberrefIndex ) 101 public String getMemberrefName(int memberrefIndex) {
116 { 102 return m_pool.getUtf8Info(m_pool.getNameAndTypeName(m_pool.getMemberNameAndType(memberrefIndex)));
117 return m_pool.getUtf8Info( m_pool.getNameAndTypeName( m_pool.getMemberNameAndType( memberrefIndex ) ) );
118 } 103 }
119 104
120 public String getMemberrefType( int memberrefIndex ) 105 public String getMemberrefType(int memberrefIndex) {
121 { 106 return m_pool.getUtf8Info(m_pool.getNameAndTypeDescriptor(m_pool.getMemberNameAndType(memberrefIndex)));
122 return m_pool.getUtf8Info( m_pool.getNameAndTypeDescriptor( m_pool.getMemberNameAndType( memberrefIndex ) ) );
123 } 107 }
124 108
125 public ConstInfoAccessor getItem( int index ) 109 public ConstInfoAccessor getItem(int index) {
126 { 110 try {
127 try 111 Object entry = m_getItem.invoke(m_pool, index);
128 { 112 if (entry == null) {
129 Object entry = m_getItem.invoke( m_pool, index );
130 if( entry == null )
131 {
132 return null; 113 return null;
133 } 114 }
134 return new ConstInfoAccessor( entry ); 115 return new ConstInfoAccessor(entry);
135 } 116 } catch (Exception ex) {
136 catch( Exception ex ) 117 throw new Error(ex);
137 {
138 throw new Error( ex );
139 } 118 }
140 } 119 }
141 120
142 public int addItem( Object item ) 121 public int addItem(Object item) {
143 { 122 try {
144 try 123 return (Integer)m_addItem.invoke(m_pool, item);
145 { 124 } catch (Exception ex) {
146 return (Integer)m_addItem.invoke( m_pool, item ); 125 throw new Error(ex);
147 }
148 catch( Exception ex )
149 {
150 throw new Error( ex );
151 } 126 }
152 } 127 }
153 128
154 public int addItemForceNew( Object item ) 129 public int addItemForceNew(Object item) {
155 { 130 try {
156 try 131 return (Integer)m_addItem0.invoke(m_pool, item);
157 { 132 } catch (Exception ex) {
158 return (Integer)m_addItem0.invoke( m_pool, item ); 133 throw new Error(ex);
159 }
160 catch( Exception ex )
161 {
162 throw new Error( ex );
163 } 134 }
164 } 135 }
165 @SuppressWarnings( "rawtypes" ) 136
166 public void removeLastItem( ) 137 @SuppressWarnings("rawtypes")
167 { 138 public void removeLastItem() {
168 try 139 try {
169 {
170 // remove the item from the cache 140 // remove the item from the cache
171 HashMap cache = getCache(); 141 HashMap cache = getCache();
172 if( cache != null ) 142 if (cache != null) {
173 { 143 Object item = getItem(m_pool.getSize() - 1);
174 Object item = getItem( m_pool.getSize() - 1 ); 144 cache.remove(item);
175 cache.remove( item );
176 } 145 }
177 146
178 // remove the actual item 147 // remove the actual item
179 // based off of LongVector.addElement() 148 // based off of LongVector.addElement()
180 Object items = m_items.get( m_pool ); 149 Object items = m_items.get(m_pool);
181 Object[][] objects = (Object[][])m_objects.get( items ); 150 Object[][] objects = (Object[][])m_objects.get(items);
182 int numElements = (Integer)m_elements.get( items ) - 1; 151 int numElements = (Integer)m_elements.get(items) - 1;
183 int nth = numElements >> 7; 152 int nth = numElements >> 7;
184 int offset = numElements & (128 - 1); 153 int offset = numElements & (128 - 1);
185 objects[nth][offset] = null; 154 objects[nth][offset] = null;
186 155
187 // decrement the number of items 156 // decrement the number of items
188 m_elements.set( items, numElements ); 157 m_elements.set(items, numElements);
189 m_numItems.set( m_pool, (Integer)m_numItems.get( m_pool ) - 1 ); 158 m_numItems.set(m_pool, (Integer)m_numItems.get(m_pool) - 1);
190 } 159 } catch (Exception ex) {
191 catch( Exception ex ) 160 throw new Error(ex);
192 {
193 throw new Error( ex );
194 } 161 }
195 } 162 }
196 163
197 @SuppressWarnings( "rawtypes" ) 164 @SuppressWarnings("rawtypes")
198 /* TEMP */public HashMap getCache( ) 165 public HashMap getCache() {
199 { 166 try {
200 try 167 return (HashMap)m_cache.get(m_pool);
201 { 168 } catch (Exception ex) {
202 return (HashMap)m_cache.get( m_pool ); 169 throw new Error(ex);
203 }
204 catch( Exception ex )
205 {
206 throw new Error( ex );
207 } 170 }
208 } 171 }
209 172
210 @SuppressWarnings( { "rawtypes", "unchecked" } ) 173 @SuppressWarnings({ "rawtypes", "unchecked" })
211 public void changeMemberrefNameAndType( int memberrefIndex, String newName, String newType ) 174 public void changeMemberrefNameAndType(int memberrefIndex, String newName, String newType) {
212 {
213 // NOTE: when changing values, we always need to copy-on-write 175 // NOTE: when changing values, we always need to copy-on-write
214 try 176 try {
215 {
216 // get the memberref item 177 // get the memberref item
217 Object item = getItem( memberrefIndex ).getItem(); 178 Object item = getItem(memberrefIndex).getItem();
218 179
219 // update the cache 180 // update the cache
220 HashMap cache = getCache(); 181 HashMap cache = getCache();
221 if( cache != null ) 182 if (cache != null) {
222 { 183 cache.remove(item);
223 cache.remove( item );
224 } 184 }
225 185
226 new MemberRefInfoAccessor( item ).setNameAndTypeIndex( m_pool.addNameAndTypeInfo( newName, newType ) ); 186 new MemberRefInfoAccessor(item).setNameAndTypeIndex(m_pool.addNameAndTypeInfo(newName, newType));
227 187
228 // update the cache 188 // update the cache
229 if( cache != null ) 189 if (cache != null) {
230 { 190 cache.put(item, item);
231 cache.put( item, item );
232 } 191 }
233 } 192 } catch (Exception ex) {
234 catch( Exception ex ) 193 throw new Error(ex);
235 {
236 throw new Error( ex );
237 } 194 }
238 195
239 // make sure the change worked 196 // make sure the change worked
240 assert( newName.equals( getMemberrefName( memberrefIndex ) ) ); 197 assert (newName.equals(getMemberrefName(memberrefIndex)));
241 assert( newType.equals( getMemberrefType( memberrefIndex ) ) ); 198 assert (newType.equals(getMemberrefType(memberrefIndex)));
242 } 199 }
243 200
244 @SuppressWarnings( { "rawtypes", "unchecked" } ) 201 @SuppressWarnings({ "rawtypes", "unchecked" })
245 public void changeClassName( int classNameIndex, String newName ) 202 public void changeClassName(int classNameIndex, String newName) {
246 {
247 // NOTE: when changing values, we always need to copy-on-write 203 // NOTE: when changing values, we always need to copy-on-write
248 try 204 try {
249 {
250 // get the class item 205 // get the class item
251 Object item = getItem( classNameIndex ).getItem(); 206 Object item = getItem(classNameIndex).getItem();
252 207
253 // update the cache 208 // update the cache
254 HashMap cache = getCache(); 209 HashMap cache = getCache();
255 if( cache != null ) 210 if (cache != null) {
256 { 211 cache.remove(item);
257 cache.remove( item );
258 } 212 }
259 213
260 // add the new name and repoint the name-and-type to it 214 // add the new name and repoint the name-and-type to it
261 new ClassInfoAccessor( item ).setNameIndex( m_pool.addUtf8Info( newName ) ); 215 new ClassInfoAccessor(item).setNameIndex(m_pool.addUtf8Info(newName));
262 216
263 // update the cache 217 // update the cache
264 if( cache != null ) 218 if (cache != null) {
265 { 219 cache.put(item, item);
266 cache.put( item, item );
267 } 220 }
268 } 221 } catch (Exception ex) {
269 catch( Exception ex ) 222 throw new Error(ex);
270 {
271 throw new Error( ex );
272 } 223 }
273 } 224 }
274 225
275 public static ConstPool newConstPool( ) 226 public static ConstPool newConstPool() {
276 {
277 // const pool expects the name of a class to initialize itself 227 // const pool expects the name of a class to initialize itself
278 // but we want an empty pool 228 // but we want an empty pool
279 // so give it a bogus name, and then clear the entries afterwards 229 // so give it a bogus name, and then clear the entries afterwards
280 ConstPool pool = new ConstPool( "a" ); 230 ConstPool pool = new ConstPool("a");
281 231
282 ConstPoolEditor editor = new ConstPoolEditor( pool ); 232 ConstPoolEditor editor = new ConstPoolEditor(pool);
283 int size = pool.getSize(); 233 int size = pool.getSize();
284 for( int i=0; i<size-1; i++ ) 234 for (int i = 0; i < size - 1; i++) {
285 {
286 editor.removeLastItem(); 235 editor.removeLastItem();
287 } 236 }
288 237
289 // make sure the pool is actually empty 238 // make sure the pool is actually empty
290 // although, in this case "empty" means one thing in it 239 // although, in this case "empty" means one thing in it
291 // the JVM spec says index 0 should be reserved 240 // the JVM spec says index 0 should be reserved
292 assert( pool.getSize() == 1 ); 241 assert (pool.getSize() == 1);
293 assert( editor.getItem( 0 ) == null ); 242 assert (editor.getItem(0) == null);
294 assert( editor.getItem( 1 ) == null ); 243 assert (editor.getItem(1) == null);
295 assert( editor.getItem( 2 ) == null ); 244 assert (editor.getItem(2) == null);
296 assert( editor.getItem( 3 ) == null ); 245 assert (editor.getItem(3) == null);
297 246
298 // also, clear the cache 247 // also, clear the cache
299 editor.getCache().clear(); 248 editor.getCache().clear();
@@ -301,15 +250,13 @@ public class ConstPoolEditor
301 return pool; 250 return pool;
302 } 251 }
303 252
304 public String dump( ) 253 public String dump() {
305 {
306 StringBuilder buf = new StringBuilder(); 254 StringBuilder buf = new StringBuilder();
307 for( int i=1; i<m_pool.getSize(); i++ ) 255 for (int i = 1; i < m_pool.getSize(); i++) {
308 { 256 buf.append(String.format("%4d", i));
309 buf.append( String.format( "%4d", i ) ); 257 buf.append(" ");
310 buf.append( " " ); 258 buf.append(getItem(i).toString());
311 buf.append( getItem( i ).toString() ); 259 buf.append("\n");
312 buf.append( "\n" );
313 } 260 }
314 return buf.toString(); 261 return buf.toString();
315 } 262 }
diff --git a/src/cuchaz/enigma/bytecode/InfoType.java b/src/cuchaz/enigma/bytecode/InfoType.java
index fe03006..deaf623 100644
--- a/src/cuchaz/enigma/bytecode/InfoType.java
+++ b/src/cuchaz/enigma/bytecode/InfoType.java
@@ -26,337 +26,290 @@ import cuchaz.enigma.bytecode.accessors.MethodTypeInfoAccessor;
26import cuchaz.enigma.bytecode.accessors.NameAndTypeInfoAccessor; 26import cuchaz.enigma.bytecode.accessors.NameAndTypeInfoAccessor;
27import cuchaz.enigma.bytecode.accessors.StringInfoAccessor; 27import cuchaz.enigma.bytecode.accessors.StringInfoAccessor;
28 28
29public enum InfoType 29public enum InfoType {
30{ 30
31 Utf8Info( 1, 0 ), 31 Utf8Info( 1, 0 ),
32 IntegerInfo( 3, 0 ), 32 IntegerInfo( 3, 0 ),
33 FloatInfo( 4, 0 ), 33 FloatInfo( 4, 0 ),
34 LongInfo( 5, 0 ), 34 LongInfo( 5, 0 ),
35 DoubleInfo( 6, 0 ), 35 DoubleInfo( 6, 0 ),
36 ClassInfo( 7, 1 ) 36 ClassInfo( 7, 1 ) {
37 { 37
38 @Override 38 @Override
39 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 39 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
40 { 40 ClassInfoAccessor accessor = new ClassInfoAccessor(entry.getItem());
41 ClassInfoAccessor accessor = new ClassInfoAccessor( entry.getItem() ); 41 gatherIndexTree(indices, editor, accessor.getNameIndex());
42 gatherIndexTree( indices, editor, accessor.getNameIndex() );
43 } 42 }
44 43
45 @Override 44 @Override
46 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 45 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
47 { 46 ClassInfoAccessor accessor = new ClassInfoAccessor(entry.getItem());
48 ClassInfoAccessor accessor = new ClassInfoAccessor( entry.getItem() ); 47 accessor.setNameIndex(remapIndex(map, accessor.getNameIndex()));
49 accessor.setNameIndex( remapIndex( map, accessor.getNameIndex() ) );
50 } 48 }
51 49
52 @Override 50 @Override
53 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 51 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
54 { 52 ClassInfoAccessor accessor = new ClassInfoAccessor(entry.getItem());
55 ClassInfoAccessor accessor = new ClassInfoAccessor( entry.getItem() ); 53 ConstInfoAccessor nameEntry = pool.getItem(accessor.getNameIndex());
56 ConstInfoAccessor nameEntry = pool.getItem( accessor.getNameIndex() );
57 return nameEntry != null && nameEntry.getTag() == Utf8Info.getTag(); 54 return nameEntry != null && nameEntry.getTag() == Utf8Info.getTag();
58 } 55 }
59 }, 56 },
60 StringInfo( 8, 1 ) 57 StringInfo( 8, 1 ) {
61 { 58
62 @Override 59 @Override
63 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 60 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
64 { 61 StringInfoAccessor accessor = new StringInfoAccessor(entry.getItem());
65 StringInfoAccessor accessor = new StringInfoAccessor( entry.getItem() ); 62 gatherIndexTree(indices, editor, accessor.getStringIndex());
66 gatherIndexTree( indices, editor, accessor.getStringIndex() );
67 } 63 }
68 64
69 @Override 65 @Override
70 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 66 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
71 { 67 StringInfoAccessor accessor = new StringInfoAccessor(entry.getItem());
72 StringInfoAccessor accessor = new StringInfoAccessor( entry.getItem() ); 68 accessor.setStringIndex(remapIndex(map, accessor.getStringIndex()));
73 accessor.setStringIndex( remapIndex( map, accessor.getStringIndex() ) );
74 } 69 }
75 70
76 @Override 71 @Override
77 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 72 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
78 { 73 StringInfoAccessor accessor = new StringInfoAccessor(entry.getItem());
79 StringInfoAccessor accessor = new StringInfoAccessor( entry.getItem() ); 74 ConstInfoAccessor stringEntry = pool.getItem(accessor.getStringIndex());
80 ConstInfoAccessor stringEntry = pool.getItem( accessor.getStringIndex() );
81 return stringEntry != null && stringEntry.getTag() == Utf8Info.getTag(); 75 return stringEntry != null && stringEntry.getTag() == Utf8Info.getTag();
82 } 76 }
83 }, 77 },
84 FieldRefInfo( 9, 2 ) 78 FieldRefInfo( 9, 2 ) {
85 { 79
86 @Override 80 @Override
87 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 81 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
88 { 82 MemberRefInfoAccessor accessor = new MemberRefInfoAccessor(entry.getItem());
89 MemberRefInfoAccessor accessor = new MemberRefInfoAccessor( entry.getItem() ); 83 gatherIndexTree(indices, editor, accessor.getClassIndex());
90 gatherIndexTree( indices, editor, accessor.getClassIndex() ); 84 gatherIndexTree(indices, editor, accessor.getNameAndTypeIndex());
91 gatherIndexTree( indices, editor, accessor.getNameAndTypeIndex() );
92 } 85 }
93 86
94 @Override 87 @Override
95 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 88 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
96 { 89 MemberRefInfoAccessor accessor = new MemberRefInfoAccessor(entry.getItem());
97 MemberRefInfoAccessor accessor = new MemberRefInfoAccessor( entry.getItem() ); 90 accessor.setClassIndex(remapIndex(map, accessor.getClassIndex()));
98 accessor.setClassIndex( remapIndex( map, accessor.getClassIndex() ) ); 91 accessor.setNameAndTypeIndex(remapIndex(map, accessor.getNameAndTypeIndex()));
99 accessor.setNameAndTypeIndex( remapIndex( map, accessor.getNameAndTypeIndex() ) );
100 } 92 }
101 93
102 @Override 94 @Override
103 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 95 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
104 { 96 MemberRefInfoAccessor accessor = new MemberRefInfoAccessor(entry.getItem());
105 MemberRefInfoAccessor accessor = new MemberRefInfoAccessor( entry.getItem() ); 97 ConstInfoAccessor classEntry = pool.getItem(accessor.getClassIndex());
106 ConstInfoAccessor classEntry = pool.getItem( accessor.getClassIndex() ); 98 ConstInfoAccessor nameAndTypeEntry = pool.getItem(accessor.getNameAndTypeIndex());
107 ConstInfoAccessor nameAndTypeEntry = pool.getItem( accessor.getNameAndTypeIndex() ); 99 return classEntry != null && classEntry.getTag() == ClassInfo.getTag() && nameAndTypeEntry != null && nameAndTypeEntry.getTag() == NameAndTypeInfo.getTag();
108 return classEntry != null && classEntry.getTag() == ClassInfo.getTag()
109 && nameAndTypeEntry != null && nameAndTypeEntry.getTag() == NameAndTypeInfo.getTag();
110 } 100 }
111 }, 101 },
112 MethodRefInfo( 10, 2 ) // same as FieldRefInfo 102 // same as FieldRefInfo
113 { 103 MethodRefInfo( 10, 2 ) {
104
114 @Override 105 @Override
115 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 106 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
116 { 107 FieldRefInfo.gatherIndexTree(indices, editor, entry);
117 FieldRefInfo.gatherIndexTree( indices, editor, entry );
118 } 108 }
119 109
120 @Override 110 @Override
121 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 111 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
122 { 112 FieldRefInfo.remapIndices(map, entry);
123 FieldRefInfo.remapIndices( map, entry );
124 } 113 }
125 114
126 @Override 115 @Override
127 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 116 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
128 { 117 return FieldRefInfo.subIndicesAreValid(entry, pool);
129 return FieldRefInfo.subIndicesAreValid( entry, pool );
130 } 118 }
131 }, 119 },
132 InterfaceMethodRefInfo( 11, 2 ) // same as FieldRefInfo 120 // same as FieldRefInfo
133 { 121 InterfaceMethodRefInfo( 11, 2 ) {
122
134 @Override 123 @Override
135 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 124 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
136 { 125 FieldRefInfo.gatherIndexTree(indices, editor, entry);
137 FieldRefInfo.gatherIndexTree( indices, editor, entry );
138 } 126 }
139 127
140 @Override 128 @Override
141 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 129 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
142 { 130 FieldRefInfo.remapIndices(map, entry);
143 FieldRefInfo.remapIndices( map, entry );
144 } 131 }
145 132
146 @Override 133 @Override
147 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 134 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
148 { 135 return FieldRefInfo.subIndicesAreValid(entry, pool);
149 return FieldRefInfo.subIndicesAreValid( entry, pool );
150 } 136 }
151 }, 137 },
152 NameAndTypeInfo( 12, 1 ) 138 NameAndTypeInfo( 12, 1 ) {
153 { 139
154 @Override 140 @Override
155 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 141 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
156 { 142 NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor(entry.getItem());
157 NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor( entry.getItem() ); 143 gatherIndexTree(indices, editor, accessor.getNameIndex());
158 gatherIndexTree( indices, editor, accessor.getNameIndex() ); 144 gatherIndexTree(indices, editor, accessor.getTypeIndex());
159 gatherIndexTree( indices, editor, accessor.getTypeIndex() );
160 } 145 }
161 146
162 @Override 147 @Override
163 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 148 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
164 { 149 NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor(entry.getItem());
165 NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor( entry.getItem() ); 150 accessor.setNameIndex(remapIndex(map, accessor.getNameIndex()));
166 accessor.setNameIndex( remapIndex( map, accessor.getNameIndex() ) ); 151 accessor.setTypeIndex(remapIndex(map, accessor.getTypeIndex()));
167 accessor.setTypeIndex( remapIndex( map, accessor.getTypeIndex() ) );
168 } 152 }
169 153
170 @Override 154 @Override
171 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 155 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
172 { 156 NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor(entry.getItem());
173 NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor( entry.getItem() ); 157 ConstInfoAccessor nameEntry = pool.getItem(accessor.getNameIndex());
174 ConstInfoAccessor nameEntry = pool.getItem( accessor.getNameIndex() ); 158 ConstInfoAccessor typeEntry = pool.getItem(accessor.getTypeIndex());
175 ConstInfoAccessor typeEntry = pool.getItem( accessor.getTypeIndex() ); 159 return nameEntry != null && nameEntry.getTag() == Utf8Info.getTag() && typeEntry != null && typeEntry.getTag() == Utf8Info.getTag();
176 return nameEntry != null && nameEntry.getTag() == Utf8Info.getTag()
177 && typeEntry != null && typeEntry.getTag() == Utf8Info.getTag();
178 } 160 }
179 }, 161 },
180 MethodHandleInfo( 15, 3 ) 162 MethodHandleInfo( 15, 3 ) {
181 { 163
182 @Override 164 @Override
183 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 165 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
184 { 166 MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor(entry.getItem());
185 MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor( entry.getItem() ); 167 gatherIndexTree(indices, editor, accessor.getTypeIndex());
186 gatherIndexTree( indices, editor, accessor.getTypeIndex() ); 168 gatherIndexTree(indices, editor, accessor.getMethodRefIndex());
187 gatherIndexTree( indices, editor, accessor.getMethodRefIndex() );
188 } 169 }
189 170
190 @Override 171 @Override
191 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 172 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
192 { 173 MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor(entry.getItem());
193 MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor( entry.getItem() ); 174 accessor.setTypeIndex(remapIndex(map, accessor.getTypeIndex()));
194 accessor.setTypeIndex( remapIndex( map, accessor.getTypeIndex() ) ); 175 accessor.setMethodRefIndex(remapIndex(map, accessor.getMethodRefIndex()));
195 accessor.setMethodRefIndex( remapIndex( map, accessor.getMethodRefIndex() ) );
196 } 176 }
197 177
198 @Override 178 @Override
199 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 179 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
200 { 180 MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor(entry.getItem());
201 MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor( entry.getItem() ); 181 ConstInfoAccessor typeEntry = pool.getItem(accessor.getTypeIndex());
202 ConstInfoAccessor typeEntry = pool.getItem( accessor.getTypeIndex() ); 182 ConstInfoAccessor methodRefEntry = pool.getItem(accessor.getMethodRefIndex());
203 ConstInfoAccessor methodRefEntry = pool.getItem( accessor.getMethodRefIndex() ); 183 return typeEntry != null && typeEntry.getTag() == Utf8Info.getTag() && methodRefEntry != null && methodRefEntry.getTag() == MethodRefInfo.getTag();
204 return typeEntry != null && typeEntry.getTag() == Utf8Info.getTag()
205 && methodRefEntry != null && methodRefEntry.getTag() == MethodRefInfo.getTag();
206 } 184 }
207 }, 185 },
208 MethodTypeInfo( 16, 1 ) 186 MethodTypeInfo( 16, 1 ) {
209 { 187
210 @Override 188 @Override
211 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 189 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
212 { 190 MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor(entry.getItem());
213 MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor( entry.getItem() ); 191 gatherIndexTree(indices, editor, accessor.getTypeIndex());
214 gatherIndexTree( indices, editor, accessor.getTypeIndex() );
215 } 192 }
216 193
217 @Override 194 @Override
218 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 195 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
219 { 196 MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor(entry.getItem());
220 MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor( entry.getItem() ); 197 accessor.setTypeIndex(remapIndex(map, accessor.getTypeIndex()));
221 accessor.setTypeIndex( remapIndex( map, accessor.getTypeIndex() ) );
222 } 198 }
223 199
224 @Override 200 @Override
225 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 201 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
226 { 202 MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor(entry.getItem());
227 MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor( entry.getItem() ); 203 ConstInfoAccessor typeEntry = pool.getItem(accessor.getTypeIndex());
228 ConstInfoAccessor typeEntry = pool.getItem( accessor.getTypeIndex() );
229 return typeEntry != null && typeEntry.getTag() == Utf8Info.getTag(); 204 return typeEntry != null && typeEntry.getTag() == Utf8Info.getTag();
230 } 205 }
231 }, 206 },
232 InvokeDynamicInfo( 18, 2 ) 207 InvokeDynamicInfo( 18, 2 ) {
233 { 208
234 @Override 209 @Override
235 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 210 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
236 { 211 InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor(entry.getItem());
237 InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor( entry.getItem() ); 212 gatherIndexTree(indices, editor, accessor.getBootstrapIndex());
238 gatherIndexTree( indices, editor, accessor.getBootstrapIndex() ); 213 gatherIndexTree(indices, editor, accessor.getNameAndTypeIndex());
239 gatherIndexTree( indices, editor, accessor.getNameAndTypeIndex() );
240 } 214 }
241 215
242 @Override 216 @Override
243 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 217 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
244 { 218 InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor(entry.getItem());
245 InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor( entry.getItem() ); 219 accessor.setBootstrapIndex(remapIndex(map, accessor.getBootstrapIndex()));
246 accessor.setBootstrapIndex( remapIndex( map, accessor.getBootstrapIndex() ) ); 220 accessor.setNameAndTypeIndex(remapIndex(map, accessor.getNameAndTypeIndex()));
247 accessor.setNameAndTypeIndex( remapIndex( map, accessor.getNameAndTypeIndex() ) );
248 } 221 }
249 222
250 @Override 223 @Override
251 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 224 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
252 { 225 InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor(entry.getItem());
253 InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor( entry.getItem() ); 226 ConstInfoAccessor bootstrapEntry = pool.getItem(accessor.getBootstrapIndex());
254 ConstInfoAccessor bootstrapEntry = pool.getItem( accessor.getBootstrapIndex() ); 227 ConstInfoAccessor nameAndTypeEntry = pool.getItem(accessor.getNameAndTypeIndex());
255 ConstInfoAccessor nameAndTypeEntry = pool.getItem( accessor.getNameAndTypeIndex() ); 228 return bootstrapEntry != null && bootstrapEntry.getTag() == Utf8Info.getTag() && nameAndTypeEntry != null && nameAndTypeEntry.getTag() == NameAndTypeInfo.getTag();
256 return bootstrapEntry != null && bootstrapEntry.getTag() == Utf8Info.getTag()
257 && nameAndTypeEntry != null && nameAndTypeEntry.getTag() == NameAndTypeInfo.getTag();
258 } 229 }
259 }; 230 };
260 231
261 private static Map<Integer,InfoType> m_types; 232 private static Map<Integer,InfoType> m_types;
262 233
263 static 234 static {
264 {
265 m_types = Maps.newTreeMap(); 235 m_types = Maps.newTreeMap();
266 for( InfoType type : values() ) 236 for (InfoType type : values()) {
267 { 237 m_types.put(type.getTag(), type);
268 m_types.put( type.getTag(), type );
269 } 238 }
270 } 239 }
271 240
272 private int m_tag; 241 private int m_tag;
273 private int m_level; 242 private int m_level;
274 243
275 private InfoType( int tag, int level ) 244 private InfoType(int tag, int level) {
276 {
277 m_tag = tag; 245 m_tag = tag;
278 m_level = level; 246 m_level = level;
279 } 247 }
280 248
281 public int getTag( ) 249 public int getTag() {
282 {
283 return m_tag; 250 return m_tag;
284 } 251 }
285 252
286 public int getLevel( ) 253 public int getLevel() {
287 {
288 return m_level; 254 return m_level;
289 } 255 }
290 256
291 public void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry ) 257 public void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, ConstInfoAccessor entry) {
292 {
293 // by default, do nothing 258 // by default, do nothing
294 } 259 }
295 260
296 public void remapIndices( Map<Integer,Integer> map, ConstInfoAccessor entry ) 261 public void remapIndices(Map<Integer,Integer> map, ConstInfoAccessor entry) {
297 {
298 // by default, do nothing 262 // by default, do nothing
299 } 263 }
300 264
301 public boolean subIndicesAreValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 265 public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
302 {
303 // by default, everything is good 266 // by default, everything is good
304 return true; 267 return true;
305 } 268 }
306 269
307 public boolean selfIndexIsValid( ConstInfoAccessor entry, ConstPoolEditor pool ) 270 public boolean selfIndexIsValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
308 { 271 ConstInfoAccessor entryCheck = pool.getItem(entry.getIndex());
309 ConstInfoAccessor entryCheck = pool.getItem( entry.getIndex() ); 272 if (entryCheck == null) {
310 if( entryCheck == null )
311 {
312 return false; 273 return false;
313 } 274 }
314 return entryCheck.getItem().equals( entry.getItem() ); 275 return entryCheck.getItem().equals(entry.getItem());
315 } 276 }
316 277
317 public static InfoType getByTag( int tag ) 278 public static InfoType getByTag(int tag) {
318 { 279 return m_types.get(tag);
319 return m_types.get( tag );
320 } 280 }
321 281
322 public static List<InfoType> getByLevel( int level ) 282 public static List<InfoType> getByLevel(int level) {
323 {
324 List<InfoType> types = Lists.newArrayList(); 283 List<InfoType> types = Lists.newArrayList();
325 for( InfoType type : values() ) 284 for (InfoType type : values()) {
326 { 285 if (type.getLevel() == level) {
327 if( type.getLevel() == level ) 286 types.add(type);
328 {
329 types.add( type );
330 } 287 }
331 } 288 }
332 return types; 289 return types;
333 } 290 }
334 291
335 public static List<InfoType> getSortedByLevel( ) 292 public static List<InfoType> getSortedByLevel() {
336 {
337 List<InfoType> types = Lists.newArrayList(); 293 List<InfoType> types = Lists.newArrayList();
338 types.addAll( getByLevel( 0 ) ); 294 types.addAll(getByLevel(0));
339 types.addAll( getByLevel( 1 ) ); 295 types.addAll(getByLevel(1));
340 types.addAll( getByLevel( 2 ) ); 296 types.addAll(getByLevel(2));
341 types.addAll( getByLevel( 3 ) ); 297 types.addAll(getByLevel(3));
342 return types; 298 return types;
343 } 299 }
344 300
345 public static void gatherIndexTree( Collection<Integer> indices, ConstPoolEditor editor, int index ) 301 public static void gatherIndexTree(Collection<Integer> indices, ConstPoolEditor editor, int index) {
346 {
347 // add own index 302 // add own index
348 indices.add( index ); 303 indices.add(index);
349 304
350 // recurse 305 // recurse
351 ConstInfoAccessor entry = editor.getItem( index ); 306 ConstInfoAccessor entry = editor.getItem(index);
352 entry.getType().gatherIndexTree( indices, editor, entry ); 307 entry.getType().gatherIndexTree(indices, editor, entry);
353 } 308 }
354 309
355 private static int remapIndex( Map<Integer,Integer> map, int index ) 310 private static int remapIndex(Map<Integer,Integer> map, int index) {
356 { 311 Integer newIndex = map.get(index);
357 Integer newIndex = map.get( index ); 312 if (newIndex == null) {
358 if( newIndex == null )
359 {
360 newIndex = index; 313 newIndex = index;
361 } 314 }
362 return newIndex; 315 return newIndex;
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
index 5e59307..f52c31a 100644
--- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java
+++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
@@ -23,105 +23,80 @@ import cuchaz.enigma.analysis.JarIndex;
23import cuchaz.enigma.mapping.BehaviorEntry; 23import cuchaz.enigma.mapping.BehaviorEntry;
24import cuchaz.enigma.mapping.ClassEntry; 24import cuchaz.enigma.mapping.ClassEntry;
25 25
26public class InnerClassWriter 26public class InnerClassWriter {
27{ 27
28 private JarIndex m_jarIndex; 28 private JarIndex m_jarIndex;
29 29
30 public InnerClassWriter( JarIndex jarIndex ) 30 public InnerClassWriter(JarIndex jarIndex) {
31 {
32 m_jarIndex = jarIndex; 31 m_jarIndex = jarIndex;
33 } 32 }
34 33
35 public void write( CtClass c ) 34 public void write(CtClass c) {
36 { 35
37 // is this an inner or outer class? 36 // is this an inner or outer class?
38 String obfInnerClassName = new ClassEntry( Descriptor.toJvmName( c.getName() ) ).getSimpleName(); 37 String obfInnerClassName = new ClassEntry(Descriptor.toJvmName(c.getName())).getSimpleName();
39 String obfOuterClassName = m_jarIndex.getOuterClass( obfInnerClassName ); 38 String obfOuterClassName = m_jarIndex.getOuterClass(obfInnerClassName);
40 if( obfOuterClassName == null ) 39 if (obfOuterClassName == null) {
41 {
42 // this is an outer class 40 // this is an outer class
43 obfOuterClassName = Descriptor.toJvmName( c.getName() ); 41 obfOuterClassName = Descriptor.toJvmName(c.getName());
44 } 42 } else {
45 else
46 {
47 // this is an inner class, rename it to outer$inner 43 // this is an inner class, rename it to outer$inner
48 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfInnerClassName ); 44 ClassEntry obfClassEntry = new ClassEntry(obfOuterClassName + "$" + obfInnerClassName);
49 c.setName( obfClassEntry.getName() ); 45 c.setName(obfClassEntry.getName());
50 46
51 BehaviorEntry caller = m_jarIndex.getAnonymousClassCaller( obfInnerClassName ); 47 BehaviorEntry caller = m_jarIndex.getAnonymousClassCaller(obfInnerClassName);
52 if( caller != null ) 48 if (caller != null) {
53 {
54 // write the enclosing method attribute 49 // write the enclosing method attribute
55 if( caller.getName().equals( "<clinit>" ) ) 50 if (caller.getName().equals("<clinit>")) {
56 { 51 c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName()));
57 c.getClassFile().addAttribute( new EnclosingMethodAttribute( 52 } else {
58 c.getClassFile().getConstPool(), 53 c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName(), caller.getName(), caller.getSignature()));
59 caller.getClassName()
60 ) );
61 }
62 else
63 {
64 c.getClassFile().addAttribute( new EnclosingMethodAttribute(
65 c.getClassFile().getConstPool(),
66 caller.getClassName(),
67 caller.getName(),
68 caller.getSignature()
69 ) );
70 } 54 }
71 } 55 }
72 } 56 }
73 57
74 // write the inner classes if needed 58 // write the inner classes if needed
75 Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses( obfOuterClassName ); 59 Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses(obfOuterClassName);
76 if( obfInnerClassNames != null && !obfInnerClassNames.isEmpty() ) 60 if (obfInnerClassNames != null && !obfInnerClassNames.isEmpty()) {
77 { 61 writeInnerClasses(c, obfOuterClassName, obfInnerClassNames);
78 writeInnerClasses( c, obfOuterClassName, obfInnerClassNames );
79 } 62 }
80 } 63 }
81 64
82 private void writeInnerClasses( CtClass c, String obfOuterClassName, Collection<String> obfInnerClassNames ) 65 private void writeInnerClasses(CtClass c, String obfOuterClassName, Collection<String> obfInnerClassNames) {
83 { 66 InnerClassesAttribute attr = new InnerClassesAttribute(c.getClassFile().getConstPool());
84 InnerClassesAttribute attr = new InnerClassesAttribute( c.getClassFile().getConstPool() ); 67 c.getClassFile().addAttribute(attr);
85 c.getClassFile().addAttribute( attr ); 68 for (String obfInnerClassName : obfInnerClassNames) {
86 for( String obfInnerClassName : obfInnerClassNames )
87 {
88 // get the new inner class name 69 // get the new inner class name
89 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfInnerClassName ); 70 ClassEntry obfClassEntry = new ClassEntry(obfOuterClassName + "$" + obfInnerClassName);
90 71
91 // here's what the JVM spec says about the InnerClasses attribute 72 // here's what the JVM spec says about the InnerClasses attribute
92 // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags ); 73 // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags );
93 74
94 // update the attribute with this inner class 75 // update the attribute with this inner class
95 ConstPool constPool = c.getClassFile().getConstPool(); 76 ConstPool constPool = c.getClassFile().getConstPool();
96 int innerClassIndex = constPool.addClassInfo( obfClassEntry.getName() ); 77 int innerClassIndex = constPool.addClassInfo(obfClassEntry.getName());
97 int outerClassIndex = 0; 78 int outerClassIndex = 0;
98 int innerClassSimpleNameIndex = 0; 79 int innerClassSimpleNameIndex = 0;
99 if( !m_jarIndex.isAnonymousClass( obfInnerClassName ) ) 80 if (!m_jarIndex.isAnonymousClass(obfInnerClassName)) {
100 { 81 outerClassIndex = constPool.addClassInfo(obfClassEntry.getOuterClassName());
101 outerClassIndex = constPool.addClassInfo( obfClassEntry.getOuterClassName() ); 82 innerClassSimpleNameIndex = constPool.addUtf8Info(obfClassEntry.getInnerClassName());
102 innerClassSimpleNameIndex = constPool.addUtf8Info( obfClassEntry.getInnerClassName() );
103 } 83 }
104 84
105 attr.append( 85 attr.append(innerClassIndex, outerClassIndex, innerClassSimpleNameIndex, c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER);
106 innerClassIndex,
107 outerClassIndex,
108 innerClassSimpleNameIndex,
109 c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER
110 );
111 86
112 /* DEBUG 87 /* DEBUG
113 System.out.println( String.format( "\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)", 88 System.out.println(String.format("\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)",
114 obfClassEntry, 89 obfClassEntry,
115 attr.outerClass( attr.tableLength() - 1 ), 90 attr.outerClass(attr.tableLength() - 1),
116 attr.innerClass( attr.tableLength() - 1 ), 91 attr.innerClass(attr.tableLength() - 1),
117 attr.innerName( attr.tableLength() - 1 ), 92 attr.innerName(attr.tableLength() - 1),
118 Constants.NonePackage + "/" + obfInnerClassName, 93 Constants.NonePackage + "/" + obfInnerClassName,
119 obfClassEntry.getName() 94 obfClassEntry.getName()
120 ) ); 95 ));
121 */ 96 */
122 97
123 // make sure the outer class references only the new inner class names 98 // make sure the outer class references only the new inner class names
124 c.replaceClassName( Constants.NonePackage + "/" + obfInnerClassName, obfClassEntry.getName() ); 99 c.replaceClassName(Constants.NonePackage + "/" + obfInnerClassName, obfClassEntry.getName());
125 } 100 }
126 } 101 }
127} 102}
diff --git a/src/cuchaz/enigma/bytecode/MethodParameterWriter.java b/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
index adea7ea..5a11cd8 100644
--- a/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
+++ b/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
@@ -25,51 +25,42 @@ import cuchaz.enigma.mapping.ConstructorEntry;
25import cuchaz.enigma.mapping.MethodEntry; 25import cuchaz.enigma.mapping.MethodEntry;
26import cuchaz.enigma.mapping.Translator; 26import cuchaz.enigma.mapping.Translator;
27 27
28public class MethodParameterWriter 28public class MethodParameterWriter {
29{ 29
30 private Translator m_translator; 30 private Translator m_translator;
31 31
32 public MethodParameterWriter( Translator translator ) 32 public MethodParameterWriter(Translator translator) {
33 {
34 m_translator = translator; 33 m_translator = translator;
35 } 34 }
36 35
37 public void writeMethodArguments( CtClass c ) 36 public void writeMethodArguments(CtClass c) {
38 { 37
39 // Procyon will read method arguments from the "MethodParameters" attribute, so write those 38 // Procyon will read method arguments from the "MethodParameters" attribute, so write those
40 ClassEntry classEntry = new ClassEntry( Descriptor.toJvmName( c.getName() ) ); 39 ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(c.getName()));
41 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 40 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
42 { 41 int numParams = Descriptor.numOfParameters(behavior.getMethodInfo().getDescriptor());
43 int numParams = Descriptor.numOfParameters( behavior.getMethodInfo().getDescriptor() ); 42 if (numParams <= 0) {
44 if( numParams <= 0 )
45 {
46 continue; 43 continue;
47 } 44 }
48 45
49 // get the behavior entry 46 // get the behavior entry
50 BehaviorEntry behaviorEntry; 47 BehaviorEntry behaviorEntry;
51 if( behavior instanceof CtMethod ) 48 if (behavior instanceof CtMethod) {
52 { 49 behaviorEntry = new MethodEntry(classEntry, behavior.getMethodInfo().getName(), behavior.getSignature());
53 behaviorEntry = new MethodEntry( classEntry, behavior.getMethodInfo().getName(), behavior.getSignature() ); 50 } else if (behavior instanceof CtConstructor) {
54 } 51 behaviorEntry = new ConstructorEntry(classEntry, behavior.getSignature());
55 else if( behavior instanceof CtConstructor ) 52 } else {
56 { 53 throw new Error("Unsupported behavior type: " + behavior.getClass().getName());
57 behaviorEntry = new ConstructorEntry( classEntry, behavior.getSignature() );
58 }
59 else
60 {
61 throw new Error( "Unsupported behavior type: " + behavior.getClass().getName() );
62 } 54 }
63 55
64 // get the list of parameter names 56 // get the list of parameter names
65 List<String> names = new ArrayList<String>( numParams ); 57 List<String> names = new ArrayList<String>(numParams);
66 for( int i=0; i<numParams; i++ ) 58 for (int i = 0; i < numParams; i++) {
67 { 59 names.add(m_translator.translate(new ArgumentEntry(behaviorEntry, i, "")));
68 names.add( m_translator.translate( new ArgumentEntry( behaviorEntry, i, "" ) ) );
69 } 60 }
70 61
71 // save the mappings to the class 62 // save the mappings to the class
72 MethodParametersAttribute.updateClass( behavior.getMethodInfo(), names ); 63 MethodParametersAttribute.updateClass(behavior.getMethodInfo(), names);
73 } 64 }
74 } 65 }
75} 66}
diff --git a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
index baf1ac1..bf95956 100644
--- a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
+++ b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
@@ -20,45 +20,38 @@ import javassist.bytecode.AttributeInfo;
20import javassist.bytecode.ConstPool; 20import javassist.bytecode.ConstPool;
21import javassist.bytecode.MethodInfo; 21import javassist.bytecode.MethodInfo;
22 22
23public class MethodParametersAttribute extends AttributeInfo 23public class MethodParametersAttribute extends AttributeInfo {
24{ 24
25 private MethodParametersAttribute( ConstPool pool, List<Integer> parameterNameIndices ) 25 private MethodParametersAttribute(ConstPool pool, List<Integer> parameterNameIndices) {
26 { 26 super(pool, "MethodParameters", writeStruct(parameterNameIndices));
27 super( pool, "MethodParameters", writeStruct( parameterNameIndices ) );
28 } 27 }
29 28
30 public static void updateClass( MethodInfo info, List<String> names ) 29 public static void updateClass(MethodInfo info, List<String> names) {
31 {
32 // add the names to the class const pool 30 // add the names to the class const pool
33 ConstPool constPool = info.getConstPool(); 31 ConstPool constPool = info.getConstPool();
34 List<Integer> parameterNameIndices = new ArrayList<Integer>(); 32 List<Integer> parameterNameIndices = new ArrayList<Integer>();
35 for( String name : names ) 33 for (String name : names) {
36 { 34 if (name != null) {
37 if( name != null ) 35 parameterNameIndices.add(constPool.addUtf8Info(name));
38 { 36 } else {
39 parameterNameIndices.add( constPool.addUtf8Info( name ) ); 37 parameterNameIndices.add(0);
40 }
41 else
42 {
43 parameterNameIndices.add( 0 );
44 } 38 }
45 } 39 }
46 40
47 // add the attribute to the method 41 // add the attribute to the method
48 info.addAttribute( new MethodParametersAttribute( constPool, parameterNameIndices ) ); 42 info.addAttribute(new MethodParametersAttribute(constPool, parameterNameIndices));
49 } 43 }
50 44
51 private static byte[] writeStruct( List<Integer> parameterNameIndices ) 45 private static byte[] writeStruct(List<Integer> parameterNameIndices) {
52 {
53 // JVM 8 Spec says the struct looks like this: 46 // JVM 8 Spec says the struct looks like this:
54 // http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jvms-fr-diffs.pdf 47 // http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jvms-fr-diffs.pdf
55 // uint8 num_params 48 // uint8 num_params
56 // for each param: 49 // for each param:
57 // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry 50 // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry
58 // uint16 access_flags -> don't care, just set to 0 51 // uint16 access_flags -> don't care, just set to 0
59 52
60 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 53 ByteArrayOutputStream buf = new ByteArrayOutputStream();
61 DataOutputStream out = new DataOutputStream( buf ); 54 DataOutputStream out = new DataOutputStream(buf);
62 55
63 // NOTE: java hates unsigned integers, so we have to be careful here 56 // NOTE: java hates unsigned integers, so we have to be careful here
64 // the writeShort(), writeByte() methods will read 16,8 low-order bits from the int argument 57 // the writeShort(), writeByte() methods will read 16,8 low-order bits from the int argument
@@ -66,31 +59,27 @@ public class MethodParametersAttribute extends AttributeInfo
66 // if the int is out of range, the byte stream won't look the way we want and weird things will happen 59 // if the int is out of range, the byte stream won't look the way we want and weird things will happen
67 final int SIZEOF_UINT8 = 1; 60 final int SIZEOF_UINT8 = 1;
68 final int SIZEOF_UINT16 = 2; 61 final int SIZEOF_UINT16 = 2;
69 final int MAX_UINT8 = ( 1 << 8 ) - 1; 62 final int MAX_UINT8 = (1 << 8) - 1;
70 final int MAX_UINT16 = ( 1 << 16 ) - 1; 63 final int MAX_UINT16 = (1 << 16) - 1;
71 64
72 try 65 try {
73 { 66 assert (parameterNameIndices.size() >= 0 && parameterNameIndices.size() <= MAX_UINT8);
74 assert( parameterNameIndices.size() >= 0 && parameterNameIndices.size() <= MAX_UINT8 ); 67 out.writeByte(parameterNameIndices.size());
75 out.writeByte( parameterNameIndices.size() );
76 68
77 for( Integer index : parameterNameIndices ) 69 for (Integer index : parameterNameIndices) {
78 { 70 assert (index >= 0 && index <= MAX_UINT16);
79 assert( index >= 0 && index <= MAX_UINT16 ); 71 out.writeShort(index);
80 out.writeShort( index );
81 72
82 // just write 0 for the access flags 73 // just write 0 for the access flags
83 out.writeShort( 0 ); 74 out.writeShort(0);
84 } 75 }
85 76
86 out.close(); 77 out.close();
87 byte[] data = buf.toByteArray(); 78 byte[] data = buf.toByteArray();
88 assert( data.length == SIZEOF_UINT8 + parameterNameIndices.size()*( SIZEOF_UINT16 + SIZEOF_UINT16 ) ); 79 assert (data.length == SIZEOF_UINT8 + parameterNameIndices.size() * (SIZEOF_UINT16 + SIZEOF_UINT16));
89 return data; 80 return data;
90 } 81 } catch (IOException ex) {
91 catch( IOException ex ) 82 throw new Error(ex);
92 {
93 throw new Error( ex );
94 } 83 }
95 } 84 }
96} 85}
diff --git a/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java
index 41e1d04..d76f056 100644
--- a/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java
@@ -12,58 +12,44 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class ClassInfoAccessor 15public class ClassInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_nameIndex; 18 private static Field m_nameIndex;
19 19
20 static 20 static {
21 { 21 try {
22 try 22 m_class = Class.forName("javassist.bytecode.ClassInfo");
23 { 23 m_nameIndex = m_class.getDeclaredField("name");
24 m_class = Class.forName( "javassist.bytecode.ClassInfo" ); 24 m_nameIndex.setAccessible(true);
25 m_nameIndex = m_class.getDeclaredField( "name" ); 25 } catch (Exception ex) {
26 m_nameIndex.setAccessible( true ); 26 throw new Error(ex);
27 }
28 catch( Exception ex )
29 {
30 throw new Error( ex );
31 } 27 }
32 } 28 }
33 29
34 public static boolean isType( ConstInfoAccessor accessor ) 30 public static boolean isType(ConstInfoAccessor accessor) {
35 { 31 return m_class.isAssignableFrom(accessor.getItem().getClass());
36 return m_class.isAssignableFrom( accessor.getItem().getClass() );
37 } 32 }
38 33
39 private Object m_item; 34 private Object m_item;
40 35
41 public ClassInfoAccessor( Object item ) 36 public ClassInfoAccessor(Object item) {
42 {
43 m_item = item; 37 m_item = item;
44 } 38 }
45 39
46 public int getNameIndex( ) 40 public int getNameIndex() {
47 { 41 try {
48 try 42 return (Integer)m_nameIndex.get(m_item);
49 { 43 } catch (Exception ex) {
50 return (Integer)m_nameIndex.get( m_item ); 44 throw new Error(ex);
51 }
52 catch( Exception ex )
53 {
54 throw new Error( ex );
55 } 45 }
56 } 46 }
57 47
58 public void setNameIndex( int val ) 48 public void setNameIndex(int val) {
59 { 49 try {
60 try 50 m_nameIndex.set(m_item, val);
61 { 51 } catch (Exception ex) {
62 m_nameIndex.set( m_item, val ); 52 throw new Error(ex);
63 }
64 catch( Exception ex )
65 {
66 throw new Error( ex );
67 } 53 }
68 } 54 }
69} 55}
diff --git a/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java
index 3c3d3fa..d00c102 100644
--- a/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java
@@ -22,44 +22,35 @@ import java.lang.reflect.Method;
22 22
23import cuchaz.enigma.bytecode.InfoType; 23import cuchaz.enigma.bytecode.InfoType;
24 24
25public class ConstInfoAccessor 25public class ConstInfoAccessor {
26{ 26
27 private static Class<?> m_class; 27 private static Class<?> m_class;
28 private static Field m_index; 28 private static Field m_index;
29 private static Method m_getTag; 29 private static Method m_getTag;
30 30
31 static 31 static {
32 { 32 try {
33 try 33 m_class = Class.forName("javassist.bytecode.ConstInfo");
34 { 34 m_index = m_class.getDeclaredField("index");
35 m_class = Class.forName( "javassist.bytecode.ConstInfo" ); 35 m_index.setAccessible(true);
36 m_index = m_class.getDeclaredField( "index" ); 36 m_getTag = m_class.getMethod("getTag");
37 m_index.setAccessible( true ); 37 m_getTag.setAccessible(true);
38 m_getTag = m_class.getMethod( "getTag" ); 38 } catch (Exception ex) {
39 m_getTag.setAccessible( true ); 39 throw new Error(ex);
40 }
41 catch( Exception ex )
42 {
43 throw new Error( ex );
44 } 40 }
45 } 41 }
46 42
47 private Object m_item; 43 private Object m_item;
48 44
49 public ConstInfoAccessor( Object item ) 45 public ConstInfoAccessor(Object item) {
50 { 46 if (item == null) {
51 if( item == null ) 47 throw new IllegalArgumentException("item cannot be null!");
52 {
53 throw new IllegalArgumentException( "item cannot be null!" );
54 } 48 }
55 m_item = item; 49 m_item = item;
56 } 50 }
57 51
58 public ConstInfoAccessor( DataInputStream in ) 52 public ConstInfoAccessor(DataInputStream in) throws IOException {
59 throws IOException 53 try {
60 {
61 try
62 {
63 // read the entry 54 // read the entry
64 String className = in.readUTF(); 55 String className = in.readUTF();
65 int oldIndex = in.readInt(); 56 int oldIndex = in.readInt();
@@ -68,132 +59,98 @@ public class ConstInfoAccessor
68 // so we have to read it here 59 // so we have to read it here
69 in.readByte(); 60 in.readByte();
70 61
71 Constructor<?> constructor = Class.forName( className ).getConstructor( DataInputStream.class, int.class ); 62 Constructor<?> constructor = Class.forName(className).getConstructor(DataInputStream.class, int.class);
72 constructor.setAccessible( true ); 63 constructor.setAccessible(true);
73 m_item = constructor.newInstance( in, oldIndex ); 64 m_item = constructor.newInstance(in, oldIndex);
74 } 65 } catch (IOException ex) {
75 catch( IOException ex )
76 {
77 throw ex; 66 throw ex;
78 } 67 } catch (Exception ex) {
79 catch( Exception ex ) 68 throw new Error(ex);
80 {
81 throw new Error( ex );
82 } 69 }
83 } 70 }
84 71
85 public Object getItem( ) 72 public Object getItem() {
86 {
87 return m_item; 73 return m_item;
88 } 74 }
89 75
90 public int getIndex( ) 76 public int getIndex() {
91 { 77 try {
92 try 78 return (Integer)m_index.get(m_item);
93 { 79 } catch (Exception ex) {
94 return (Integer)m_index.get( m_item ); 80 throw new Error(ex);
95 }
96 catch( Exception ex )
97 {
98 throw new Error( ex );
99 } 81 }
100 } 82 }
101 83
102 public void setIndex( int val ) 84 public void setIndex(int val) {
103 { 85 try {
104 try 86 m_index.set(m_item, val);
105 { 87 } catch (Exception ex) {
106 m_index.set( m_item, val ); 88 throw new Error(ex);
107 }
108 catch( Exception ex )
109 {
110 throw new Error( ex );
111 } 89 }
112 } 90 }
113 91
114 public int getTag( ) 92 public int getTag() {
115 { 93 try {
116 try 94 return (Integer)m_getTag.invoke(m_item);
117 { 95 } catch (Exception ex) {
118 return (Integer)m_getTag.invoke( m_item ); 96 throw new Error(ex);
119 }
120 catch( Exception ex )
121 {
122 throw new Error( ex );
123 } 97 }
124 } 98 }
125 99
126 public ConstInfoAccessor copy( ) 100 public ConstInfoAccessor copy() {
127 { 101 return new ConstInfoAccessor(copyItem());
128 return new ConstInfoAccessor( copyItem() );
129 } 102 }
130 103
131 public Object copyItem( ) 104 public Object copyItem() {
132 {
133 // I don't know of a simpler way to copy one of these silly things... 105 // I don't know of a simpler way to copy one of these silly things...
134 try 106 try {
135 {
136 // serialize the item 107 // serialize the item
137 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 108 ByteArrayOutputStream buf = new ByteArrayOutputStream();
138 DataOutputStream out = new DataOutputStream( buf ); 109 DataOutputStream out = new DataOutputStream(buf);
139 write( out ); 110 write(out);
140 111
141 // deserialize the item 112 // deserialize the item
142 DataInputStream in = new DataInputStream( new ByteArrayInputStream( buf.toByteArray() ) ); 113 DataInputStream in = new DataInputStream(new ByteArrayInputStream(buf.toByteArray()));
143 Object item = new ConstInfoAccessor( in ).getItem(); 114 Object item = new ConstInfoAccessor(in).getItem();
144 in.close(); 115 in.close();
145 116
146 return item; 117 return item;
147 } 118 } catch (Exception ex) {
148 catch( Exception ex ) 119 throw new Error(ex);
149 {
150 throw new Error( ex );
151 } 120 }
152 } 121 }
153 122
154 public void write( DataOutputStream out ) 123 public void write(DataOutputStream out) throws IOException {
155 throws IOException 124 try {
156 { 125 out.writeUTF(m_item.getClass().getName());
157 try 126 out.writeInt(getIndex());
158 {
159 out.writeUTF( m_item.getClass().getName() );
160 out.writeInt( getIndex() );
161 127
162 Method method = m_item.getClass().getMethod( "write", DataOutputStream.class ); 128 Method method = m_item.getClass().getMethod("write", DataOutputStream.class);
163 method.setAccessible( true ); 129 method.setAccessible(true);
164 method.invoke( m_item, out ); 130 method.invoke(m_item, out);
165 } 131 } catch (IOException ex) {
166 catch( IOException ex )
167 {
168 throw ex; 132 throw ex;
169 } 133 } catch (Exception ex) {
170 catch( Exception ex ) 134 throw new Error(ex);
171 {
172 throw new Error( ex );
173 } 135 }
174 } 136 }
175 137
176 @Override 138 @Override
177 public String toString( ) 139 public String toString() {
178 { 140 try {
179 try
180 {
181 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 141 ByteArrayOutputStream buf = new ByteArrayOutputStream();
182 PrintWriter out = new PrintWriter( buf ); 142 PrintWriter out = new PrintWriter(buf);
183 Method print = m_item.getClass().getMethod( "print", PrintWriter.class ); 143 Method print = m_item.getClass().getMethod("print", PrintWriter.class);
184 print.setAccessible( true ); 144 print.setAccessible(true);
185 print.invoke( m_item, out ); 145 print.invoke(m_item, out);
186 out.close(); 146 out.close();
187 return buf.toString().replace( "\n", "" ); 147 return buf.toString().replace("\n", "");
188 } 148 } catch (Exception ex) {
189 catch( Exception ex ) 149 throw new Error(ex);
190 {
191 throw new Error( ex );
192 } 150 }
193 } 151 }
194 152
195 public InfoType getType( ) 153 public InfoType getType() {
196 { 154 return InfoType.getByTag(getTag());
197 return InfoType.getByTag( getTag() );
198 } 155 }
199} 156}
diff --git a/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java
index 169306a..0d780ea 100644
--- a/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java
@@ -12,85 +12,63 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class InvokeDynamicInfoAccessor 15public class InvokeDynamicInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_bootstrapIndex; 18 private static Field m_bootstrapIndex;
19 private static Field m_nameAndTypeIndex; 19 private static Field m_nameAndTypeIndex;
20 20
21 static 21 static {
22 { 22 try {
23 try 23 m_class = Class.forName("javassist.bytecode.InvokeDynamicInfo");
24 { 24 m_bootstrapIndex = m_class.getDeclaredField("bootstrap");
25 m_class = Class.forName( "javassist.bytecode.InvokeDynamicInfo" ); 25 m_bootstrapIndex.setAccessible(true);
26 m_bootstrapIndex = m_class.getDeclaredField( "bootstrap" ); 26 m_nameAndTypeIndex = m_class.getDeclaredField("nameAndType");
27 m_bootstrapIndex.setAccessible( true ); 27 m_nameAndTypeIndex.setAccessible(true);
28 m_nameAndTypeIndex = m_class.getDeclaredField( "nameAndType" ); 28 } catch (Exception ex) {
29 m_nameAndTypeIndex.setAccessible( true ); 29 throw new Error(ex);
30 }
31 catch( Exception ex )
32 {
33 throw new Error( ex );
34 } 30 }
35 } 31 }
36 32
37 public static boolean isType( ConstInfoAccessor accessor ) 33 public static boolean isType(ConstInfoAccessor accessor) {
38 { 34 return m_class.isAssignableFrom(accessor.getItem().getClass());
39 return m_class.isAssignableFrom( accessor.getItem().getClass() );
40 } 35 }
41 36
42 private Object m_item; 37 private Object m_item;
43 38
44 public InvokeDynamicInfoAccessor( Object item ) 39 public InvokeDynamicInfoAccessor(Object item) {
45 {
46 m_item = item; 40 m_item = item;
47 } 41 }
48 42
49 public int getBootstrapIndex( ) 43 public int getBootstrapIndex() {
50 { 44 try {
51 try 45 return (Integer)m_bootstrapIndex.get(m_item);
52 { 46 } catch (Exception ex) {
53 return (Integer)m_bootstrapIndex.get( m_item ); 47 throw new Error(ex);
54 }
55 catch( Exception ex )
56 {
57 throw new Error( ex );
58 } 48 }
59 } 49 }
60 50
61 public void setBootstrapIndex( int val ) 51 public void setBootstrapIndex(int val) {
62 { 52 try {
63 try 53 m_bootstrapIndex.set(m_item, val);
64 { 54 } catch (Exception ex) {
65 m_bootstrapIndex.set( m_item, val ); 55 throw new Error(ex);
66 }
67 catch( Exception ex )
68 {
69 throw new Error( ex );
70 } 56 }
71 } 57 }
72 58
73 public int getNameAndTypeIndex( ) 59 public int getNameAndTypeIndex() {
74 { 60 try {
75 try 61 return (Integer)m_nameAndTypeIndex.get(m_item);
76 { 62 } catch (Exception ex) {
77 return (Integer)m_nameAndTypeIndex.get( m_item ); 63 throw new Error(ex);
78 }
79 catch( Exception ex )
80 {
81 throw new Error( ex );
82 } 64 }
83 } 65 }
84 66
85 public void setNameAndTypeIndex( int val ) 67 public void setNameAndTypeIndex(int val) {
86 { 68 try {
87 try 69 m_nameAndTypeIndex.set(m_item, val);
88 { 70 } catch (Exception ex) {
89 m_nameAndTypeIndex.set( m_item, val ); 71 throw new Error(ex);
90 }
91 catch( Exception ex )
92 {
93 throw new Error( ex );
94 } 72 }
95 } 73 }
96} 74}
diff --git a/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java
index 2ee3aff..9fe945f 100644
--- a/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java
@@ -12,85 +12,63 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class MemberRefInfoAccessor 15public class MemberRefInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_classIndex; 18 private static Field m_classIndex;
19 private static Field m_nameAndTypeIndex; 19 private static Field m_nameAndTypeIndex;
20 20
21 static 21 static {
22 { 22 try {
23 try 23 m_class = Class.forName("javassist.bytecode.MemberrefInfo");
24 { 24 m_classIndex = m_class.getDeclaredField("classIndex");
25 m_class = Class.forName( "javassist.bytecode.MemberrefInfo" ); 25 m_classIndex.setAccessible(true);
26 m_classIndex = m_class.getDeclaredField( "classIndex" ); 26 m_nameAndTypeIndex = m_class.getDeclaredField("nameAndTypeIndex");
27 m_classIndex.setAccessible( true ); 27 m_nameAndTypeIndex.setAccessible(true);
28 m_nameAndTypeIndex = m_class.getDeclaredField( "nameAndTypeIndex" ); 28 } catch (Exception ex) {
29 m_nameAndTypeIndex.setAccessible( true ); 29 throw new Error(ex);
30 }
31 catch( Exception ex )
32 {
33 throw new Error( ex );
34 } 30 }
35 } 31 }
36 32
37 public static boolean isType( ConstInfoAccessor accessor ) 33 public static boolean isType(ConstInfoAccessor accessor) {
38 { 34 return m_class.isAssignableFrom(accessor.getItem().getClass());
39 return m_class.isAssignableFrom( accessor.getItem().getClass() );
40 } 35 }
41 36
42 private Object m_item; 37 private Object m_item;
43 38
44 public MemberRefInfoAccessor( Object item ) 39 public MemberRefInfoAccessor(Object item) {
45 {
46 m_item = item; 40 m_item = item;
47 } 41 }
48 42
49 public int getClassIndex( ) 43 public int getClassIndex() {
50 { 44 try {
51 try 45 return (Integer)m_classIndex.get(m_item);
52 { 46 } catch (Exception ex) {
53 return (Integer)m_classIndex.get( m_item ); 47 throw new Error(ex);
54 }
55 catch( Exception ex )
56 {
57 throw new Error( ex );
58 } 48 }
59 } 49 }
60 50
61 public void setClassIndex( int val ) 51 public void setClassIndex(int val) {
62 { 52 try {
63 try 53 m_classIndex.set(m_item, val);
64 { 54 } catch (Exception ex) {
65 m_classIndex.set( m_item, val ); 55 throw new Error(ex);
66 }
67 catch( Exception ex )
68 {
69 throw new Error( ex );
70 } 56 }
71 } 57 }
72 58
73 public int getNameAndTypeIndex( ) 59 public int getNameAndTypeIndex() {
74 { 60 try {
75 try 61 return (Integer)m_nameAndTypeIndex.get(m_item);
76 { 62 } catch (Exception ex) {
77 return (Integer)m_nameAndTypeIndex.get( m_item ); 63 throw new Error(ex);
78 }
79 catch( Exception ex )
80 {
81 throw new Error( ex );
82 } 64 }
83 } 65 }
84 66
85 public void setNameAndTypeIndex( int val ) 67 public void setNameAndTypeIndex(int val) {
86 { 68 try {
87 try 69 m_nameAndTypeIndex.set(m_item, val);
88 { 70 } catch (Exception ex) {
89 m_nameAndTypeIndex.set( m_item, val ); 71 throw new Error(ex);
90 }
91 catch( Exception ex )
92 {
93 throw new Error( ex );
94 } 72 }
95 } 73 }
96} 74}
diff --git a/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java
index 27b7aee..4c95b22 100644
--- a/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java
@@ -12,85 +12,63 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class MethodHandleInfoAccessor 15public class MethodHandleInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_kindIndex; 18 private static Field m_kindIndex;
19 private static Field m_indexIndex; 19 private static Field m_indexIndex;
20 20
21 static 21 static {
22 { 22 try {
23 try 23 m_class = Class.forName("javassist.bytecode.MethodHandleInfo");
24 { 24 m_kindIndex = m_class.getDeclaredField("refKind");
25 m_class = Class.forName( "javassist.bytecode.MethodHandleInfo" ); 25 m_kindIndex.setAccessible(true);
26 m_kindIndex = m_class.getDeclaredField( "refKind" ); 26 m_indexIndex = m_class.getDeclaredField("refIndex");
27 m_kindIndex.setAccessible( true ); 27 m_indexIndex.setAccessible(true);
28 m_indexIndex = m_class.getDeclaredField( "refIndex" ); 28 } catch (Exception ex) {
29 m_indexIndex.setAccessible( true ); 29 throw new Error(ex);
30 }
31 catch( Exception ex )
32 {
33 throw new Error( ex );
34 } 30 }
35 } 31 }
36 32
37 public static boolean isType( ConstInfoAccessor accessor ) 33 public static boolean isType(ConstInfoAccessor accessor) {
38 { 34 return m_class.isAssignableFrom(accessor.getItem().getClass());
39 return m_class.isAssignableFrom( accessor.getItem().getClass() );
40 } 35 }
41 36
42 private Object m_item; 37 private Object m_item;
43 38
44 public MethodHandleInfoAccessor( Object item ) 39 public MethodHandleInfoAccessor(Object item) {
45 {
46 m_item = item; 40 m_item = item;
47 } 41 }
48 42
49 public int getTypeIndex( ) 43 public int getTypeIndex() {
50 { 44 try {
51 try 45 return (Integer)m_kindIndex.get(m_item);
52 { 46 } catch (Exception ex) {
53 return (Integer)m_kindIndex.get( m_item ); 47 throw new Error(ex);
54 }
55 catch( Exception ex )
56 {
57 throw new Error( ex );
58 } 48 }
59 } 49 }
60 50
61 public void setTypeIndex( int val ) 51 public void setTypeIndex(int val) {
62 { 52 try {
63 try 53 m_kindIndex.set(m_item, val);
64 { 54 } catch (Exception ex) {
65 m_kindIndex.set( m_item, val ); 55 throw new Error(ex);
66 }
67 catch( Exception ex )
68 {
69 throw new Error( ex );
70 } 56 }
71 } 57 }
72 58
73 public int getMethodRefIndex( ) 59 public int getMethodRefIndex() {
74 { 60 try {
75 try 61 return (Integer)m_indexIndex.get(m_item);
76 { 62 } catch (Exception ex) {
77 return (Integer)m_indexIndex.get( m_item ); 63 throw new Error(ex);
78 }
79 catch( Exception ex )
80 {
81 throw new Error( ex );
82 } 64 }
83 } 65 }
84 66
85 public void setMethodRefIndex( int val ) 67 public void setMethodRefIndex(int val) {
86 { 68 try {
87 try 69 m_indexIndex.set(m_item, val);
88 { 70 } catch (Exception ex) {
89 m_indexIndex.set( m_item, val ); 71 throw new Error(ex);
90 }
91 catch( Exception ex )
92 {
93 throw new Error( ex );
94 } 72 }
95 } 73 }
96} 74}
diff --git a/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java
index 4cba6a2..e151117 100644
--- a/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java
@@ -12,58 +12,44 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class MethodTypeInfoAccessor 15public class MethodTypeInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_descriptorIndex; 18 private static Field m_descriptorIndex;
19 19
20 static 20 static {
21 { 21 try {
22 try 22 m_class = Class.forName("javassist.bytecode.MethodTypeInfo");
23 { 23 m_descriptorIndex = m_class.getDeclaredField("descriptor");
24 m_class = Class.forName( "javassist.bytecode.MethodTypeInfo" ); 24 m_descriptorIndex.setAccessible(true);
25 m_descriptorIndex = m_class.getDeclaredField( "descriptor" ); 25 } catch (Exception ex) {
26 m_descriptorIndex.setAccessible( true ); 26 throw new Error(ex);
27 }
28 catch( Exception ex )
29 {
30 throw new Error( ex );
31 } 27 }
32 } 28 }
33 29
34 public static boolean isType( ConstInfoAccessor accessor ) 30 public static boolean isType(ConstInfoAccessor accessor) {
35 { 31 return m_class.isAssignableFrom(accessor.getItem().getClass());
36 return m_class.isAssignableFrom( accessor.getItem().getClass() );
37 } 32 }
38 33
39 private Object m_item; 34 private Object m_item;
40 35
41 public MethodTypeInfoAccessor( Object item ) 36 public MethodTypeInfoAccessor(Object item) {
42 {
43 m_item = item; 37 m_item = item;
44 } 38 }
45 39
46 public int getTypeIndex( ) 40 public int getTypeIndex() {
47 { 41 try {
48 try 42 return (Integer)m_descriptorIndex.get(m_item);
49 { 43 } catch (Exception ex) {
50 return (Integer)m_descriptorIndex.get( m_item ); 44 throw new Error(ex);
51 }
52 catch( Exception ex )
53 {
54 throw new Error( ex );
55 } 45 }
56 } 46 }
57 47
58 public void setTypeIndex( int val ) 48 public void setTypeIndex(int val) {
59 { 49 try {
60 try 50 m_descriptorIndex.set(m_item, val);
61 { 51 } catch (Exception ex) {
62 m_descriptorIndex.set( m_item, val ); 52 throw new Error(ex);
63 }
64 catch( Exception ex )
65 {
66 throw new Error( ex );
67 } 53 }
68 } 54 }
69} 55}
diff --git a/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java
index 03b4de3..6e82f3e 100644
--- a/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java
@@ -12,85 +12,63 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class NameAndTypeInfoAccessor 15public class NameAndTypeInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_nameIndex; 18 private static Field m_nameIndex;
19 private static Field m_typeIndex; 19 private static Field m_typeIndex;
20 20
21 static 21 static {
22 { 22 try {
23 try 23 m_class = Class.forName("javassist.bytecode.NameAndTypeInfo");
24 { 24 m_nameIndex = m_class.getDeclaredField("memberName");
25 m_class = Class.forName( "javassist.bytecode.NameAndTypeInfo" ); 25 m_nameIndex.setAccessible(true);
26 m_nameIndex = m_class.getDeclaredField( "memberName" ); 26 m_typeIndex = m_class.getDeclaredField("typeDescriptor");
27 m_nameIndex.setAccessible( true ); 27 m_typeIndex.setAccessible(true);
28 m_typeIndex = m_class.getDeclaredField( "typeDescriptor" ); 28 } catch (Exception ex) {
29 m_typeIndex.setAccessible( true ); 29 throw new Error(ex);
30 }
31 catch( Exception ex )
32 {
33 throw new Error( ex );
34 } 30 }
35 } 31 }
36 32
37 public static boolean isType( ConstInfoAccessor accessor ) 33 public static boolean isType(ConstInfoAccessor accessor) {
38 { 34 return m_class.isAssignableFrom(accessor.getItem().getClass());
39 return m_class.isAssignableFrom( accessor.getItem().getClass() );
40 } 35 }
41 36
42 private Object m_item; 37 private Object m_item;
43 38
44 public NameAndTypeInfoAccessor( Object item ) 39 public NameAndTypeInfoAccessor(Object item) {
45 {
46 m_item = item; 40 m_item = item;
47 } 41 }
48 42
49 public int getNameIndex( ) 43 public int getNameIndex() {
50 { 44 try {
51 try 45 return (Integer)m_nameIndex.get(m_item);
52 { 46 } catch (Exception ex) {
53 return (Integer)m_nameIndex.get( m_item ); 47 throw new Error(ex);
54 }
55 catch( Exception ex )
56 {
57 throw new Error( ex );
58 } 48 }
59 } 49 }
60 50
61 public void setNameIndex( int val ) 51 public void setNameIndex(int val) {
62 { 52 try {
63 try 53 m_nameIndex.set(m_item, val);
64 { 54 } catch (Exception ex) {
65 m_nameIndex.set( m_item, val ); 55 throw new Error(ex);
66 }
67 catch( Exception ex )
68 {
69 throw new Error( ex );
70 } 56 }
71 } 57 }
72 58
73 public int getTypeIndex( ) 59 public int getTypeIndex() {
74 { 60 try {
75 try 61 return (Integer)m_typeIndex.get(m_item);
76 { 62 } catch (Exception ex) {
77 return (Integer)m_typeIndex.get( m_item ); 63 throw new Error(ex);
78 }
79 catch( Exception ex )
80 {
81 throw new Error( ex );
82 } 64 }
83 } 65 }
84 66
85 public void setTypeIndex( int val ) 67 public void setTypeIndex(int val) {
86 { 68 try {
87 try 69 m_typeIndex.set(m_item, val);
88 { 70 } catch (Exception ex) {
89 m_typeIndex.set( m_item, val ); 71 throw new Error(ex);
90 }
91 catch( Exception ex )
92 {
93 throw new Error( ex );
94 } 72 }
95 } 73 }
96} 74}
diff --git a/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java
index 5cdfce4..6665ffe 100644
--- a/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java
@@ -12,58 +12,44 @@ package cuchaz.enigma.bytecode.accessors;
12 12
13import java.lang.reflect.Field; 13import java.lang.reflect.Field;
14 14
15public class StringInfoAccessor 15public class StringInfoAccessor {
16{ 16
17 private static Class<?> m_class; 17 private static Class<?> m_class;
18 private static Field m_stringIndex; 18 private static Field m_stringIndex;
19 19
20 static 20 static {
21 { 21 try {
22 try 22 m_class = Class.forName("javassist.bytecode.StringInfo");
23 { 23 m_stringIndex = m_class.getDeclaredField("string");
24 m_class = Class.forName( "javassist.bytecode.StringInfo" ); 24 m_stringIndex.setAccessible(true);
25 m_stringIndex = m_class.getDeclaredField( "string" ); 25 } catch (Exception ex) {
26 m_stringIndex.setAccessible( true ); 26 throw new Error(ex);
27 }
28 catch( Exception ex )
29 {
30 throw new Error( ex );
31 } 27 }
32 } 28 }
33 29
34 public static boolean isType( ConstInfoAccessor accessor ) 30 public static boolean isType(ConstInfoAccessor accessor) {
35 { 31 return m_class.isAssignableFrom(accessor.getItem().getClass());
36 return m_class.isAssignableFrom( accessor.getItem().getClass() );
37 } 32 }
38 33
39 private Object m_item; 34 private Object m_item;
40 35
41 public StringInfoAccessor( Object item ) 36 public StringInfoAccessor(Object item) {
42 {
43 m_item = item; 37 m_item = item;
44 } 38 }
45 39
46 public int getStringIndex( ) 40 public int getStringIndex() {
47 { 41 try {
48 try 42 return (Integer)m_stringIndex.get(m_item);
49 { 43 } catch (Exception ex) {
50 return (Integer)m_stringIndex.get( m_item ); 44 throw new Error(ex);
51 }
52 catch( Exception ex )
53 {
54 throw new Error( ex );
55 } 45 }
56 } 46 }
57 47
58 public void setStringIndex( int val ) 48 public void setStringIndex(int val) {
59 { 49 try {
60 try 50 m_stringIndex.set(m_item, val);
61 { 51 } catch (Exception ex) {
62 m_stringIndex.set( m_item, val ); 52 throw new Error(ex);
63 }
64 catch( Exception ex )
65 {
66 throw new Error( ex );
67 } 53 }
68 } 54 }
69} 55}
diff --git a/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java
index 1cadd83..2abf60b 100644
--- a/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java
+++ b/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java
@@ -10,24 +10,19 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.bytecode.accessors; 11package cuchaz.enigma.bytecode.accessors;
12 12
13public class Utf8InfoAccessor 13public class Utf8InfoAccessor {
14{ 14
15 private static Class<?> m_class; 15 private static Class<?> m_class;
16 16
17 static 17 static {
18 { 18 try {
19 try 19 m_class = Class.forName("javassist.bytecode.Utf8Info");
20 { 20 } catch (Exception ex) {
21 m_class = Class.forName( "javassist.bytecode.Utf8Info" ); 21 throw new Error(ex);
22 }
23 catch( Exception ex )
24 {
25 throw new Error( ex );
26 } 22 }
27 } 23 }
28 24
29 public static boolean isType( ConstInfoAccessor accessor ) 25 public static boolean isType(ConstInfoAccessor accessor) {
30 { 26 return m_class.isAssignableFrom(accessor.getItem().getClass());
31 return m_class.isAssignableFrom( accessor.getItem().getClass() );
32 } 27 }
33} 28}