/* Copyright (c) 2006, Sriram Srinivasan * * You may distribute this software under the terms of the license * specified in the file "License" */ package kilim.analysis; import static kilim.Constants.THROWABLE_CLASS; import java.util.ArrayList; import java.util.Collections; /** * Representation for a catch handler. */ public class Handler implements Comparable<Handler> { /** * Source offset in method's instruction list */ public int from; /** * End offset in method's instruction list */ public int to; /** * Exception type */ public String type; /** * catch handler's entry point */ public BasicBlock catchBB; public Handler(int aFrom, int aTo, String aType, BasicBlock aCatchBB) { from = aFrom; to = aTo; if (aType == null) { // try/finally is compiled with a covering catch handler with // type null. It is the same as catching Throwable. aType = THROWABLE_CLASS; } type = aType; catchBB = aCatchBB; } public int compareTo(Handler h) { int c = this.type.compareTo(h.type); if (c != 0) return c; c = this.catchBB.compareTo(h.catchBB); if (c != 0) return c; return from < h.from ? -1 : (from == h.from) ? 0 : 1; } public static ArrayList<Handler> consolidate( ArrayList<Handler> list) { Collections.sort(list); ArrayList<Handler> newList = new ArrayList<Handler>(list.size()); Handler cur = null; for (Handler h: list) { if (cur == null) { cur = h; newList.add(cur); continue; } // Two options here. Either h is contiguous with c or it isn't. Contiguous // means that it has to be the same type and the same catchBB and // from == to+1 if (cur.type.equals(h.type) && (cur.catchBB == h.catchBB) && (h.from == cur.to + 1)) { cur.to = h.to; } else { cur = h; newList.add(cur); } } return newList; } }