KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > baf > JasminClass


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1999 Patrick Lam, Patrick Pominville and Raja Vallee-Rai
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27
28
29
30 package soot.baf;
31 import soot.options.*;
32 import soot.tagkit.*;
33 import soot.*;
34 import soot.jimple.*;
35 import soot.toolkits.graph.*;
36 import soot.util.*;
37 import java.util.*;
38 import java.io.*;
39
40 public class JasminClass extends AbstractJasminClass
41 {
42     
43     public JasminClass(SootClass sootClass)
44     {
45         super(sootClass);
46     }
47
48     protected void assignColorsToLocals(Body body)
49     {
50         super.assignColorsToLocals(body);
51         
52         if(Options.v().time())
53             Timers.v().packTimer.end();
54                     
55     }
56
57     protected void emitMethodBody(SootMethod method)
58     {
59         if(Options.v().time())
60             Timers.v().buildJasminTimer.end();
61         
62         Body activeBody = method.getActiveBody();
63         
64         if(!(activeBody instanceof BafBody))
65             throw new RuntimeException JavaDoc("method: " + method.getName() + " has an invalid active body!");
66         
67         BafBody body = (BafBody) activeBody;
68         
69         if(body == null)
70             throw new RuntimeException JavaDoc("method: " + method.getName() + " has no active body!");
71             
72         if(Options.v().time())
73             Timers.v().buildJasminTimer.start();
74         
75         Chain instList = body.getUnits();
76
77         int stackLimitIndex = -1;
78         
79
80         subroutineToReturnAddressSlot = new HashMap(10, 0.7f);
81
82         // Determine the unitToLabel map
83
{
84             Iterator boxIt = body.getUnitBoxes(true).iterator();
85
86             unitToLabel = new HashMap(instList.size() * 2 + 1, 0.7f);
87             labelCount = 0;
88
89             while(boxIt.hasNext())
90             {
91                 // Assign a label for each statement reference
92
{
93                     InstBox box = (InstBox) boxIt.next();
94
95                     if(!unitToLabel.containsKey(box.getUnit()))
96                         unitToLabel.put(box.getUnit(), "label" + labelCount++);
97                 }
98             }
99         }
100
101
102
103
104         // Emit the exceptions, recording the Units at the beginning
105
// of handlers so that later on we can recognize blocks that
106
// begin with an exception on the stack.
107
Set handlerUnits = new ArraySet(body.getTraps().size());
108         {
109             Iterator trapIt = body.getTraps().iterator();
110
111             while(trapIt.hasNext())
112             {
113                 Trap trap = (Trap) trapIt.next();
114
115         handlerUnits.add(trap.getHandlerUnit());
116                 if(trap.getBeginUnit() != trap.getEndUnit()) {
117                     emit(".catch " + slashify(trap.getException().getName()) + " from " +
118                         unitToLabel.get(trap.getBeginUnit()) + " to " + unitToLabel.get(trap.getEndUnit()) +
119                         " using " + unitToLabel.get(trap.getHandlerUnit()));
120         }
121             }
122         }
123
124         // Determine where the locals go
125
{
126             int localCount = 0;
127             int[] paramSlots = new int[method.getParameterCount()];
128             int thisSlot = 0;
129             Set assignedLocals = new HashSet();
130             Map groupColorPairToSlot = new HashMap(body.getLocalCount() * 2 + 1, 0.7f);
131             
132             localToSlot = new HashMap(body.getLocalCount() * 2 + 1, 0.7f);
133
134             //assignColorsToLocals(body);
135

136             // Determine slots for 'this' and parameters
137
{
138                 List paramTypes = method.getParameterTypes();
139
140                 if(!method.isStatic())
141                 {
142                     thisSlot = 0;
143                     localCount++;
144                 }
145
146                 for(int i = 0; i < paramTypes.size(); i++)
147                 {
148                     paramSlots[i] = localCount;
149                     localCount += sizeOfType((Type) paramTypes.get(i));
150                 }
151             }
152
153             // Handle identity statements
154
{
155                 Iterator instIt = instList.iterator();
156
157                 while(instIt.hasNext())
158                 {
159                     Inst s = (Inst) instIt.next();
160
161                     if(s instanceof IdentityInst && ((IdentityInst) s).getLeftOp() instanceof Local)
162                     {
163                         Local l = (Local) ((IdentityInst) s).getLeftOp();
164                         IdentityRef identity = (IdentityRef) ((IdentityInst) s).getRightOp();
165
166                         int slot = 0;
167                                                 
168                         if(identity instanceof ThisRef)
169                         {
170                             if(method.isStatic())
171                                 throw new RuntimeException JavaDoc("Attempting to use 'this' in static method");
172
173                             slot = thisSlot;
174                         }
175                         else if(identity instanceof ParameterRef)
176                             slot = paramSlots[((ParameterRef) identity).getIndex()];
177                         else {
178                             // Exception ref. Skip over this
179
continue;
180                         }
181                         
182                         localToSlot.put(l, new Integer JavaDoc(slot));
183                         assignedLocals.add(l);
184                         
185                     }
186                 }
187             }
188
189             // Assign the rest of the locals
190
{
191                 Iterator localIt = body.getLocals().iterator();
192
193                 while(localIt.hasNext())
194                 {
195                     Local local = (Local) localIt.next();
196
197                     if(!assignedLocals.contains(local))
198                     {
199                         localToSlot.put(local, new Integer JavaDoc(localCount));
200                         localCount += sizeOfType((Type)local.getType());
201                         assignedLocals.add(local);
202                     }
203                 }
204
205                 if (!Modifier.isNative(method.getModifiers())
206                     && !Modifier.isAbstract(method.getModifiers()))
207                   {
208                     emit(" .limit stack ?");
209                     stackLimitIndex = code.size() - 1;
210                     
211                     emit(" .limit locals " + localCount);
212                   }
213             }
214         }
215
216         // Emit code in one pass
217
{
218             Iterator codeIt = instList.iterator();
219
220             isEmittingMethodCode = true;
221             maxStackHeight = 0;
222             isNextGotoAJsr = false;
223
224             while(codeIt.hasNext())
225             {
226                 Inst s = (Inst) codeIt.next();
227
228                 if(unitToLabel.containsKey(s))
229                     emit(unitToLabel.get(s) + ":");
230
231                 // emit this statement
232
{
233                     emitInst(s);
234                 }
235             }
236
237             isEmittingMethodCode = false;
238             
239             // calculate max stack height
240
{
241                 maxStackHeight = 0;
242                 if(activeBody.getUnits().size() != 0 ) {
243                     BlockGraph blockGraph = new BriefBlockGraph(activeBody);
244
245                 
246                     List blocks = blockGraph.getBlocks();
247                 
248
249                     if(blocks.size() != 0) {
250                         // set the stack height of the entry points
251
List entryPoints = ((DirectedGraph)blockGraph).getHeads();
252                         Iterator entryIt = entryPoints.iterator();
253                         while(entryIt.hasNext()) {
254                             Block entryBlock = (Block) entryIt.next();
255                             Integer JavaDoc initialHeight;
256                             if(handlerUnits.contains(entryBlock.getHead())) {
257                                 initialHeight = new Integer JavaDoc(1);
258                             } else {
259                                 initialHeight = new Integer JavaDoc(0);
260                             }
261                             if (blockToStackHeight == null){
262                                 blockToStackHeight = new HashMap();
263                             }
264                             blockToStackHeight.put(entryBlock, initialHeight);
265                             if (blockToLogicalStackHeight == null){
266                                 blockToLogicalStackHeight = new HashMap();
267                             }
268                             blockToLogicalStackHeight.put(entryBlock, initialHeight);
269                         }
270                                     
271                         // dfs the block graph using the blocks in the entryPoints list as roots
272
entryIt = entryPoints.iterator();
273                         while(entryIt.hasNext()) {
274                             Block nextBlock = (Block) entryIt.next();
275                             calculateStackHeight(nextBlock);
276                             calculateLogicalStackHeightCheck(nextBlock);
277                         }
278                     }
279                 }
280             }
281             if (!Modifier.isNative(method.getModifiers())
282                 && !Modifier.isAbstract(method.getModifiers()))
283                 code.set(stackLimitIndex, " .limit stack " + maxStackHeight);
284         }
285
286     // emit code attributes
287
{
288         Iterator it = body.getTags().iterator();
289         while(it.hasNext()) {
290         Tag t = (Tag) it.next();
291         if(t instanceof JasminAttribute) {
292             emit(".code_attribute " + t.getName() +" \"" + ((JasminAttribute) t).getJasminValue(unitToLabel) +"\"");
293         }
294         }
295     }
296     }
297
298
299     void emitInst(Inst inst)
300     {
301         inst.apply(new InstSwitch()
302         {
303             public void caseReturnVoidInst(ReturnVoidInst i)
304             {
305                 emit("return");
306             }
307
308             public void caseReturnInst(ReturnInst i)
309             {
310                 i.getOpType().apply(new TypeSwitch()
311                 {
312                     public void defaultCase(Type t)
313                     {
314                         throw new RuntimeException JavaDoc("invalid return type " + t.toString());
315                      }
316
317                      public void caseDoubleType(DoubleType t)
318                      {
319                         emit("dreturn");
320                      }
321
322                      public void caseFloatType(FloatType t)
323                      {
324                         emit("freturn");
325                      }
326
327                      public void caseIntType(IntType t)
328                      {
329                         emit("ireturn");
330                      }
331
332                      public void caseByteType(ByteType t)
333                      {
334                         emit("ireturn");
335                      }
336
337                      public void caseShortType(ShortType t)
338                      {
339                         emit("ireturn");
340                      }
341
342                      public void caseCharType(CharType t)
343                      {
344                         emit("ireturn");
345                      }
346
347                      public void caseBooleanType(BooleanType t)
348                      {
349                         emit("ireturn");
350                      }
351
352                      public void caseLongType(LongType t)
353                      {
354                         emit("lreturn");
355                      }
356
357                      public void caseArrayType(ArrayType t)
358                      {
359                         emit("areturn");
360                      }
361
362                      public void caseRefType(RefType t)
363                      {
364                         emit("areturn");
365                      }
366
367                      public void caseNullType(NullType t)
368                      {
369                         emit("areturn");
370                      }
371
372                 });
373             }
374
375             public void caseNopInst(NopInst i) { emit ("nop"); }
376
377             public void caseEnterMonitorInst(EnterMonitorInst i)
378             {
379                 emit ("monitorenter");
380             }
381             
382             public void casePopInst(PopInst i)
383                 {
384                     if(i.getWordCount() == 2) {
385                         emit("pop2");
386                     }
387                     else
388                         emit("pop");
389                 }
390                     
391
392             public void caseExitMonitorInst(ExitMonitorInst i)
393             {
394                 emit ("monitorexit");
395             }
396
397             public void caseGotoInst(GotoInst i)
398             {
399                 emit("goto " + unitToLabel.get(i.getTarget()));
400             }
401
402             public void casePushInst(PushInst i)
403             {
404                 if (i.getConstant() instanceof IntConstant)
405                 {
406                     IntConstant v = (IntConstant)(i.getConstant());
407                     if(v.value == -1)
408                         emit("iconst_m1");
409                     else if(v.value >= 0 && v.value <= 5)
410                         emit("iconst_" + v.value);
411                     else if(v.value >= Byte.MIN_VALUE &&
412                             v.value <= Byte.MAX_VALUE)
413                         emit("bipush " + v.value);
414                     else if(v.value >= Short.MIN_VALUE &&
415                             v.value <= Short.MAX_VALUE)
416                         emit("sipush " + v.value);
417                     else
418                         emit("ldc " + v.toString());
419                 }
420                 else if (i.getConstant() instanceof StringConstant)
421                 {
422                     emit("ldc " + i.getConstant().toString());
423                 }
424                 else if (i.getConstant() instanceof ClassConstant)
425                 {
426                     emit("ldc_w " + ((ClassConstant)i.getConstant()).getValue());
427                 }
428                 else if (i.getConstant() instanceof DoubleConstant)
429                 {
430                     DoubleConstant v = (DoubleConstant)(i.getConstant());
431
432                     if((v.value == 0) && ((1.0/v.value) > 0.0))
433                         emit("dconst_0");
434                     else if(v.value == 1)
435                         emit("dconst_1");
436                     else {
437                         String JavaDoc s = v.toString();
438                         
439                         if(s.equals("#Infinity"))
440                             s="+DoubleInfinity";
441                         
442                         if(s.equals("#-Infinity"))
443                             s="-DoubleInfinity";
444                         
445                         if(s.equals("#NaN"))
446                             s="+DoubleNaN";
447                         
448                         emit("ldc2_w " + s);
449                     }
450                 }
451                 else if (i.getConstant() instanceof FloatConstant)
452                 {
453                     FloatConstant v = (FloatConstant)(i.getConstant());
454                     if((v.value == 0) && ((1.0f/v.value) > 1.0f))
455                         emit("fconst_0");
456                     else if(v.value == 1)
457                         emit("fconst_1");
458                     else if(v.value == 2)
459                         emit("fconst_2");
460                     else {
461                         String JavaDoc s = v.toString();
462                         
463                         if(s.equals("#InfinityF"))
464                             s="+FloatInfinity";
465                         if(s.equals("#-InfinityF"))
466                             s="-FloatInfinity";
467                         
468                         if(s.equals("#NaNF"))
469                             s="+FloatNaN";
470                         
471                         emit("ldc " + s);
472                     }
473                 }
474                 else if (i.getConstant() instanceof LongConstant)
475                 {
476                     LongConstant v = (LongConstant)(i.getConstant());
477                     if(v.value == 0)
478                         emit("lconst_0");
479                     else if(v.value == 1)
480                         emit("lconst_1");
481                     else
482                         emit("ldc2_w " + v.toString());
483                 }
484                 else if (i.getConstant() instanceof NullConstant)
485                     emit("aconst_null");
486                 else
487                     throw new RuntimeException JavaDoc("unsupported opcode");
488             }
489
490             public void caseIdentityInst(IdentityInst i)
491             {
492                 if(i.getRightOp() instanceof CaughtExceptionRef &&
493                     i.getLeftOp() instanceof Local)
494                 {
495                     int slot = ((Integer JavaDoc) localToSlot.get(i.getLeftOp())).intValue();
496
497                     if(slot >= 0 && slot <= 3)
498                         emit("astore_" + slot);
499                     else
500                         emit("astore " + slot);
501                 }
502             }
503
504             public void caseStoreInst(StoreInst i)
505             {
506                     final int slot =
507                         ((Integer JavaDoc) localToSlot.get(i.getLocal())).intValue();
508
509                     i.getOpType().apply(new TypeSwitch()
510                     {
511                         public void caseArrayType(ArrayType t)
512                         {
513                             if(slot >= 0 && slot <= 3)
514                                 emit("astore_" + slot);
515                             else
516                                 emit("astore " + slot);
517                         }
518
519                         public void caseDoubleType(DoubleType t)
520                         {
521                             if(slot >= 0 && slot <= 3)
522                                 emit("dstore_" + slot);
523                             else
524                                 emit("dstore " + slot);
525                         }
526
527                         public void caseFloatType(FloatType t)
528                         {
529                             if(slot >= 0 && slot <= 3)
530                                 emit("fstore_" + slot);
531                             else
532                                 emit("fstore " + slot);
533                         }
534
535                         public void caseIntType(IntType t)
536                         {
537                             if(slot >= 0 && slot <= 3)
538                                 emit("istore_" + slot);
539                             else
540                                 emit("istore " + slot);
541                         }
542
543             public void caseByteType(ByteType t)
544                         {
545                             if(slot >= 0 && slot <= 3)
546                                 emit("istore_" + slot);
547                             else
548                                 emit("istore " + slot);
549                         }
550
551             public void caseShortType(ShortType t)
552                         {
553                             if(slot >= 0 && slot <= 3)
554                                 emit("istore_" + slot);
555                             else
556                                 emit("istore " + slot);
557                         }
558
559             public void caseCharType(CharType t)
560                         {
561                             if(slot >= 0 && slot <= 3)
562                                 emit("istore_" + slot);
563                             else
564                                 emit("istore " + slot);
565                         }
566
567             public void caseBooleanType(BooleanType t)
568                         {
569                             if(slot >= 0 && slot <= 3)
570                                 emit("istore_" + slot);
571                             else
572                                 emit("istore " + slot);
573                         }
574
575                         public void caseLongType(LongType t)
576                         {
577                             if(slot >= 0 && slot <= 3)
578                                 emit("lstore_" + slot);
579                             else
580                                 emit("lstore " + slot);
581                         }
582
583                         public void caseRefType(RefType t)
584                         {
585                             if(slot >= 0 && slot <= 3)
586                                 emit("astore_" + slot);
587                             else
588                                 emit("astore " + slot);
589                         }
590
591                         public void caseStmtAddressType(StmtAddressType t)
592                         {
593                             isNextGotoAJsr = true;
594                             returnAddressSlot = slot;
595
596                                 /*
597                                   if ( slot >= 0 && slot <= 3)
598                                   emit("astore_" + slot, );
599                                   else
600                                   emit("astore " + slot, );
601
602                                 */

603                         }
604
605                         public void caseNullType(NullType t)
606                         {
607                             if(slot >= 0 && slot <= 3)
608                                 emit("astore_" + slot);
609                             else
610                                 emit("astore " + slot);
611                         }
612                         
613                         public void defaultCase(Type t)
614                         {
615                             throw new RuntimeException JavaDoc("Invalid local type:"
616                                                        + t);
617                         }
618                     });
619             }
620
621             public void caseLoadInst(LoadInst i)
622             {
623                 final int slot =
624                     ((Integer JavaDoc) localToSlot.get(i.getLocal())).intValue();
625
626                 i.getOpType().apply(new TypeSwitch()
627                 {
628                     public void caseArrayType(ArrayType t)
629                     {
630                         if(slot >= 0 && slot <= 3)
631                             emit("aload_" + slot);
632                         else
633                             emit("aload " + slot);
634                     }
635             
636                     public void defaultCase(Type t)
637                     {
638                         throw new
639                             RuntimeException JavaDoc("invalid local type to load" + t);
640                     }
641
642                     public void caseDoubleType(DoubleType t)
643                     {
644                         if(slot >= 0 && slot <= 3)
645                             emit("dload_" + slot);
646                         else
647                             emit("dload " + slot);
648                     }
649
650                     public void caseFloatType(FloatType t)
651                     {
652                         if(slot >= 0 && slot <= 3)
653                             emit("fload_" + slot);
654                         else
655                             emit("fload " + slot);
656                     }
657             
658                     public void caseIntType(IntType t)
659                     {
660                         if(slot >= 0 && slot <= 3)
661                             emit("iload_" + slot);
662                         else
663                             emit("iload " + slot);
664                     }
665
666             public void caseByteType(ByteType t)
667                     {
668                         if(slot >= 0 && slot <= 3)
669                             emit("iload_" + slot);
670                         else
671                             emit("iload " + slot);
672                     }
673
674             public void caseShortType(ShortType t)
675                     {
676                         if(slot >= 0 && slot <= 3)
677                             emit("iload_" + slot);
678                         else
679                             emit("iload " + slot);
680                     }
681
682             public void caseCharType(CharType t)
683                     {
684                         if(slot >= 0 && slot <= 3)
685                             emit("iload_" + slot);
686                         else
687                             emit("iload " + slot);
688                     }
689
690             public void caseBooleanType(BooleanType t)
691                     {
692                         if(slot >= 0 && slot <= 3)
693                             emit("iload_" + slot);
694                         else
695                             emit("iload " + slot);
696                     }
697
698                     public void caseLongType(LongType t)
699                     {
700                         if(slot >= 0 && slot <= 3)
701                             emit("lload_" + slot);
702                         else
703                             emit("lload " + slot);
704                     }
705
706                     public void caseRefType(RefType t)
707                     {
708                         if(slot >= 0 && slot <= 3)
709                             emit("aload_" + slot);
710                         else
711                             emit("aload " + slot);
712                     }
713
714                     public void caseNullType(NullType t)
715                     {
716                         if(slot >= 0 && slot <= 3)
717                             emit("aload_" + slot);
718                         else
719                             emit("aload " + slot);
720                     }
721                 });
722             }
723
724             public void caseArrayWriteInst(ArrayWriteInst i)
725             {
726                 i.getOpType().apply(new TypeSwitch()
727                 {
728                     public void caseArrayType(ArrayType t)
729                     {
730                         emit("aastore");
731                     }
732
733                     public void caseDoubleType(DoubleType t)
734                     {
735                         emit("dastore");
736                     }
737
738                     public void caseFloatType(FloatType t)
739                     {
740                         emit("fastore");
741                     }
742
743                     public void caseIntType(IntType t)
744                     {
745                         emit("iastore");
746                     }
747
748                     public void caseLongType(LongType t)
749                     {
750                         emit("lastore");
751                     }
752
753                     public void caseRefType(RefType t)
754                     {
755                         emit("aastore");
756                     }
757
758                     public void caseByteType(ByteType t)
759                     {
760                         emit("bastore");
761                     }
762
763                     public void caseBooleanType(BooleanType t)
764                     {
765                         emit("bastore");
766                     }
767
768                     public void caseCharType(CharType t)
769                     {
770                         emit("castore");
771                     }
772
773                     public void caseShortType(ShortType t)
774                     {
775                         emit("sastore");
776                     }
777
778                     public void defaultCase(Type t)
779                     {
780                         throw new RuntimeException JavaDoc("Invalid type: " + t);
781                     }});
782                     
783                 }
784
785             public void caseArrayReadInst(ArrayReadInst i)
786             {
787                 i.getOpType().apply(new TypeSwitch()
788                 {
789                     public void caseArrayType(ArrayType ty)
790                     {
791                         emit("aaload");
792                     }
793
794                     public void caseBooleanType(BooleanType ty)
795                     {
796                         emit("baload");
797                     }
798
799                     public void caseByteType(ByteType ty)
800                     {
801                         emit("baload");
802                     }
803
804                     public void caseCharType(CharType ty)
805                     {
806                         emit("caload");
807                     }
808
809                     public void defaultCase(Type ty)
810                     {
811                         throw new RuntimeException JavaDoc("invalid base type");
812                     }
813
814                     public void caseDoubleType(DoubleType ty)
815                     {
816                         emit("daload");
817                     }
818
819                     public void caseFloatType(FloatType ty)
820                     {
821                         emit("faload");
822                     }
823
824                     public void caseIntType(IntType ty)
825                     {
826                         emit("iaload");
827                     }
828
829                     public void caseLongType(LongType ty)
830                     {
831                         emit("laload");
832                     }
833
834                     public void caseNullType(NullType ty)
835                     {
836                         emit("aaload");
837                     }
838                     public void caseRefType(RefType ty)
839                     {
840                         emit("aaload");
841                     }
842
843                     public void caseShortType(ShortType ty)
844                     {
845                         emit("saload");
846                     }
847                 });
848             }
849
850             public void caseIfNullInst(IfNullInst i)
851             {
852                 emit("ifnull " + unitToLabel.get(i.getTarget()));
853             }
854
855             public void caseIfNonNullInst(IfNonNullInst i)
856             {
857                 emit("ifnonnull " + unitToLabel.get(i.getTarget()));
858             }
859
860             public void caseIfEqInst(IfEqInst i)
861             {
862                 emit("ifeq " + unitToLabel.get(i.getTarget()));
863             }
864
865             public void caseIfNeInst(IfNeInst i)
866             {
867                 emit("ifne " + unitToLabel.get(i.getTarget()));
868             }
869
870             public void caseIfGtInst(IfGtInst i)
871             {
872                 emit("ifgt " + unitToLabel.get(i.getTarget()));
873             }
874
875             public void caseIfGeInst(IfGeInst i)
876             {
877                 emit("ifge " + unitToLabel.get(i.getTarget()));
878             }
879
880             public void caseIfLtInst(IfLtInst i)
881             {
882                 emit("iflt " + unitToLabel.get(i.getTarget()));
883             }
884
885             public void caseIfLeInst(IfLeInst i)
886             {
887                 emit("ifle " + unitToLabel.get(i.getTarget()));
888             }
889
890             public void caseIfCmpEqInst(final IfCmpEqInst i)
891             {
892                 i.getOpType().apply(new TypeSwitch()
893                 {
894                     public void caseIntType(IntType t)
895                     {
896                         emit("if_icmpeq " +
897                              unitToLabel.get(i.getTarget()));
898                     }
899
900                     public void caseBooleanType(BooleanType t)
901                     {
902                         emit("if_icmpeq " +
903                              unitToLabel.get(i.getTarget()));
904                     }
905
906                     public void caseShortType(ShortType t)
907                     {
908                         emit("if_icmpeq " +
909                              unitToLabel.get(i.getTarget()));
910                     }
911
912                     public void caseCharType(CharType t)
913                     {
914                         emit("if_icmpeq " +
915                              unitToLabel.get(i.getTarget()));
916                     }
917
918                     public void caseByteType(ByteType t)
919                     {
920                         emit("if_icmpeq " +
921                              unitToLabel.get(i.getTarget()));
922                     }
923
924                     public void caseDoubleType(DoubleType t)
925                     {
926                         emit("dcmpg");
927                         emit("ifeq " +
928                              unitToLabel.get(i.getTarget()));
929                     }
930
931                     public void caseLongType(LongType t)
932                     {
933                         emit("lcmp");
934                         emit("ifeq " +
935                              unitToLabel.get(i.getTarget()));
936                     }
937
938                     public void caseFloatType(FloatType t)
939                     {
940                         emit("fcmpg");
941                         emit("ifeq " +
942                              unitToLabel.get(i.getTarget()));
943                     }
944
945                     public void caseArrayType(ArrayType t)
946                     {
947                         emit("if_acmpeq " +
948                              unitToLabel.get(i.getTarget()));
949                     }
950
951                     public void caseRefType(RefType t)
952                     {
953                         emit("if_acmpeq " +
954                              unitToLabel.get(i.getTarget()));
955                     }
956
957                     public void caseNullType(NullType t)
958                     {
959                         emit("if_acmpeq " +
960                              unitToLabel.get(i.getTarget()));
961                     }
962
963                     public void defaultCase(Type t)
964                     {
965                         throw new RuntimeException JavaDoc("invalid type");
966                     }
967                 });
968             }
969
970             public void caseIfCmpNeInst(final IfCmpNeInst i)
971             {
972                 i.getOpType().apply(new TypeSwitch()
973                 {
974                     public void caseIntType(IntType t)
975                     {
976                         emit("if_icmpne " +
977                              unitToLabel.get(i.getTarget()));
978                     }
979
980                     public void caseBooleanType(BooleanType t)
981                     {
982                         emit("if_icmpne " +
983                              unitToLabel.get(i.getTarget()));
984                     }
985
986                     public void caseShortType(ShortType t)
987                     {
988                         emit("if_icmpne " +
989                              unitToLabel.get(i.getTarget()));
990                     }
991
992                     public void caseCharType(CharType t)
993                     {
994                         emit("if_icmpne " +
995                              unitToLabel.get(i.getTarget()));
996                     }
997
998                     public void caseByteType(ByteType t)
999                     {
1000                        emit("if_icmpne " +
1001                             unitToLabel.get(i.getTarget()));
1002                    }
1003
1004                    public void caseDoubleType(DoubleType t)
1005                    {
1006                        emit("dcmpg");
1007                        emit("ifne " +
1008                             unitToLabel.get(i.getTarget()));
1009                    }
1010
1011                    public void caseLongType(LongType t)
1012                    {
1013                        emit("lcmp");
1014                        emit("ifne " +
1015                             unitToLabel.get(i.getTarget()));
1016                    }
1017
1018                    public void caseFloatType(FloatType t)
1019                    {
1020                        emit("fcmpg");
1021                        emit("ifne " +
1022                             unitToLabel.get(i.getTarget()));
1023                    }
1024
1025                    public void caseArrayType(ArrayType t)
1026                    {
1027                        emit("if_acmpne " +
1028                             unitToLabel.get(i.getTarget()));
1029                    }
1030
1031                    public void caseRefType(RefType t)
1032                    {
1033                        emit("if_acmpne " +
1034                             unitToLabel.get(i.getTarget()));
1035                    }
1036
1037                    public void caseNullType(NullType t)
1038                    {
1039                        emit("if_acmpne " +
1040                             unitToLabel.get(i.getTarget()));
1041                    }
1042
1043                    public void defaultCase(Type t)
1044                    {
1045                        throw new RuntimeException JavaDoc("invalid type");
1046                    }
1047                });
1048            }
1049
1050            public void caseIfCmpGtInst(final IfCmpGtInst i)
1051            {
1052                i.getOpType().apply(new TypeSwitch()
1053                {
1054                    public void caseIntType(IntType t)
1055                    {
1056                        emit("if_icmpgt " +
1057                             unitToLabel.get(i.getTarget()));
1058                    }
1059
1060                    public void caseBooleanType(BooleanType t)
1061                    {
1062                        emit("if_icmpgt " +
1063                             unitToLabel.get(i.getTarget()));
1064                    }
1065
1066                    public void caseShortType(ShortType t)
1067                    {
1068                        emit("if_icmpgt " +
1069                             unitToLabel.get(i.getTarget()));
1070                    }
1071
1072                    public void caseCharType(CharType t)
1073                    {
1074                        emit("if_icmpgt " +
1075                             unitToLabel.get(i.getTarget()));
1076                    }
1077
1078                    public void caseByteType(ByteType t)
1079                    {
1080                        emit("if_icmpgt " +
1081                             unitToLabel.get(i.getTarget()));
1082                    }
1083
1084                    public void caseDoubleType(DoubleType t)
1085                    {
1086                        emit("dcmpg");
1087                        emit("ifgt " +
1088                             unitToLabel.get(i.getTarget()));
1089                    }
1090
1091                    public void caseLongType(LongType t)
1092                    {
1093                        emit("lcmp");
1094                        emit("ifgt " +
1095                             unitToLabel.get(i.getTarget()));
1096                    }
1097
1098                    public void caseFloatType(FloatType t)
1099                    {
1100                        emit("fcmpg");
1101                        emit("ifgt " +
1102                             unitToLabel.get(i.getTarget()));
1103                    }
1104
1105                    public void caseArrayType(ArrayType t)
1106                    {
1107                        emit("if_acmpgt " +
1108                             unitToLabel.get(i.getTarget()));
1109                    }
1110
1111                    public void caseRefType(RefType t)
1112                    {
1113                        emit("if_acmpgt " +
1114                             unitToLabel.get(i.getTarget()));
1115                    }
1116
1117                    public void caseNullType(NullType t)
1118                    {
1119                        emit("if_acmpgt " +
1120                             unitToLabel.get(i.getTarget()));
1121                    }
1122
1123                    public void defaultCase(Type t)
1124                    {
1125                        throw new RuntimeException JavaDoc("invalid type");
1126                    }
1127                });
1128            }
1129
1130            public void caseIfCmpGeInst(final IfCmpGeInst i)
1131            {
1132                i.getOpType().apply(new TypeSwitch()
1133                {
1134                    public void caseIntType(IntType t)
1135                    {
1136                        emit("if_icmpge " +
1137                             unitToLabel.get(i.getTarget()));
1138                    }
1139
1140                    public void caseBooleanType(BooleanType t)
1141                    {
1142                        emit("if_icmpge " +
1143                             unitToLabel.get(i.getTarget()));
1144                    }
1145
1146                    public void caseShortType(ShortType t)
1147                    {
1148                        emit("if_icmpge " +
1149                             unitToLabel.get(i.getTarget()));
1150                    }
1151
1152                    public void caseCharType(CharType t)
1153                    {
1154                        emit("if_icmpge " +
1155                             unitToLabel.get(i.getTarget()));
1156                    }
1157
1158                    public void caseByteType(ByteType t)
1159                    {
1160                        emit("if_icmpge " +
1161                             unitToLabel.get(i.getTarget()));
1162                    }
1163
1164                    public void caseDoubleType(DoubleType t)
1165                    {
1166                        emit("dcmpg");
1167                        emit("ifge " +
1168                             unitToLabel.get(i.getTarget()));
1169                    }
1170
1171                    public void caseLongType(LongType t)
1172                    {
1173                        emit("lcmp");
1174                        emit("ifge " +
1175                             unitToLabel.get(i.getTarget()));
1176                    }
1177
1178                    public void caseFloatType(FloatType t)
1179                    {
1180                        emit("fcmpg");
1181                        emit("ifge " +
1182                             unitToLabel.get(i.getTarget()));
1183                    }
1184
1185                    public void caseArrayType(ArrayType t)
1186                    {
1187                        emit("if_acmpge " +
1188                             unitToLabel.get(i.getTarget()));
1189                    }
1190
1191                    public void caseRefType(RefType t)
1192                    {
1193                        emit("if_acmpge " +
1194                             unitToLabel.get(i.getTarget()));
1195                    }
1196
1197                    public void caseNullType(NullType t)
1198                    {
1199                        emit("if_acmpge " +
1200                             unitToLabel.get(i.getTarget()));
1201                    }
1202
1203                    public void defaultCase(Type t)
1204                    {
1205                        throw new RuntimeException JavaDoc("invalid type");
1206                    }
1207                });
1208            }
1209
1210            public void caseIfCmpLtInst(final IfCmpLtInst i)
1211            {
1212                i.getOpType().apply(new TypeSwitch()
1213                {
1214                    public void caseIntType(IntType t)
1215                    {
1216                        emit("if_icmplt " +
1217                             unitToLabel.get(i.getTarget()));
1218                    }
1219
1220                    public void caseBooleanType(BooleanType t)
1221                    {
1222                        emit("if_icmplt " +
1223                             unitToLabel.get(i.getTarget()));
1224                    }
1225
1226                    public void caseShortType(ShortType t)
1227                    {
1228                        emit("if_icmplt " +
1229                             unitToLabel.get(i.getTarget()));
1230                    }
1231
1232                    public void caseCharType(CharType t)
1233                    {
1234                        emit("if_icmplt " +
1235                             unitToLabel.get(i.getTarget()));
1236                    }
1237
1238                    public void caseByteType(ByteType t)
1239                    {
1240                        emit("if_icmplt " +
1241                             unitToLabel.get(i.getTarget()));
1242                    }
1243
1244                    public void caseDoubleType(DoubleType t)
1245                    {
1246                        emit("dcmpg");
1247                        emit("iflt " +
1248                             unitToLabel.get(i.getTarget()));
1249                    }
1250
1251                    public void caseLongType(LongType t)
1252                    {
1253                        emit("lcmp");
1254                        emit("iflt " +
1255                             unitToLabel.get(i.getTarget()));
1256                    }
1257
1258                    public void caseFloatType(FloatType t)
1259                    {
1260                        emit("fcmpg");
1261                        emit("iflt " +
1262                             unitToLabel.get(i.getTarget()));
1263                    }
1264
1265                    public void caseArrayType(ArrayType t)
1266                    {
1267                        emit("if_acmplt " +
1268                             unitToLabel.get(i.getTarget()));
1269                    }
1270
1271                    public void caseRefType(RefType t)
1272                    {
1273                        emit("if_acmplt " +
1274                             unitToLabel.get(i.getTarget()));
1275                    }
1276
1277                    public void caseNullType(NullType t)
1278                    {
1279                        emit("if_acmplt " +
1280                             unitToLabel.get(i.getTarget()));
1281                    }
1282
1283                    public void defaultCase(Type t)
1284                    {
1285                        throw new RuntimeException JavaDoc("invalid type");
1286                    }
1287                });
1288            }
1289
1290            public void caseIfCmpLeInst(final IfCmpLeInst i)
1291            {
1292                i.getOpType().apply(new TypeSwitch()
1293                {
1294                    public void caseIntType(IntType t)
1295                    {
1296                        emit("if_icmple " +
1297                             unitToLabel.get(i.getTarget()));
1298                    }
1299
1300                    public void caseBooleanType(BooleanType t)
1301                    {
1302                        emit("if_icmple " +
1303                             unitToLabel.get(i.getTarget()));
1304                    }
1305
1306                    public void caseShortType(ShortType t)
1307                    {
1308                        emit("if_icmple " +
1309                             unitToLabel.get(i.getTarget()));
1310                    }
1311
1312                    public void caseCharType(CharType t)
1313                    {
1314                        emit("if_icmple " +
1315                             unitToLabel.get(i.getTarget()));
1316                    }
1317
1318                    public void caseByteType(ByteType t)
1319                    {
1320                        emit("if_icmple " +
1321                             unitToLabel.get(i.getTarget()));
1322                    }
1323
1324                    public void caseDoubleType(DoubleType t)
1325                    {
1326                        emit("dcmpg");
1327                        emit("ifle " +
1328                             unitToLabel.get(i.getTarget()));
1329                    }
1330
1331                    public void caseLongType(LongType t)
1332                    {
1333                        emit("lcmp");
1334                        emit("ifle " +
1335                             unitToLabel.get(i.getTarget()));
1336                    }
1337
1338                    public void caseFloatType(FloatType t)
1339                    {
1340                        emit("fcmpg");
1341                        emit("ifle " +
1342                             unitToLabel.get(i.getTarget()));
1343                    }
1344
1345                    public void caseArrayType(ArrayType t)
1346                    {
1347                        emit("if_acmple " +
1348                             unitToLabel.get(i.getTarget()));
1349                    }
1350
1351                    public void caseRefType(RefType t)
1352                    {
1353                        emit("if_acmple " +
1354                             unitToLabel.get(i.getTarget()));
1355                    }
1356
1357                    public void caseNullType(NullType t)
1358                    {
1359                        emit("if_acmple " +
1360                             unitToLabel.get(i.getTarget()));
1361                    }
1362
1363                    public void defaultCase(Type t)
1364                    {
1365                        throw new RuntimeException JavaDoc("invalid type");
1366                    }
1367                });
1368            }
1369
1370            public void caseStaticGetInst(StaticGetInst i)
1371            {
1372                SootFieldRef field = i.getFieldRef();
1373                emit("getstatic " +
1374                     slashify(field.declaringClass().getName()) + "/" +
1375                     field.name() + " " +
1376                     jasminDescriptorOf(field.type()));
1377            }
1378
1379            public void caseStaticPutInst(StaticPutInst i)
1380            {
1381                emit("putstatic " +
1382                     slashify(i.getFieldRef().declaringClass().getName()) +
1383                     "/" + i.getFieldRef().name() + " " +
1384                     jasminDescriptorOf(i.getFieldRef().type()));
1385            }
1386
1387            public void caseFieldGetInst(FieldGetInst i)
1388            {
1389                emit("getfield " +
1390                     slashify(i.getFieldRef().declaringClass().getName()) +
1391                     "/" + i.getFieldRef().name() + " " +
1392                     jasminDescriptorOf(i.getFieldRef().type()));
1393            }
1394
1395            public void caseFieldPutInst(FieldPutInst i)
1396            {
1397                emit("putfield " +
1398                     slashify(i.getFieldRef().declaringClass().getName()) +
1399                     "/" + i.getFieldRef().name() + " " +
1400                     jasminDescriptorOf(i.getFieldRef().type()));
1401            }
1402
1403            public void caseInstanceCastInst(InstanceCastInst i)
1404            {
1405                Type castType = i.getCastType();
1406
1407                if(castType instanceof RefType)
1408                    emit("checkcast " + slashify(castType.toString()));
1409                else if(castType instanceof ArrayType)
1410                    emit("checkcast " + jasminDescriptorOf(castType));
1411            }
1412
1413            public void caseInstanceOfInst(InstanceOfInst i)
1414            {
1415                Type checkType = i.getCheckType();
1416
1417                if(checkType instanceof RefType)
1418                    emit("instanceof " + slashify(checkType.toString()));
1419                else if(checkType instanceof ArrayType)
1420                    emit("instanceof " + jasminDescriptorOf(checkType));
1421            }
1422
1423            public void caseNewInst(NewInst i)
1424            {
1425                emit("new "+slashify(i.getBaseType().toString()));
1426            }
1427
1428            public void casePrimitiveCastInst(PrimitiveCastInst i)
1429            {
1430                emit(i.toString());
1431            }
1432
1433            public void caseStaticInvokeInst(StaticInvokeInst i)
1434            {
1435                SootMethodRef m = i.getMethodRef();
1436
1437                emit("invokestatic " + slashify(m.declaringClass().getName()) + "/" +
1438                    m.name() + jasminDescriptorOf(m));
1439            }
1440            
1441            public void caseVirtualInvokeInst(VirtualInvokeInst i)
1442            {
1443                SootMethodRef m = i.getMethodRef();
1444
1445                emit("invokevirtual " + slashify(m.declaringClass().getName()) + "/" +
1446                    m.name() + jasminDescriptorOf(m));
1447            }
1448
1449            public void caseInterfaceInvokeInst(InterfaceInvokeInst i)
1450            {
1451                SootMethodRef m = i.getMethodRef();
1452
1453                emit("invokeinterface " + slashify(m.declaringClass().getName()) + "/" +
1454                    m.name() + jasminDescriptorOf(m) + " " + (argCountOf(m) + 1));
1455            }
1456
1457            public void caseSpecialInvokeInst(SpecialInvokeInst i)
1458            {
1459                SootMethodRef m = i.getMethodRef();
1460
1461                emit("invokespecial " + slashify(m.declaringClass().getName()) + "/" +
1462                    m.name() + jasminDescriptorOf(m));
1463            }
1464
1465            public void caseThrowInst(ThrowInst i)
1466            {
1467                emit("athrow");
1468            }
1469
1470            public void caseCmpInst(CmpInst i)
1471            {
1472                emit("lcmp");
1473            }
1474
1475            public void caseCmplInst(CmplInst i)
1476            {
1477                if(i.getOpType().equals(FloatType.v()))
1478                    emit("fcmpl");
1479                else
1480                    emit("dcmpl");
1481            }
1482
1483            public void caseCmpgInst(CmpgInst i)
1484            {
1485                if(i.getOpType().equals(FloatType.v()))
1486                    emit("fcmpg");
1487                else
1488                    emit("dcmpg");
1489            }
1490
1491            private void emitOpTypeInst(final String JavaDoc s, final OpTypeArgInst i)
1492            {
1493                i.getOpType().apply(new TypeSwitch()
1494                {
1495                    private void handleIntCase()
1496                    {
1497                        emit("i"+s);
1498                    }
1499
1500                    public void caseIntType(IntType t) { handleIntCase(); }
1501                    public void caseBooleanType(BooleanType t) { handleIntCase(); }
1502                    public void caseShortType(ShortType t) { handleIntCase(); }
1503                    public void caseCharType(CharType t) { handleIntCase(); }
1504                    public void caseByteType(ByteType t) { handleIntCase(); }
1505
1506                    public void caseLongType(LongType t)
1507                    {
1508                        emit("l"+s);
1509                    }
1510
1511                    public void caseDoubleType(DoubleType t)
1512                    {
1513                        emit("d"+s);
1514                    }
1515
1516                    public void caseFloatType(FloatType t)
1517                    {
1518                        emit("f"+s);
1519                    }
1520
1521                    public void defaultCase(Type t)
1522                    {
1523                        throw new RuntimeException JavaDoc("Invalid argument type for div");
1524                    }
1525                });
1526            }
1527
1528            public void caseAddInst(AddInst i)
1529            {
1530                emitOpTypeInst("add", i);
1531            }
1532
1533            public void caseDivInst(DivInst i)
1534            {
1535                emitOpTypeInst("div", i);
1536            }
1537
1538            public void caseSubInst(SubInst i)
1539            {
1540                emitOpTypeInst("sub", i);
1541            }
1542
1543            public void caseMulInst(MulInst i)
1544            {
1545                emitOpTypeInst("mul", i);
1546            }
1547
1548            public void caseRemInst(RemInst i)
1549            {
1550                emitOpTypeInst("rem", i);
1551            }
1552
1553            public void caseShlInst(ShlInst i)
1554            {
1555                emitOpTypeInst("shl", i);
1556            }
1557
1558            public void caseAndInst(AndInst i)
1559            {
1560                emitOpTypeInst("and", i);
1561            }
1562
1563            public void caseOrInst(OrInst i)
1564            {
1565                emitOpTypeInst("or", i);
1566            }
1567
1568            public void caseXorInst(XorInst i)
1569            {
1570                emitOpTypeInst("xor", i);
1571            }
1572
1573            public void caseShrInst(ShrInst i)
1574            {
1575                emitOpTypeInst("shr", i);
1576            }
1577
1578            public void caseUshrInst(UshrInst i)
1579            {
1580                emitOpTypeInst("ushr", i);
1581            }
1582
1583            public void caseIncInst(IncInst i)
1584            {
1585                if(((ValueBox) i.getUseBoxes().get(0)).getValue() != ((ValueBox) i.getDefBoxes().get(0)).getValue())
1586                    throw new RuntimeException JavaDoc("iinc def and use boxes don't match");
1587                    
1588                emit("iinc " + ((Integer JavaDoc) localToSlot.get(i.getLocal())) + " " + i.getConstant());
1589            }
1590
1591            public void caseArrayLengthInst(ArrayLengthInst i)
1592            {
1593                emit("arraylength");
1594            }
1595
1596            public void caseNegInst(NegInst i)
1597            {
1598                emitOpTypeInst("neg", i);
1599            }
1600
1601            public void caseNewArrayInst(NewArrayInst i)
1602            {
1603                if(i.getBaseType() instanceof RefType)
1604                    emit("anewarray " + slashify(i.getBaseType().toString()));
1605                else if(i.getBaseType() instanceof ArrayType)
1606                    emit("anewarray " + jasminDescriptorOf(i.getBaseType()));
1607                else
1608                    emit("newarray " + i.getBaseType().toString());
1609            }
1610
1611            public void caseNewMultiArrayInst(NewMultiArrayInst i)
1612            {
1613                emit("multianewarray " + jasminDescriptorOf(i.getBaseType()) + " " +
1614                     i.getDimensionCount());
1615            }
1616
1617            public void caseLookupSwitchInst(LookupSwitchInst i)
1618            {
1619                emit("lookupswitch");
1620
1621                List lookupValues = i.getLookupValues();
1622                List targets = i.getTargets();
1623
1624                for(int j = 0; j < lookupValues.size(); j++)
1625                    emit(" " + lookupValues.get(j) + " : " +
1626                         unitToLabel.get(targets.get(j)));
1627
1628                emit(" default : " + unitToLabel.get(i.getDefaultTarget()));
1629            }
1630
1631            public void caseTableSwitchInst(TableSwitchInst i)
1632                {
1633                emit("tableswitch " + i.getLowIndex() + " ; high = " + i.getHighIndex());
1634
1635                List targets = i.getTargets();
1636
1637                for(int j = 0; j < targets.size(); j++)
1638                    emit(" " + unitToLabel.get(targets.get(j)));
1639
1640                emit("default : " + unitToLabel.get(i.getDefaultTarget()));
1641            }
1642
1643            private boolean isDwordType(Type t)
1644            {
1645                return t instanceof LongType || t instanceof DoubleType
1646                    || t instanceof DoubleWordType;
1647            }
1648            
1649            public void caseDup1Inst(Dup1Inst i)
1650            {
1651                Type firstOpType = i.getOp1Type();
1652                if (isDwordType(firstOpType))
1653                    emit("dup2"); // (form 2)
1654
else
1655                    emit("dup");
1656            }
1657
1658            public void caseDup2Inst(Dup2Inst i)
1659            {
1660                Type firstOpType = i.getOp1Type();
1661                Type secondOpType = i.getOp2Type();
1662                // The first two cases have no real bytecode equivalents.
1663
// Use a pair of insts to simulate them.
1664
if(isDwordType(firstOpType)) {
1665                    emit("dup2"); // (form 2)
1666
if(isDwordType(secondOpType)) {
1667                        emit("dup2"); // (form 2 -- by simulation)
1668
} else
1669                        emit("dup"); // also a simulation
1670
} else if(isDwordType(secondOpType)) {
1671                    if(isDwordType(firstOpType)) {
1672                        emit("dup2"); // (form 2)
1673
} else
1674                        emit("dup");
1675                    emit("dup2"); // (form 2 -- complete the simulation)
1676
} else {
1677                    //delme[
1678
G.v().out.println("3000:(JasminClass): dup2 created");
1679                    //delme
1680
emit("dup2"); // form 1
1681
}
1682            }
1683
1684            public void caseDup1_x1Inst(Dup1_x1Inst i)
1685            {
1686                Type opType = i.getOp1Type();
1687                Type underType = i.getUnder1Type();
1688                
1689                if(isDwordType(opType)) {
1690                    if(isDwordType(underType)) {
1691                        emit("dup2_x2"); // (form 4)
1692
} else
1693                        emit("dup2_x1"); // (form 2)
1694
} else {
1695                    if(isDwordType(underType))
1696                        emit("dup_x2"); // (form 2)
1697
else
1698                        emit("dup_x1"); // (only one form)
1699
}
1700            }
1701
1702            public void caseDup1_x2Inst(Dup1_x2Inst i)
1703            {
1704                Type opType = i.getOp1Type();
1705                Type under1Type = i.getUnder1Type();
1706                Type under2Type = i.getUnder2Type();
1707
1708                if (isDwordType(opType)) {
1709                    if (!isDwordType(under1Type) && !isDwordType(under2Type))
1710                        emit("dup2_x2"); // (form 2)
1711
else
1712                        throw new RuntimeException JavaDoc("magic not implemented yet");
1713                } else {
1714                    if (isDwordType(under1Type) || isDwordType(under2Type))
1715                        throw new RuntimeException JavaDoc("magic not implemented yet");
1716                }
1717
1718                emit("dup_x2"); // (form 1)
1719
}
1720
1721            public void caseDup2_x1Inst(Dup2_x1Inst i)
1722            {
1723                Type op1Type = i.getOp1Type();
1724                Type op2Type = i.getOp2Type();
1725                Type under1Type = i.getUnder1Type();
1726
1727                if (isDwordType(under1Type)) {
1728                    if (!isDwordType(op1Type) && !isDwordType(op2Type))
1729                        throw new RuntimeException JavaDoc("magic not implemented yet");
1730                    else
1731                        emit("dup2_x2"); // (form 3)
1732
} else {
1733                    if (isDwordType(op1Type) || isDwordType(op2Type))
1734                        throw new RuntimeException JavaDoc("magic not implemented yet");
1735                }
1736
1737                emit("dup2_x1"); // (form 1)
1738
}
1739
1740           
1741
1742            public void caseDup2_x2Inst(Dup2_x2Inst i)
1743            {
1744                Type op1Type = i.getOp1Type();
1745                Type op2Type = i.getOp2Type();
1746                Type under1Type = i.getUnder1Type();
1747                Type under2Type = i.getUnder2Type();
1748
1749                if (isDwordType(op1Type) || isDwordType(op2Type) ||
1750                    isDwordType(under1Type) || isDwordType(under1Type))
1751                    throw new RuntimeException JavaDoc("magic not implemented yet");
1752
1753                emit("dup2_x2"); // (form 1)
1754
}
1755
1756            public void caseSwapInst(SwapInst i)
1757                {
1758                    emit("swap");
1759                }
1760
1761
1762
1763        });
1764    }
1765   
1766
1767
1768 
1769    private void calculateStackHeight(Block aBlock)
1770    {
1771        Iterator it = aBlock.iterator();
1772        int blockHeight = ((Integer JavaDoc)blockToStackHeight.get(aBlock)).intValue();
1773        if( blockHeight > maxStackHeight) {
1774            maxStackHeight = blockHeight;
1775        }
1776        
1777        while(it.hasNext()) {
1778          Inst nInst = (Inst) it.next();
1779          
1780          blockHeight -= nInst.getInMachineCount();
1781      
1782          if(blockHeight < 0 ){
1783          throw new RuntimeException JavaDoc("Negative Stack height has been attained: \n" +
1784                                       "StackHeight: " + blockHeight + "\n" +
1785                                       "At instruction:" + nInst + "\n" +
1786                                       "Block:\n" + aBlock +
1787                                       "\n\nMethod: " + aBlock.getBody().getMethod().getName()
1788                                       + "\n" + aBlock.getBody().getMethod()
1789                                       );
1790          }
1791          
1792          blockHeight += nInst.getOutMachineCount();
1793          if( blockHeight > maxStackHeight) {
1794            maxStackHeight = blockHeight;
1795          }
1796          //G.v().out.println(">>> " + nInst + " " + blockHeight);
1797
}
1798        
1799        
1800        Iterator succs = aBlock.getSuccs().iterator();
1801        while(succs.hasNext()) {
1802            Block b = (Block) succs.next();
1803            Integer JavaDoc i = (Integer JavaDoc) blockToStackHeight.get(b);
1804            if(i != null) {
1805                if(i.intValue() != blockHeight) {
1806                    throw new RuntimeException JavaDoc("incoherent stack height at block merge point " + b + aBlock + "\ncomputed blockHeight == " + blockHeight + " recorded blockHeight = " + i.intValue());
1807                }
1808                
1809            } else {
1810                blockToStackHeight.put(b, new Integer JavaDoc(blockHeight));
1811                calculateStackHeight(b);
1812            }
1813        }
1814    }
1815
1816
1817    private void calculateLogicalStackHeightCheck(Block aBlock)
1818    {
1819        Iterator it = aBlock.iterator();
1820        int blockHeight = ((Integer JavaDoc)blockToLogicalStackHeight.get(aBlock)).intValue();
1821        
1822        while(it.hasNext()) {
1823            Inst nInst = (Inst) it.next();
1824          
1825            blockHeight -= nInst.getInCount();
1826
1827            if(blockHeight < 0 ){
1828                throw new RuntimeException JavaDoc("Negative Stack Logical height has been attained: \n" +
1829                                           "StackHeight: " + blockHeight +
1830                                           "\nAt instruction:" + nInst +
1831                                           "\nBlock:\n" + aBlock +
1832                                           "\n\nMethod: " + aBlock.getBody().getMethod().getName()
1833                                           + "\n" + aBlock.getBody().getMethod()
1834                                           );
1835            }
1836
1837            blockHeight += nInst.getOutCount();
1838            
1839            //G.v().out.println(">>> " + nInst + " " + blockHeight);
1840
}
1841        
1842        
1843        Iterator succs = aBlock.getSuccs().iterator();
1844        while(succs.hasNext()) {
1845            Block b = (Block) succs.next();
1846            Integer JavaDoc i = (Integer JavaDoc) blockToLogicalStackHeight.get(b);
1847            if(i != null) {
1848                if(i.intValue() != blockHeight) {
1849                    throw new RuntimeException JavaDoc("incoherent logical stack height at block merge point " + b + aBlock);
1850                }
1851                
1852            } else {
1853                blockToLogicalStackHeight.put(b, new Integer JavaDoc(blockHeight));
1854                calculateLogicalStackHeightCheck(b);
1855            }
1856        }
1857    }
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868}
1869
1870class GroupIntPair
1871{
1872    Object JavaDoc group;
1873    int x;
1874    
1875    GroupIntPair(Object JavaDoc group, int x)
1876    {
1877        this.group = group;
1878        this.x = x;
1879    }
1880    
1881    public boolean equals(Object JavaDoc other)
1882    {
1883        if(other instanceof GroupIntPair)
1884            return ((GroupIntPair) other).group.equals(this.group) &&
1885                    ((GroupIntPair) other).x == this.x;
1886        else
1887            return false;
1888    }
1889    
1890    public int hashCode()
1891    {
1892        return group.hashCode() + 1013 * x;
1893    }
1894    
1895    
1896}
1897
Popular Tags