summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar jeff2014-08-25 16:49:41 -0400
committerGravatar jeff2014-08-25 16:49:41 -0400
commitb469814281b063c8ea6a752c28de7b2fdcca2cac (patch)
treecb327c0515b118f1f573c16c8d0ddc2b07116106 /src
parentsilly mercurial. You should commit this file... (diff)
downloadenigma-fork-b469814281b063c8ea6a752c28de7b2fdcca2cac.tar.gz
enigma-fork-b469814281b063c8ea6a752c28de7b2fdcca2cac.tar.xz
enigma-fork-b469814281b063c8ea6a752c28de7b2fdcca2cac.zip
wrote CheckCastIterator to try to do generic type inference. It's too hard to do at the bytecode level though, so I'm tabling that problem for now.
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/bytecode/CheckCastIterator.java150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/bytecode/CheckCastIterator.java b/src/cuchaz/enigma/bytecode/CheckCastIterator.java
new file mode 100644
index 0000000..7ed5d7f
--- /dev/null
+++ b/src/cuchaz/enigma/bytecode/CheckCastIterator.java
@@ -0,0 +1,150 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.bytecode;
12
13import java.util.Iterator;
14
15import javassist.bytecode.BadBytecode;
16import javassist.bytecode.CodeAttribute;
17import javassist.bytecode.CodeIterator;
18import javassist.bytecode.ConstPool;
19import javassist.bytecode.Descriptor;
20import javassist.bytecode.Opcode;
21import cuchaz.enigma.bytecode.CheckCastIterator.CheckCast;
22import cuchaz.enigma.mapping.ClassEntry;
23import cuchaz.enigma.mapping.MethodEntry;
24
25public class CheckCastIterator implements Iterator<CheckCast>
26{
27 public static class CheckCast
28 {
29 public String className;
30 public MethodEntry prevMethodEntry;
31
32 public CheckCast( String className, MethodEntry prevMethodEntry )
33 {
34 this.className = className;
35 this.prevMethodEntry = prevMethodEntry;
36 }
37 }
38
39 private ConstPool m_constants;
40 private CodeAttribute m_attribute;
41 private CodeIterator m_iter;
42 private CheckCast m_next;
43
44 public CheckCastIterator( CodeAttribute codeAttribute )
45 throws BadBytecode
46 {
47 m_constants = codeAttribute.getConstPool();
48 m_attribute = codeAttribute;
49 m_iter = m_attribute.iterator();
50
51 m_next = getNext();
52 }
53
54 @Override
55 public boolean hasNext( )
56 {
57 return m_next != null;
58 }
59
60 @Override
61 public CheckCast next( )
62 {
63 CheckCast out = m_next;
64 try
65 {
66 m_next = getNext();
67 }
68 catch( BadBytecode ex )
69 {
70 throw new Error( ex );
71 }
72 return out;
73 }
74
75 @Override
76 public void remove( )
77 {
78 throw new UnsupportedOperationException();
79 }
80
81 private CheckCast getNext( )
82 throws BadBytecode
83 {
84 int prevPos = 0;
85 while( m_iter.hasNext() )
86 {
87 int pos = m_iter.next();
88 int opcode = m_iter.byteAt( pos );
89 switch( opcode )
90 {
91 case Opcode.CHECKCAST:
92
93 // get the type of this op code (next two bytes are a classinfo index)
94 MethodEntry prevMethodEntry = getMethodEntry( prevPos );
95 if( prevMethodEntry != null )
96 {
97 return new CheckCast(
98 m_constants.getClassInfo( m_iter.s16bitAt( pos + 1 ) ),
99 prevMethodEntry
100 );
101 }
102 break;
103 }
104 prevPos = pos;
105 }
106 return null;
107 }
108
109 private MethodEntry getMethodEntry( int pos )
110 {
111 switch( m_iter.byteAt( pos ) )
112 {
113 case Opcode.INVOKEVIRTUAL:
114 case Opcode.INVOKESTATIC:
115 case Opcode.INVOKEDYNAMIC:
116 case Opcode.INVOKESPECIAL:
117 {
118 int index = m_iter.s16bitAt( pos + 1 );
119 return new MethodEntry(
120 new ClassEntry( Descriptor.toJvmName( m_constants.getMethodrefClassName( index ) ) ),
121 m_constants.getMethodrefName( index ),
122 m_constants.getMethodrefType( index )
123 );
124 }
125
126 case Opcode.INVOKEINTERFACE:
127 {
128 int index = m_iter.s16bitAt( pos + 1 );
129 return new MethodEntry(
130 new ClassEntry( Descriptor.toJvmName( m_constants.getInterfaceMethodrefClassName( index ) ) ),
131 m_constants.getInterfaceMethodrefName( index ),
132 m_constants.getInterfaceMethodrefType( index )
133 );
134 }
135 }
136 return null;
137 }
138
139 public Iterable<CheckCast> casts( )
140 {
141 return new Iterable<CheckCast>( )
142 {
143 @Override
144 public Iterator<CheckCast> iterator( )
145 {
146 return CheckCastIterator.this;
147 }
148 };
149 }
150}