diff options
Diffstat (limited to 'src/cuchaz/enigma/bytecode')
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; | |||
| 18 | import javassist.bytecode.CodeIterator; | 18 | import javassist.bytecode.CodeIterator; |
| 19 | import javassist.bytecode.Opcode; | 19 | import javassist.bytecode.Opcode; |
| 20 | 20 | ||
| 21 | public class BytecodeIndexIterator implements Iterator<BytecodeIndexIterator.Index> | 21 | public 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; | |||
| 34 | import cuchaz.enigma.bytecode.BytecodeIndexIterator.Index; | 34 | import cuchaz.enigma.bytecode.BytecodeIndexIterator.Index; |
| 35 | import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; | 35 | import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; |
| 36 | 36 | ||
| 37 | public class BytecodeTools | 37 | public 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; | |||
| 22 | import cuchaz.enigma.mapping.ClassEntry; | 22 | import cuchaz.enigma.mapping.ClassEntry; |
| 23 | import cuchaz.enigma.mapping.MethodEntry; | 23 | import cuchaz.enigma.mapping.MethodEntry; |
| 24 | 24 | ||
| 25 | public class CheckCastIterator implements Iterator<CheckCast> | 25 | public 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; | |||
| 27 | import cuchaz.enigma.mapping.SignatureUpdater; | 27 | import cuchaz.enigma.mapping.SignatureUpdater; |
| 28 | import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; | 28 | import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; |
| 29 | 29 | ||
| 30 | public class ClassRenamer | 30 | public 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; | |||
| 28 | import cuchaz.enigma.mapping.MethodEntry; | 28 | import cuchaz.enigma.mapping.MethodEntry; |
| 29 | import cuchaz.enigma.mapping.Translator; | 29 | import cuchaz.enigma.mapping.Translator; |
| 30 | 30 | ||
| 31 | public class ClassTranslator | 31 | public 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; | |||
| 23 | import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; | 23 | import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; |
| 24 | import cuchaz.enigma.bytecode.accessors.MemberRefInfoAccessor; | 24 | import cuchaz.enigma.bytecode.accessors.MemberRefInfoAccessor; |
| 25 | 25 | ||
| 26 | public class ConstPoolEditor | 26 | public 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; | |||
| 26 | import cuchaz.enigma.bytecode.accessors.NameAndTypeInfoAccessor; | 26 | import cuchaz.enigma.bytecode.accessors.NameAndTypeInfoAccessor; |
| 27 | import cuchaz.enigma.bytecode.accessors.StringInfoAccessor; | 27 | import cuchaz.enigma.bytecode.accessors.StringInfoAccessor; |
| 28 | 28 | ||
| 29 | public enum InfoType | 29 | public 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; | |||
| 23 | import cuchaz.enigma.mapping.BehaviorEntry; | 23 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 24 | import cuchaz.enigma.mapping.ClassEntry; | 24 | import cuchaz.enigma.mapping.ClassEntry; |
| 25 | 25 | ||
| 26 | public class InnerClassWriter | 26 | public 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; | |||
| 25 | import cuchaz.enigma.mapping.MethodEntry; | 25 | import cuchaz.enigma.mapping.MethodEntry; |
| 26 | import cuchaz.enigma.mapping.Translator; | 26 | import cuchaz.enigma.mapping.Translator; |
| 27 | 27 | ||
| 28 | public class MethodParameterWriter | 28 | public 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; | |||
| 20 | import javassist.bytecode.ConstPool; | 20 | import javassist.bytecode.ConstPool; |
| 21 | import javassist.bytecode.MethodInfo; | 21 | import javassist.bytecode.MethodInfo; |
| 22 | 22 | ||
| 23 | public class MethodParametersAttribute extends AttributeInfo | 23 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class ClassInfoAccessor | 15 | public 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 | ||
| 23 | import cuchaz.enigma.bytecode.InfoType; | 23 | import cuchaz.enigma.bytecode.InfoType; |
| 24 | 24 | ||
| 25 | public class ConstInfoAccessor | 25 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class InvokeDynamicInfoAccessor | 15 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class MemberRefInfoAccessor | 15 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class MethodHandleInfoAccessor | 15 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class MethodTypeInfoAccessor | 15 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class NameAndTypeInfoAccessor | 15 | public 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 | ||
| 13 | import java.lang.reflect.Field; | 13 | import java.lang.reflect.Field; |
| 14 | 14 | ||
| 15 | public class StringInfoAccessor | 15 | public 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 | ******************************************************************************/ |
| 11 | package cuchaz.enigma.bytecode.accessors; | 11 | package cuchaz.enigma.bytecode.accessors; |
| 12 | 12 | ||
| 13 | public class Utf8InfoAccessor | 13 | public 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 | } |