summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/bytecode/CheckCastIterator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/bytecode/CheckCastIterator.java')
-rw-r--r--src/cuchaz/enigma/bytecode/CheckCastIterator.java126
1 files changed, 126 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..b6efbd4
--- /dev/null
+++ b/src/cuchaz/enigma/bytecode/CheckCastIterator.java
@@ -0,0 +1,126 @@
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 this.className = className;
34 this.prevMethodEntry = prevMethodEntry;
35 }
36 }
37
38 private ConstPool m_constants;
39 private CodeAttribute m_attribute;
40 private CodeIterator m_iter;
41 private CheckCast m_next;
42
43 public CheckCastIterator(CodeAttribute codeAttribute) throws BadBytecode {
44 m_constants = codeAttribute.getConstPool();
45 m_attribute = codeAttribute;
46 m_iter = m_attribute.iterator();
47
48 m_next = getNext();
49 }
50
51 @Override
52 public boolean hasNext() {
53 return m_next != null;
54 }
55
56 @Override
57 public CheckCast next() {
58 CheckCast out = m_next;
59 try {
60 m_next = getNext();
61 } catch (BadBytecode ex) {
62 throw new Error(ex);
63 }
64 return out;
65 }
66
67 @Override
68 public void remove() {
69 throw new UnsupportedOperationException();
70 }
71
72 private CheckCast getNext() throws BadBytecode {
73 int prevPos = 0;
74 while (m_iter.hasNext()) {
75 int pos = m_iter.next();
76 int opcode = m_iter.byteAt(pos);
77 switch (opcode) {
78 case Opcode.CHECKCAST:
79
80 // get the type of this op code (next two bytes are a classinfo index)
81 MethodEntry prevMethodEntry = getMethodEntry(prevPos);
82 if (prevMethodEntry != null) {
83 return new CheckCast(m_constants.getClassInfo(m_iter.s16bitAt(pos + 1)), prevMethodEntry);
84 }
85 break;
86 }
87 prevPos = pos;
88 }
89 return null;
90 }
91
92 private MethodEntry getMethodEntry(int pos) {
93 switch (m_iter.byteAt(pos)) {
94 case Opcode.INVOKEVIRTUAL:
95 case Opcode.INVOKESTATIC:
96 case Opcode.INVOKEDYNAMIC:
97 case Opcode.INVOKESPECIAL: {
98 int index = m_iter.s16bitAt(pos + 1);
99 return new MethodEntry(
100 new ClassEntry(Descriptor.toJvmName(m_constants.getMethodrefClassName(index))),
101 m_constants.getMethodrefName(index),
102 m_constants.getMethodrefType(index)
103 );
104 }
105
106 case Opcode.INVOKEINTERFACE: {
107 int index = m_iter.s16bitAt(pos + 1);
108 return new MethodEntry(
109 new ClassEntry(Descriptor.toJvmName(m_constants.getInterfaceMethodrefClassName(index))),
110 m_constants.getInterfaceMethodrefName(index),
111 m_constants.getInterfaceMethodrefType(index)
112 );
113 }
114 }
115 return null;
116 }
117
118 public Iterable<CheckCast> casts() {
119 return new Iterable<CheckCast>() {
120 @Override
121 public Iterator<CheckCast> iterator() {
122 return CheckCastIterator.this;
123 }
124 };
125 }
126}