KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jbet > DagSnippit


1 /*
2  * JBET - Java Binary Enhancement Tool
3  * Copyright (c) 2003 Networks Associates Technology, Inc.
4  *
5  * This software was developed under DARPA/SPAWAR contract
6  * N66001-00-C-8602 "SPMA" as part of the
7  * DARPA OASIS research program.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */

30
31 package jbet;
32 import java.util.*;
33 import java.lang.reflect.*;
34
35 /* Represents a list of basic blocks. This is used in two ways: as the initial
36  * representation of a method's code as value DAGs, and as a container for the
37  * final list of independant basic blocks. A DagMethodInfo contains one DagSnippit
38  * structure.
39  *
40  * @author Andrew Reisse
41  */

42
43 public class DagSnippit {
44
45     public static String JavaDoc JbetLogFacility = "dags";
46
47     public Vector bbs; // vector of output blocks
48
public DagMethodInfo method; // containing method
49
public Node.param[] params; // array of block inputs
50
public int blflags; // Block.Blc flags for all blocks
51

52     Vector inbbs; //cache the inbbs vector from graphify so we don't need it when we re-graphify
53

54     public BasicBlock blockAt (int i) {
55     return (BasicBlock) (bbs.elementAt (i));
56     }
57
58     abstract public static class Modifier
59     {
60       abstract public void f (DagSnippit dags);
61     }
62
63     /** constructor.
64      */

65     public DagSnippit () { }
66
67     /** Convert one method's InstrBlocks to BasicBlocks.
68      * Linking outputs of a block to inputs of its successors is also done here.
69      *
70      * @param mi The method to convert
71      * @return DAG representing the method
72      */

73     public static DagSnippit graphify (MethodInfo mi) throws ClassFileException, DataFlowException, ElementNotFoundException {
74     return graphify(mi, ClassFilter.ALL);
75     }
76
77     /** Convert one method's InstrBlocks to BasicBlocks.
78      * Linking outputs of a block to inputs of its successors is also done here.
79      *
80      * @param mi The method to graphify
81      * @param fixcons Function that says whether to replace new with invokeinit
82      * @return DAG representing the method
83      */

84
85     public static DagSnippit graphify (MethodInfo mi, ClassFilter fixcons)
86     throws ClassFileException, DataFlowException, ElementNotFoundException {
87     return graphify (mi, fixcons, null, null);
88     }
89
90     public static DagSnippit graphify (MethodInfo mi, ClassFilter fixcons, DagSnippit inme, int [] permutation)
91     throws ClassFileException, DataFlowException, ElementNotFoundException {
92
93     final DagSnippit me = (inme==null) ? new DagSnippit() : inme;
94
95     Node.New.newcount = 0;
96
97     final Vector inbbs = (me.inbbs==null) ? InstrBlock.FindBasicBlocks (mi, null) : me.inbbs;
98     me.inbbs = inbbs;
99
100     if (inbbs == null)
101         return null;
102     Vector outbbs = new Vector(); // temp used to build up me.bbs
103

104     me.params = new Node.param
105         [ mi.descriptor.count()-1 + (mi.isStatic() ? 0 : 1) ];
106     int param_lv = 0;
107     if (!mi.isStatic()) {
108         me.params[param_lv] = new Node.param(param_lv, new Type(mi.cr));
109         param_lv++;
110     }
111     for (int i = 0; i < mi.descriptor.args.length; i++, param_lv++) {
112         me.params[param_lv] = new Node.param(param_lv, mi.descriptor.args[i]);
113         if (mi.descriptor.args[i].category() == 2)
114         param_lv++;
115     }
116
117     AliasDB currdb = null;
118
119     // build dags for each basic block
120
for (int i = 0; i < inbbs.size(); i++) {
121         IntFunction inserials;
122         int j;
123         if (permutation == null) {
124         currdb = new AliasDB();
125         inserials = null;
126         j = i+1;
127         } else {
128         j = permutation[i];
129         if (j < 0) {
130             currdb = new AliasDB();
131             j = -j;
132         }
133         inserials = new IntFunction() {
134             public int f(int n) {
135                 return (n==0) ? 1 : -1;
136             }
137             };
138         }
139         InstrBlock ib = (InstrBlock) inbbs.elementAt (j-1);
140         if (ib.pse != null && ib.psx != null) {
141         BasicBlock newblock = me.bbs==null ? new BasicBlock() : me.blockAt(j-1);
142         newblock.model (ib, fixcons, inserials, currdb);
143         outbbs.addElement(newblock);
144         }
145     }
146
147     /* copy exit records */
148     for (int i = 0; i < outbbs.size(); i++) {
149         BasicBlock sb = (BasicBlock) outbbs.elementAt (i);
150         InstrBlock in = (InstrBlock) inbbs.elementAt (i);
151
152         sb.es.op = in.es.op;
153         sb.es.stackuse = in.es.stackuse;
154
155         sb.es.primary = in.es.primary != null ?
156         (BasicBlock) outbbs.elementAt (in.es.primary.swval - 1) : null;
157         sb.es.jump = in.es.jump != null ?
158         (BasicBlock) outbbs.elementAt (in.es.jump.swval - 1) : null;
159         sb.es.ret = in.es.ret != null ?
160         (BasicBlock) outbbs.elementAt (in.es.ret.swval - 1) : null;
161
162         if (in.es.switches != null) {
163           BranchTarget[] switches = new BranchTarget [in.es.switches.length];
164           sb.es.switches = switches;
165           sb.es.swofs = in.es.swofs;
166
167           for (int j = 0; j < switches.length; j++)
168         if (in.es.switches[j] != null) {
169           switches[j] = new BranchTarget();
170           switches[j].key = in.es.switches[j].key;
171           switches[j].block = (BasicBlock) outbbs.elementAt (in.es.switches[j].block.swval-1);
172         }
173         }
174
175         if (in.es.exceptions != null) {
176           sb.es.exceptions = new Vector();
177
178           for (int j = 0; j < in.es.exceptions.size(); j++) {
179         Block.ExcInfo eo = in.es.exAt (j);
180         Block.ExcInfo er = new Block.ExcInfo();
181
182         er.handler = (BasicBlock) outbbs.elementAt (eo.handler.swval-1);
183         er.type = eo.type;
184         er.info = eo.info;
185
186         sb.es.exceptions.addElement (er);
187           }
188         }
189     } // for
190

191     Jbet.debug.println ("SUCCESSORS");
192     /* calculate the predecessors of every block */
193     final Vector [] pred = new Vector [ outbbs.size() ];
194     for (int i = 0; i < pred.length; i++)
195         pred[i] = new Vector();
196     for (int i = 0; i < outbbs.size(); i++) {
197         BasicBlock sb = (BasicBlock) outbbs.elementAt (i);
198         Jbet.debug.print(" #B" + sb.swval);
199         for (Enumeration e = sb.getSuccessors().elements();
200          e.hasMoreElements();) {
201         BasicBlock succ = (BasicBlock) e.nextElement();
202         Jbet.debug.print(" " + succ.swval);
203         pred[succ.swval-1].addElement(sb);
204         }
205         Jbet.debug.println();
206     }
207
208     Jbet.debug.println();
209     Jbet.debug.println ("PREDECESSORS");
210     for (int i = 0; i < pred.length; i++) {
211         Vector v = pred[i];
212         ((Block)outbbs.elementAt(i)).pred = pred[i];
213
214         Jbet.debug.print (" #B" + (i+1));
215         for (int j = 0; j < v.size(); j++)
216         Jbet.debug.print (" " + ((Block)v.elementAt (j)).swval);
217         Jbet.debug.println ();
218     }
219     Jbet.debug.println();
220
221     /* we recompute the output array for each block */
222     final HashSet [] newouts = new HashSet [ outbbs.size() ];
223     for (int i = 0; i < newouts.length; i++)
224         newouts[i] = new HashSet();
225     final HashSet visited = new HashSet();
226
227     
228     class _util {
229         /* if traceing through trivial assignments only reaches a
230                single node then we can just link to it */

231         Node nontrivial;
232         int depth = 0;
233
234         void println(String JavaDoc s) {
235         for (int i = 0; i < depth; i++) Jbet.debug.print(" ");
236         Jbet.debug.println(s);
237         }
238
239         void in() { depth += 2; }
240
241         void out() {depth -= 2; }
242
243         void find_producers (Node.var var, BasicBlock sb) throws ClassFileException, ElementNotFoundException {
244         println ("FP: " + var + " #" + sb.swval);
245         in();
246         try {
247             if (sb.swval == 1 && var.v < me.params.length && var.v >= 0){
248             var.producers.add(me.params[var.v]);
249             println ("found " + me.params[var.v]);
250             }
251             if (sb.handler != null) { // this is an exception handler
252
if (var.v == -1) {
253                 var.exobject = true;
254                 return;
255             } else if (var.v < 0)
256                 throw new IllegalStateException JavaDoc ("bad stack for exception handler");
257             }
258             for (Enumeration e = pred[sb.swval-1].elements();
259              e.hasMoreElements();) {
260             fpHelper (var, (BasicBlock) e.nextElement());
261             }
262         } finally {
263             out();
264         }
265         }
266
267         //bottom of block
268
void fpHelper (Node.var var, BasicBlock sb) throws ClassFileException, ElementNotFoundException {
269         println ("H: " + var + " " + sb.swval);
270         in();
271         try {
272             if (visited.contains(sb)) {
273             println("cutoff");
274             return;
275             }
276             visited.add(sb);
277             boolean good = false;
278             for (int i = 0; i < sb.outputs.length; i++) {
279             if (!(sb.outputs[i] instanceof Node.assign)) continue;
280             Node.assign assign = (Node.assign) sb.outputs[i];
281             if (assign.lvt != var.v) continue;
282             var.producers.add( assign.val );
283             println("found " + assign.val);
284             good = true;
285             break;
286             }
287             if (good) {
288             boolean bigbadexception = false;
289             if (sb.es.exceptions != null) {
290                 for (Iterator i = sb.senodes.iterator();
291                  i.hasNext() && !bigbadexception ;) {
292                 Node sen = (Node) i.next();
293                 MethodSignature ms1 = null;
294                 if (sen instanceof Node.invokes)
295                     ms1 = ((Node.invokes)sen).method;
296                 if (sen instanceof Node.invokev)
297                     ms1 = ((Node.invokev)sen).method;
298                 if (ms1 == null) continue;
299                 MethodInfo ms = ms1.resolveAny();
300
301                 for (int j = 0; j < ms.exceptions.size(); j++) {
302                     String JavaDoc exstr = (String JavaDoc)
303                     ms.exceptions.elementAt(j);
304                     for (int k = 0; k < sb.es.exceptions.size(); k++) {
305                     Block.ExcInfo exinfo = (Block.ExcInfo) sb.es.exceptions.elementAt(k);
306                     println("YAKYAK " + exinfo.type);
307                     if (ClassInfo.isAncestor (exstr, exinfo.type))
308                         bigbadexception = true;
309                     }
310                 }
311                 for (int k = 0; k < sb.es.exceptions.size(); k++) {
312                     Block.ExcInfo exinfo = (Block.ExcInfo) sb.es.exceptions.elementAt(k);
313                     if (ClassInfo.isAncestor (exinfo.type, "java/lang/RuntimeException") ||
314                     ClassInfo.isAncestor (exinfo.type, "java/lang/Error"))
315                     bigbadexception = true;
316                 }
317                 }
318             } // if exceptions nonnull
319
if (bigbadexception) {
320                 println ("bad exceptoin thing!!!");
321                 find_producers (var, sb);
322             } else
323                 return;
324             }
325             println ("notfound");
326             find_producers (var, sb);
327         } finally {
328             out();
329         }
330         }
331         
332         Node uniqueProducer;
333
334         // _util.setUniqueProducer
335
boolean setUniqueProducer(Node f) {
336         if (f == null) throw new IllegalStateException JavaDoc("yak!");
337         if (uniqueProducer != null && !uniqueProducer.equals(f)) {
338             println ("double uniqueProducer ! " + uniqueProducer + " " + f);
339             return false;
340         } else {
341             uniqueProducer = f;
342             println ("uniqueProducer set to " + uniqueProducer);
343             return true;
344         }
345         }
346
347         // _util.trace
348
boolean trace (Node.var var) {
349         println("trace " + var);
350         in();
351         try {
352             if (visited.contains(var)) {
353             println ("cutoff");
354             return true;
355             }
356             visited.add(var);
357             for (Iterator i = var.producers.iterator(); i.hasNext();) {
358             Object JavaDoc o = i.next();
359             if (o instanceof Node.var) {
360                 if (!trace ((Node.var) o)) return false ;
361             } else {
362                 println("setting to " + o);
363                 if (!setUniqueProducer((Node) o)) return false;
364             }
365             }
366             return uniqueProducer != null;
367         } finally { out(); }
368         }
369
370         // _util.link
371
void link (Node from, Node.var to) {
372         println ("arrow " + from + " -> " + to);
373         from.addDestination(to);
374         to.producers.add(from);
375         if (from.sb != null)
376             newouts[from.sb.swval-1].add (from);
377         else if (!(from instanceof Node.param)) throw new
378             IllegalStateException JavaDoc ("a non-param node has no block: " + from);
379         }
380
381         // _util.link
382
void link (Node.var var) {
383         println("link " + var);
384         in();
385         try {
386             uniqueProducer = null;
387             if ( trace (var) ) {
388             var.producers.clear();
389             println ("linking " + uniqueProducer);
390             link (uniqueProducer, var);
391             println ("good trace " + uniqueProducer);
392             } else
393             for (Iterator i = var.producers.iterator();
394                  i.hasNext();)
395                 link ((Node) i.next(), var);
396         } finally { out(); }
397         }
398         
399         /*
400         // _util.tracecall
401         void traceall (Node.var var, BasicBlock sb) {
402         traceall (var, sb, var.v);
403         }
404
405             // _uitl.traceall
406         // call trace on all of sb's predecessors
407         void traceall (Node.var var, BasicBlock sb, int lvt) {
408         if (sb.swval == 1 && lvt < me.params.length) {
409             link(me.params[lvt], var);
410         }
411             
412         println ("TRACEALL: " + var + " #" + sb.swval + " " + lvt);
413         in();
414         for (Enumeration e = pred[sb.swval-1].elements();
415              e.hasMoreElements();)
416             trace (var, (BasicBlock) e.nextElement(), lvt);
417         out();
418         }
419         */

420     } // _util
421
_util util = new _util();
422
423     // call find_producers to find each block's input producers
424
for (int i = 0; i < outbbs.size(); i++) {
425         util.println("FP ==================== " + (i+1));
426         util.in();
427         BasicBlock sb = (BasicBlock) outbbs.elementAt (i);
428         for (int j = 0; j < sb.inputs.length; j++)
429         if (sb.inputs[j] instanceof Node.var) {
430             visited.clear();
431             util.find_producers((Node.var) sb.inputs[j], sb);
432         }
433         util.out();
434     }
435
436     // call link() on each block's inputs
437
for (int i = 0; i < outbbs.size(); i++) {
438         util.println("LINK ==================== " + (i+1));
439         util.in();
440         final BasicBlock sb = (BasicBlock) outbbs.elementAt (i);
441         for (int j = 0; j < sb.inputs.length; j++) {
442         final int jj = j;
443         if (sb.inputs[j] instanceof Node.var) {
444             visited.clear();
445             util.link((Node.var) sb.inputs[j]);
446         }
447         if (false)
448         for (int k = 0; k < j; k++) {
449             final int kk = k;
450             if (sb.inputs[k].producers.equals(sb.inputs[j].producers)){
451             util.println("double " + sb.inputs[jj] + " " +
452                      sb.inputs[kk]);
453             /*sb.replace(new Hashtable(), new Node.SubMethod() {
454                 public Node f(Node in) {
455                     return in==sb.inputs[jj] ? sb.inputs[kk] :
456                     in;
457                 }
458                 });*/

459             }
460         }
461             
462         }
463         util.out();
464     } // for i
465

466
467
468     /* Convert the outputs that were used to array storage, replacing
469        the original outputs (which may include unused values)
470
471        An output is kept if it is an input to a succeeding block, or
472        it is used by the exit behavior. */

473
474     for (int i = 0; i < outbbs.size(); i++) {
475         BasicBlock sb = (BasicBlock) outbbs.elementAt (i);
476         for (int j = 0; j < sb.outputs.length; j++)
477         if (!(sb.outputs[j] instanceof Node.assign))
478             newouts[sb.swval-1].add (sb.outputs[j]);
479         sb.outputs = (Node[]) newouts[sb.swval-1].toArray (new Node[0]);
480     }
481
482     for (int i = 0; i < outbbs.size(); i++) {
483         BasicBlock sb = (BasicBlock) outbbs.elementAt(i);
484         Collection nodes = sb.findnodes();
485         for (Iterator j = nodes.iterator(); j.hasNext();) {
486         Node n = (Node) j.next();
487         if (n.destinations == null) continue;
488         for (Iterator k = n.destinations.iterator(); k.hasNext();) {
489             Node.var dest = (Node.var) k.next();
490             if (dest.sb == sb)
491             n.requires.addElement(dest);
492         }
493         }
494     }
495
496     me.bbs = outbbs;
497
498     //me.findRoles();
499

500     return me;
501     } // graphify
502

503
504     /** Display a DAG on the output stream
505      * @param out stream to write on
506      */

507     public void printinfo(LineWriter out) {
508     for (int i = 0; i < params.length; i++) {
509         if (params[i] == null) continue;
510         out.print("param " + params[i] + " " + params[i].type());
511         if (params[i].destinations == null) { out.println(); continue; }
512         out.print(" -> ");
513         for (Iterator j = params[i].destinations.iterator(); j.hasNext();)
514         out.print( j.next() + " ");
515         out.println();
516     }
517     
518     out.println();
519     for (int i = 0; i < bbs.size(); i++)
520         ((Block) bbs.elementAt (i)).printinfo (out, true);
521
522     out.println ();
523     }
524
525     /** disableblock
526      * @param db
527      */

528     void disableblock (BasicBlock db) {
529     db.blflags |= Block.Blc_disabled;
530
531     for (int i = 0; i < bbs.size(); i++) {
532         BasicBlock sb = (BasicBlock) bbs.elementAt (i);
533
534         for (int j = 0; j < sb.inputs.length; j++) {
535         Node.var var = (Node.var) sb.inputs[j];
536
537         loop: for (int k = 0; k < db.outputs.length; k++) {
538             if (var.producers.contains (db.outputs[k])) {
539             Jbet.warn.println ("" + var + " has dead producer " + db.outputs[k]);
540             var.producers.remove (db.outputs[k]);
541             continue loop;
542             } else {
543             for (Iterator l = var.producers.iterator(); l.hasNext(); ) {
544                 Object JavaDoc o = l.next();
545                 if (o.equals (db.outputs[k])) {
546                 Jbet.warn.println ("" + var + " has dead producer " + db.outputs[k]);
547                 var.producers.remove (o);
548                 continue loop;
549                 }
550             } // for l
551
}
552         } // for k
553
} // for j
554
} // for i
555
} // disableblock
556

557     /** replace
558      * @param subs
559      * @param sm
560      */

561     public void replace (Hashtable subs, Node.SubMethod sm) throws Throwable JavaDoc
562     {
563     for (int i = 0; i < bbs.size(); i++)
564         blockAt (i).replace (subs, sm);
565     }
566
567     public void replace_cfe (Hashtable subs, Node.SubMethod sm) throws ClassFileException
568     {
569     try {
570         for (int i = 0; i < bbs.size(); i++)
571         blockAt (i).replace (subs, sm);
572     }
573     catch (ClassFileException e) { throw e; }
574     catch (Throwable JavaDoc e) { e.printStackTrace (Jbet.error); throw new IllegalStateException JavaDoc (e.toString ()); }
575     }
576
577     /** Search for label nodes in all blocks. Put label placeholder blocks into bbs for
578      * each label found. The block numbers of other blocks may be changed.
579      */

580     public void findLabels ()
581     {
582     Vector newbbs = new Vector();
583
584     for (int i = 0; i < bbs.size(); i++) {
585         BasicBlock sb = (BasicBlock) bbs.elementAt (i);
586
587         if (sb.es.op == Instruction.AOP_LABEL)
588         continue;
589
590         newbbs.addElement (sb);
591
592         Collection nodes = sb.findnodes();
593         for (Iterator j = nodes.iterator(); j.hasNext(); ) {
594         Object JavaDoc o = j.next();
595
596         if (o instanceof Node.Label)
597             newbbs.addElement (new BasicBlock ((Node.Label) o));
598         }
599     }
600
601     bbs = newbbs;
602     BasicBlock.renumber (bbs);
603     } // findLabels
604

605     /** clearTmps sets clocal to -1 for each Node. (doesn't seem to be called)
606      */

607     public void clearTmps() {
608     for (int i = 0; i < bbs.size(); i++) {
609         BasicBlock sb = blockAt (i);
610         Collection nodes = sb.findnodes ();
611
612         for (Iterator j = nodes.iterator(); j.hasNext(); )
613         ((Node)j.next()).clocal = -1;
614     }
615     }
616
617     /** findRoles sets sb.es.role for each basic block
618      */

619     public void findRoles() {
620     for (int i = 0; i < bbs.size(); i++) {
621         BasicBlock sb = blockAt (i);
622
623         switch (sb.es.op) {
624         case 0:
625         if (sb.es.primary.pred.size() == 1)
626             sb.es.role = Block.Erol_Single;
627         break;
628
629         case Instruction.OP_RETURN:
630         case Instruction.OP_IRETURN:
631         case Instruction.OP_LRETURN:
632         case Instruction.OP_ARETURN:
633         case Instruction.OP_FRETURN:
634         case Instruction.OP_DRETURN:
635         sb.es.role = Block.Erol_Special;
636         break;
637
638         case Instruction.OP_IFNULL:
639         case Instruction.OP_IFNONNULL:
640         case Instruction.OP_IFEQ:
641         case Instruction.OP_IFNE:
642         case Instruction.OP_IFLE:
643         case Instruction.OP_IFLT:
644         case Instruction.OP_IFGT:
645         case Instruction.OP_IFGE:
646         case Instruction.OP_IF_ACMPEQ:
647         case Instruction.OP_IF_ACMPNE:
648         case Instruction.OP_IF_ICMPEQ:
649         case Instruction.OP_IF_ICMPNE:
650         case Instruction.OP_IF_ICMPLE:
651         case Instruction.OP_IF_ICMPLT:
652         case Instruction.OP_IF_ICMPGT:
653         case Instruction.OP_IF_ICMPGE:
654         if (sb.es.primary.alwaysIfLeadsTo (sb) ||
655             sb.es.jump.alwaysIfLeadsTo (sb))
656             sb.es.role = Block.Erol_LoopCond;
657         else
658             sb.es.role = Block.Erol_Cond;
659         /*
660         sb.es.role = Block.Erol_Cond;
661         Vector others = new Vector();
662         others.addElement (sb);
663         others.addElement (sb.es.primary);
664         if (sb.es.jump.alwaysIfLeadsTo (others))
665             sb.es.role = Block.Erol_LoopCond;
666         others = new Vector();
667         others.addElement (sb);
668         others.addElement (sb.es.jump);
669         if (sb.es.primary.alwaysIfLeadsTo (others))
670             sb.es.role = Block.Erol_LoopCond;
671         */

672         break;
673
674         case Instruction.OP_TABLESWITCH:
675         case Instruction.OP_LOOKUPSWITCH:
676         sb.es.role = Block.Erol_Switch;
677         break;
678         }
679     }
680     } // findRoles
681

682 }
683
Popular Tags