1 28 29 package org.jibx.binding.classes; 30 31 import org.apache.bcel.generic.BranchHandle; 32 import org.apache.bcel.generic.InstructionHandle; 33 34 42 43 public class BranchWrapper 44 { 45 46 private static boolean s_trackSource; 47 48 49 private static boolean s_errorOverride; 50 51 52 private final BranchHandle m_branchHandle; 53 54 55 private final String [] m_stackTypes; 56 57 58 private final Object m_sourceObject; 59 60 61 private final Throwable m_sourceTrace; 62 63 70 71 BranchWrapper(BranchHandle hand, String [] types, Object src) { 72 m_branchHandle = hand; 73 m_stackTypes = types; 74 m_sourceObject = src; 75 if (s_trackSource) { 76 m_sourceTrace = new Throwable (); 77 } else { 78 m_sourceTrace = null; 79 } 80 } 81 82 87 88 String [] getStackState() { 89 return m_stackTypes; 90 } 91 92 98 99 private String describeStack(String [] types) { 100 StringBuffer buff = new StringBuffer (); 101 for (int i = 0; i < types.length; i++) { 102 buff.append(" "); 103 buff.append(i); 104 buff.append(": "); 105 buff.append(types[i]); 106 buff.append('\n'); 107 } 108 return buff.toString(); 109 } 110 111 121 122 private String buildReport(String text, String [] types, MethodBuilder mb) { 123 124 if (m_sourceTrace != null) { 126 System.err.println("Backtrack for branch source:"); 127 m_sourceTrace.printStackTrace(System.err); 128 } 129 130 StringBuffer buff = new StringBuffer (text); 132 buff.append("\n in method "); 133 buff.append(mb.getClassFile().getName()); 134 buff.append('.'); 135 buff.append(mb.getName()); 136 buff.append("\n generated by "); 137 buff.append(m_sourceObject.toString()); 138 buff.append("\n from stack:\n"); 139 buff.append(describeStack(m_stackTypes)); 140 buff.append(" to stack:\n"); 141 buff.append(describeStack(types)); 142 return buff.toString(); 143 } 144 145 153 154 void setTarget(InstructionHandle hand, String [] types, 155 MethodBuilder mb) { 156 157 if (types.length == m_stackTypes.length) { 159 boolean match = true; 160 for (int i = 0; i < types.length; i++) { 161 String stype = m_stackTypes[i]; 162 if (!types[i].equals(stype)) { 163 if (!"<null>".equals(types[i]) && !"<null>".equals(stype)) { 164 if (m_sourceTrace != null) { 165 System.err.println("Backtrack for branch source:"); 166 m_sourceTrace.printStackTrace(System.err); 167 } 168 String text = buildReport 169 ("Stack value type mismatch on branch", types, mb); 170 if (s_errorOverride) { 171 new Throwable (text).printStackTrace(System.err); 172 } else { 173 throw new IllegalStateException (text); 174 } 175 } 176 } 177 } 178 } else { 179 String text = 180 buildReport("Stack size mismatch on branch", types, mb); 181 if (s_errorOverride) { 182 new Throwable (text).printStackTrace(System.err); 183 } else { 184 throw new IllegalStateException (text); 185 } 186 } 187 188 m_branchHandle.setTarget(hand); 190 } 191 192 199 200 public void setTarget(BranchTarget target, MethodBuilder mb) { 201 setTarget(target.getInstruction(), target.getStack(), mb); 202 } 203 204 212 213 public static void setTracking(boolean track) { 214 s_trackSource = track; 215 } 216 217 225 226 public static void setErrorOverride(boolean over) { 227 s_errorOverride = over; 228 } 229 } | Popular Tags |