Package javassist.bytecode.stackmap

Source Code of javassist.bytecode.stackmap.BasicBlock$Mark

/*     */ package javassist.bytecode.stackmap;
/*     */
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collection;
/*     */ import java.util.HashMap;
/*     */ import javassist.bytecode.BadBytecode;
/*     */ import javassist.bytecode.CodeAttribute;
/*     */ import javassist.bytecode.CodeIterator;
/*     */ import javassist.bytecode.ExceptionTable;
/*     */ import javassist.bytecode.MethodInfo;
/*     */
/*     */ public class BasicBlock
/*     */ {
/*     */   public int position;
/*     */   public int length;
/*     */   public int incoming;
/*     */   public BasicBlock[] exit;
/*     */   public boolean stop;
/*     */   public Catch toCatch;
/*     */
/*     */   protected BasicBlock(int pos)
/*     */   {
/*  30 */     this.position = pos;
/*  31 */     this.length = 0;
/*  32 */     this.incoming = 0;
/*     */   }
/*     */
/*     */   public static BasicBlock find(BasicBlock[] blocks, int pos)
/*     */     throws BadBytecode
/*     */   {
/*  38 */     for (int i = 0; i < blocks.length; i++) {
/*  39 */       int iPos = blocks[i].position;
/*  40 */       if ((iPos <= pos) && (pos < iPos + blocks[i].length)) {
/*  41 */         return blocks[i];
/*     */       }
/*     */     }
/*  44 */     throw new BadBytecode("no basic block at " + pos);
/*     */   }
/*     */
/*     */   public String toString()
/*     */   {
/*  59 */     StringBuffer sbuf = new StringBuffer();
/*  60 */     String cname = getClass().getName();
/*  61 */     int i = cname.lastIndexOf('.');
/*  62 */     sbuf.append(i < 0 ? cname : cname.substring(i + 1));
/*  63 */     sbuf.append("[");
/*  64 */     toString2(sbuf);
/*  65 */     sbuf.append("]");
/*  66 */     return sbuf.toString();
/*     */   }
/*     */
/*     */   protected void toString2(StringBuffer sbuf) {
/*  70 */     sbuf.append("pos=").append(this.position).append(", len=").append(this.length).append(", in=").append(this.incoming).append(", exit{");
/*     */
/*  73 */     if (this.exit != null) {
/*  74 */       for (int i = 0; i < this.exit.length; i++) {
/*  75 */         sbuf.append(this.exit[i].position).append(", ");
/*     */       }
/*     */     }
/*  78 */     sbuf.append("}, {");
/*  79 */     Catch th = this.toCatch;
/*  80 */     while (th != null) {
/*  81 */       sbuf.append("(").append(th.body.position).append(", ").append(th.typeIndex).append("), ");
/*     */
/*  83 */       th = th.next;
/*     */     }
/*     */
/*  86 */     sbuf.append("}");
/*     */   }
/*     */
/*     */   public static class Maker
/*     */   {
/*     */     protected BasicBlock makeBlock(int pos)
/*     */     {
/* 127 */       return new BasicBlock(pos);
/*     */     }
/*     */
/*     */     protected BasicBlock[] makeArray(int size) {
/* 131 */       return new BasicBlock[size];
/*     */     }
/*     */
/*     */     private BasicBlock[] makeArray(BasicBlock b) {
/* 135 */       BasicBlock[] array = makeArray(1);
/* 136 */       array[0] = b;
/* 137 */       return array;
/*     */     }
/*     */
/*     */     private BasicBlock[] makeArray(BasicBlock b1, BasicBlock b2) {
/* 141 */       BasicBlock[] array = makeArray(2);
/* 142 */       array[0] = b1;
/* 143 */       array[1] = b2;
/* 144 */       return array;
/*     */     }
/*     */
/*     */     public BasicBlock[] make(MethodInfo minfo) throws BadBytecode {
/* 148 */       CodeAttribute ca = minfo.getCodeAttribute();
/* 149 */       if (ca == null) {
/* 150 */         return null;
/*     */       }
/* 152 */       CodeIterator ci = ca.iterator();
/* 153 */       return make(ci, 0, ci.getCodeLength(), ca.getExceptionTable());
/*     */     }
/*     */
/*     */     public BasicBlock[] make(CodeIterator ci, int begin, int end, ExceptionTable et)
/*     */       throws BadBytecode
/*     */     {
/* 160 */       HashMap marks = makeMarks(ci, begin, end, et);
/* 161 */       BasicBlock[] bb = makeBlocks(marks);
/* 162 */       addCatchers(bb, et);
/* 163 */       return bb;
/*     */     }
/*     */
/*     */     private BasicBlock.Mark makeMark(HashMap table, int pos)
/*     */     {
/* 169 */       return makeMark0(table, pos, true, true);
/*     */     }
/*     */
/*     */     private BasicBlock.Mark makeMark(HashMap table, int pos, BasicBlock[] jump, int size, boolean always)
/*     */     {
/* 177 */       BasicBlock.Mark m = makeMark0(table, pos, false, false);
/* 178 */       m.setJump(jump, size, always);
/* 179 */       return m;
/*     */     }
/*     */
/*     */     private BasicBlock.Mark makeMark0(HashMap table, int pos, boolean isBlockBegin, boolean isTarget)
/*     */     {
/* 184 */       Integer p = new Integer(pos);
/* 185 */       BasicBlock.Mark m = (BasicBlock.Mark)table.get(p);
/* 186 */       if (m == null) {
/* 187 */         m = new BasicBlock.Mark(pos);
/* 188 */         table.put(p, m);
/*     */       }
/*     */
/* 191 */       if (isBlockBegin) {
/* 192 */         if (m.block == null) {
/* 193 */           m.block = makeBlock(pos);
/*     */         }
/* 195 */         if (isTarget) {
/* 196 */           m.block.incoming += 1;
/*     */         }
/*     */       }
/* 199 */       return m;
/*     */     }
/*     */
/*     */     private HashMap makeMarks(CodeIterator ci, int begin, int end, ExceptionTable et)
/*     */       throws BadBytecode
/*     */     {
/* 206 */       ci.begin();
/* 207 */       ci.move(begin);
/* 208 */       HashMap marks = new HashMap();
/* 209 */       while (ci.hasNext()) {
/* 210 */         int index = ci.next();
/* 211 */         if (index >= end) {
/*     */           break;
/*     */         }
/* 214 */         int op = ci.byteAt(index);
/* 215 */         if (((153 <= op) && (op <= 166)) || (op == 198) || (op == 199))
/*     */         {
/* 217 */           BasicBlock.Mark to = makeMark(marks, index + ci.s16bitAt(index + 1));
/* 218 */           BasicBlock.Mark next = makeMark(marks, index + 3);
/* 219 */           makeMark(marks, index, makeArray(to.block, next.block), 3, false);
/*     */         }
/* 221 */         else if ((167 <= op) && (op <= 171)) {
/* 222 */           switch (op) {
/*     */           case 167:
/*     */           case 168:
/* 225 */             makeGotoJsr(marks, index, index + ci.s16bitAt(index + 1), op == 167, 3);
/*     */
/* 227 */             break;
/*     */           case 169:
/* 229 */             makeMark(marks, index, null, 1, true);
/* 230 */             break;
/*     */           case 170:
/* 232 */             int pos = (index & 0xFFFFFFFC) + 4;
/* 233 */             int low = ci.s32bitAt(pos + 4);
/* 234 */             int high = ci.s32bitAt(pos + 8);
/* 235 */             int ncases = high - low + 1;
/* 236 */             BasicBlock[] to = makeArray(ncases + 1);
/* 237 */             to[0] = makeMark(marks, index + ci.s32bitAt(pos)).block;
/* 238 */             int p = pos + 12;
/* 239 */             int n = p + ncases * 4;
/* 240 */             int k = 1;
/* 241 */             while (p < n) {
/* 242 */               to[(k++)] = makeMark(marks, index + ci.s32bitAt(p)).block;
/* 243 */               p += 4;
/*     */             }
/* 245 */             makeMark(marks, index, to, n - index, true);
/* 246 */             break;
/*     */           case 171:
/* 248 */             int pos = (index & 0xFFFFFFFC) + 4;
/* 249 */             int ncases = ci.s32bitAt(pos + 4);
/* 250 */             BasicBlock[] to = makeArray(ncases + 1);
/* 251 */             to[0] = makeMark(marks, index + ci.s32bitAt(pos)).block;
/* 252 */             int p = pos + 8 + 4;
/* 253 */             int n = p + ncases * 8 - 4;
/* 254 */             int k = 1;
/* 255 */             while (p < n) {
/* 256 */               to[(k++)] = makeMark(marks, index + ci.s32bitAt(p)).block;
/* 257 */               p += 8;
/*     */             }
/* 259 */             makeMark(marks, index, to, n - index, true);
/* 260 */             break;
/*     */           }
/* 262 */         } else if (((172 <= op) && (op <= 177)) || (op == 191)) {
/* 263 */           makeMark(marks, index, null, 1, true);
/* 264 */         } else if ((op == 200) || (op == 201)) {
/* 265 */           makeGotoJsr(marks, index, index + ci.s32bitAt(index + 1), op == 200, 5);
/*     */         }
/* 267 */         else if ((op == 196) && (ci.byteAt(index + 1) == 169)) {
/* 268 */           makeMark(marks, index, null, 1, true);
/*     */         }
/*     */       }
/* 271 */       if (et != null) {
/* 272 */         int i = et.size();
/*     */         while (true) { i--; if (i < 0) break;
/* 274 */           makeMark0(marks, et.startPc(i), true, false);
/* 275 */           makeMark(marks, et.handlerPc(i));
/*     */         }
/*     */       }
/*     */
/* 279 */       return marks;
/*     */     }
/*     */
/*     */     private void makeGotoJsr(HashMap marks, int pos, int target, boolean isGoto, int size) {
/* 283 */       BasicBlock.Mark to = makeMark(marks, target);
/*     */       BasicBlock[] jumps;
/*     */       BasicBlock[] jumps;
/* 285 */       if (isGoto) {
/* 286 */         jumps = makeArray(to.block);
/*     */       } else {
/* 288 */         BasicBlock.Mark next = makeMark(marks, pos + size);
/* 289 */         jumps = makeArray(to.block, next.block);
/*     */       }
/*     */
/* 292 */       makeMark(marks, pos, jumps, size, isGoto);
/*     */     }
/*     */
/*     */     private BasicBlock[] makeBlocks(HashMap markTable) {
/* 296 */       BasicBlock.Mark[] marks = (BasicBlock.Mark[])(BasicBlock.Mark[])markTable.values().toArray(new BasicBlock.Mark[markTable.size()]);
/*     */
/* 298 */       Arrays.sort(marks);
/* 299 */       ArrayList blocks = new ArrayList();
/* 300 */       int i = 0;
/*     */       BasicBlock prev;
/*     */       BasicBlock prev;
/* 302 */       if ((marks.length > 0) && (marks[0].position == 0) && (marks[0].block != null))
/* 303 */         prev = getBBlock(marks[(i++)]);
/*     */       else {
/* 305 */         prev = makeBlock(0);
/*     */       }
/* 307 */       blocks.add(prev);
/* 308 */       while (i < marks.length) {
/* 309 */         BasicBlock.Mark m = marks[(i++)];
/* 310 */         BasicBlock bb = getBBlock(m);
/* 311 */         if (bb == null)
/*     */         {
/* 313 */           if (prev.length > 0)
/*     */           {
/* 315 */             prev = makeBlock(prev.position + prev.length);
/* 316 */             blocks.add(prev);
/*     */           }
/*     */
/* 319 */           prev.length = (m.position + m.size - prev.position);
/* 320 */           prev.exit = m.jump;
/* 321 */           prev.stop = m.alwaysJmp;
/*     */         }
/*     */         else
/*     */         {
/* 325 */           if (prev.length == 0) {
/* 326 */             prev.length = (m.position - prev.position);
/* 327 */             bb.incoming += 1;
/* 328 */             prev.exit = makeArray(bb);
/*     */           }
/*     */           else
/*     */           {
/* 332 */             int prevPos = prev.position;
/* 333 */             if (prevPos + prev.length < m.position) {
/* 334 */               prev = makeBlock(prevPos + prev.length);
/* 335 */               prev.length = (m.position - prevPos);
/*     */
/* 338 */               prev.exit = makeArray(bb);
/*     */             }
/*     */           }
/*     */
/* 342 */           blocks.add(bb);
/* 343 */           prev = bb;
/*     */         }
/*     */       }
/*     */
/* 347 */       return (BasicBlock[])(BasicBlock[])blocks.toArray(makeArray(blocks.size()));
/*     */     }
/*     */
/*     */     private static BasicBlock getBBlock(BasicBlock.Mark m) {
/* 351 */       BasicBlock b = m.block;
/* 352 */       if ((b != null) && (m.size > 0)) {
/* 353 */         b.exit = m.jump;
/* 354 */         b.length = m.size;
/* 355 */         b.stop = m.alwaysJmp;
/*     */       }
/*     */
/* 358 */       return b;
/*     */     }
/*     */
/*     */     private void addCatchers(BasicBlock[] blocks, ExceptionTable et)
/*     */       throws BadBytecode
/*     */     {
/* 364 */       if (et == null) {
/* 365 */         return;
/*     */       }
/* 367 */       int i = et.size();
/*     */       while (true) { i--; if (i < 0) break;
/* 369 */         BasicBlock handler = BasicBlock.find(blocks, et.handlerPc(i));
/* 370 */         int start = et.startPc(i);
/* 371 */         int end = et.endPc(i);
/* 372 */         int type = et.catchType(i);
/* 373 */         handler.incoming -= 1;
/* 374 */         for (int k = 0; k < blocks.length; k++) {
/* 375 */           BasicBlock bb = blocks[k];
/* 376 */           int iPos = bb.position;
/* 377 */           if ((start <= iPos) && (iPos < end)) {
/* 378 */             bb.toCatch = new BasicBlock.Catch(handler, type, bb.toCatch);
/* 379 */             handler.incoming += 1;
/*     */           }
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   static class Mark
/*     */     implements Comparable
/*     */   {
/*     */     int position;
/*     */     BasicBlock block;
/*     */     BasicBlock[] jump;
/*     */     boolean alwaysJmp;
/*     */     int size;
/*     */     BasicBlock.Catch catcher;
/*     */
/*     */     Mark(int p)
/*     */     {
/*  98 */       this.position = p;
/*  99 */       this.block = null;
/* 100 */       this.jump = null;
/* 101 */       this.alwaysJmp = false;
/* 102 */       this.size = 0;
/* 103 */       this.catcher = null;
/*     */     }
/*     */
/*     */     public int compareTo(Object obj) {
/* 107 */       if ((obj instanceof Mark)) {
/* 108 */         int pos = ((Mark)obj).position;
/* 109 */         return this.position - pos;
/*     */       }
/*     */
/* 112 */       return -1;
/*     */     }
/*     */
/*     */     void setJump(BasicBlock[] bb, int s, boolean always) {
/* 116 */       this.jump = bb;
/* 117 */       this.size = s;
/* 118 */       this.alwaysJmp = always;
/*     */     }
/*     */   }
/*     */
/*     */   public static class Catch
/*     */   {
/*     */     Catch next;
/*     */     BasicBlock body;
/*     */     int typeIndex;
/*     */
/*     */     Catch(BasicBlock b, int i, Catch c)
/*     */     {
/*  52 */       this.body = b;
/*  53 */       this.typeIndex = i;
/*  54 */       this.next = c;
/*     */     }
/*     */   }
/*     */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/thirdparty-all.jar
* Qualified Name:     javassist.bytecode.stackmap.BasicBlock
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of javassist.bytecode.stackmap.BasicBlock$Mark

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.