001: /*
002: * BranchHelper.java Copyright (c) 2006,07 Swaroop Belur
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008:
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013:
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
017: *
018: */
019:
020: package net.sf.jdec.blockhelpers;
021:
022: import net.sf.jdec.blocks.IFBlock;
023: import net.sf.jdec.blocks.Loop;
024: import net.sf.jdec.blocks.Switch;
025: import net.sf.jdec.blocks.Switch.Case;
026: import net.sf.jdec.core.DecompilerHelper;
027: import net.sf.jdec.core.GlobalVariableStore;
028: import net.sf.jdec.core.JvmOpCodes;
029: import net.sf.jdec.core.ShortcutAnalyser;
030: import net.sf.jdec.core.DecompilerHelper.BranchLabel;
031: import net.sf.jdec.lookup.FinderFactory;
032: import net.sf.jdec.lookup.IFinder;
033: import net.sf.jdec.reflection.Behaviour;
034: import net.sf.jdec.util.ExecutionState;
035:
036: import java.util.*;
037:
038: /*******************************************************************************
039: * Helper functions for loops/switches
040: *
041: * @author sbelur
042: *
043: */
044: public class BranchHelper {
045:
046: public static boolean checkForInvalidDefault(int defStart,
047: int switchStart) {
048: Behaviour b = ExecutionState.getMethodContext();
049: Set ifs = b.getMethodIfs();
050: if (ifs == null)
051: return false;
052: Iterator it = ifs.iterator();
053: while (it.hasNext()) {
054: IFBlock ifb = (IFBlock) it.next();
055: if (ifb.getIfStart() == defStart) {
056: int ifj = getGenericFinder().getJumpAddress(
057: ifb.getIfStart());
058: Loop someloop = LoopHelper.getLoopGivenStart(ifj);
059: if (someloop != null) {
060: if (ifj < switchStart) {
061: return true;
062: }
063: }
064: } else if (ifb.getIfCloseLineNumber() == defStart) {
065: int ifsstart = ifb.getIfStart();
066: if (ifsstart < switchStart) {
067: return true;
068: }
069: }
070: }
071: return false;
072: }
073:
074: public static boolean checkForReturn(byte[] code, int i) {
075: boolean present = false;
076: int jvmInst = code[i];
077: boolean b = getGenericFinder().isThisInstrStart(i);
078: if (b == false)
079: return false;
080: switch (jvmInst) {
081: case JvmOpCodes.ARETURN:
082: case JvmOpCodes.IRETURN:
083: case JvmOpCodes.FRETURN:
084: case JvmOpCodes.DRETURN:
085: case JvmOpCodes.LRETURN:
086: case JvmOpCodes.RETURN:
087: present = true;
088: break;
089: default:
090: present = false;
091: break;
092: }
093: return present;
094: }
095:
096: private static Behaviour getContext() {
097: return ExecutionState.getMethodContext();
098: }
099:
100: private static IFinder getGenericFinder() {
101: return FinderFactory.getFinder(IFinder.BASE);
102: }
103:
104: private static IFinder getBranchFinder() {
105: return FinderFactory.getFinder(IFinder.BRANCH);
106: }
107:
108: public static int getReqdGoto(int start, byte[] info, int end) {
109: int x = -1;
110: for (int s = (start + 3); s <= end; s++) {
111: int cur = info[s];
112: if (cur == JvmOpCodes.GOTO) {
113: x = s;
114: }// break;}
115: }
116: boolean b = getGenericFinder().isThisInstrStart(x);
117: if (b)
118: return x;
119: else
120: return -1;
121: }
122:
123: public static java.lang.String getBranchTypeAtI(int i,
124: IFBlock ifst, StringBuffer sb) {
125: boolean skip = skipBranchCheck(i);
126: if (skip)
127: return "";
128: Iterator it = GlobalVariableStore.getBranchLabels().entrySet()
129: .iterator();
130: while (it.hasNext()) {
131: Map.Entry e = (Map.Entry) it.next();
132: int end = ((Integer) (e.getValue())).intValue();
133: if (end == i) {
134: DecompilerHelper.BranchLabel b = (DecompilerHelper.BranchLabel) e
135: .getKey();
136: IFBlock IF = b.getIF();
137: if (IF == ifst) {
138:
139: if (b.getLBL().trim().length() > 0) {
140: GlobalVariableStore.getLabelAssociated().put(
141: new Integer(i), "true");
142: }
143: sb.append(b.getBrlbl());
144: return b.getLBL();
145: }
146: }
147:
148: }
149:
150: return "";
151: }
152:
153: private static boolean skipBranchCheck(int i) {
154: boolean b = false;
155: Iterator it = GlobalVariableStore.getLabelAssociated()
156: .entrySet().iterator();
157: while (it.hasNext()) {
158: Map.Entry e = (Map.Entry) it.next();
159: java.lang.String skip = ((java.lang.String) (e.getValue()));
160: int end = ((Integer) e.getKey()).intValue();
161: if (i == end && skip.equals("true"))
162: b = true;
163: }
164: return b;
165: }
166:
167: public static java.lang.String getBranchType(int if_else_begin,
168: int GotoStart, byte[] info, ArrayList loops, StringBuffer sb) {
169: boolean over = false;
170: java.lang.String lbl = "";
171: int immGotoJmp = getGenericFinder().getJumpAddress(GotoStart);
172: int i = immGotoJmp;
173: boolean cont = continueFindingBranchType(immGotoJmp, info);
174:
175: // check whether immGotoJmp is loop start
176: int loop_end = LoopHelper.getloopEndForStart(loops, immGotoJmp);
177: boolean done = false;
178: if (loop_end != -1) {
179: // Some loop is present
180:
181: Object[] sortedLoops = LoopHelper.sortLoops(loops);
182: int parentLoopStart = LoopHelper.getParentLoopStartForIf(
183: sortedLoops, if_else_begin);
184: if (parentLoopStart == immGotoJmp) {
185: java.lang.String s = setJDecLabelForContinue(
186: parentLoopStart, loop_end);
187: sb.append(s);
188: lbl = "continue";
189: GlobalVariableStore.getContinue_JumpOffsets().add(
190: new Integer(immGotoJmp));
191: done = true;
192: } else {
193: int nextstart = LoopHelper.getNextLoopStart(immGotoJmp);
194: if (nextstart != -1) {
195: int loopend = LoopHelper.getloopEndForStart(loops,
196: nextstart);
197: if (loopend != -1) {
198: if (if_else_begin > loopend
199: && nextstart < GotoStart) {
200: sb.append("jdecLABEL" + immGotoJmp);
201: lbl = "continue ";
202: over = true;
203: GlobalVariableStore.getLABELS().put(
204: new Integer(immGotoJmp),
205: "jdecLABEL" + immGotoJmp);
206: }
207: }
208: if (over == false && nextstart < GotoStart) {
209: GlobalVariableStore.getBreak_JumpOffsets().add(
210: new Integer(nextstart));
211: sb.append("jdecLABEL" + nextstart);
212: GlobalVariableStore.getLABELS().put(
213: new Integer(nextstart),
214: "jdecLABEL" + nextstart);
215: lbl = "break";
216: }
217: }
218:
219: done = true;
220: }
221:
222: }
223:
224: if (done == false) {
225: while ((i < info.length))// && cont) // TODO: check why This was
226: // needed
227: {
228: int current = info[i];
229: if (current == JvmOpCodes.GOTO) {
230: // BigInteger b;
231:
232: if (i > immGotoJmp
233: && info[immGotoJmp] != JvmOpCodes.GOTO) {
234: lbl = "";
235: break;
236: }
237: boolean end = LoopHelper.isIndexEndOfLoop(loops, i);
238: if (end) {
239: int start = LoopHelper.getLoopStartForEnd(i,
240: loops);
241: if (start > if_else_begin) {
242: return lbl;
243: }
244: Object[] sortedLoops = LoopHelper
245: .sortLoops(loops);
246: int parentLoopStart = LoopHelper
247: .getParentLoopStartForIf(sortedLoops,
248: if_else_begin);
249: if (parentLoopStart == start) {
250: java.lang.String s = setJDecLabelForContinue(
251: parentLoopStart, i);
252: sb.append(s);
253: lbl = "continue";
254: GlobalVariableStore
255: .getContinue_JumpOffsets().add(
256: new Integer(immGotoJmp));
257: break;
258: } else {
259: int nextstart = LoopHelper
260: .getNextLoopStart(start);
261: if (nextstart != -1
262: && nextstart < GotoStart) {
263: GlobalVariableStore
264: .getBreak_JumpOffsets().add(
265: new Integer(nextstart));
266: sb.append("jdecLABEL" + nextstart);
267: GlobalVariableStore.getLABELS().put(
268: new Integer(nextstart),
269: "jdecLABEL" + nextstart);
270: }
271: lbl = "break";
272: break;
273: }
274:
275: } else {
276: lbl = "";
277: break;
278: }
279:
280: } else
281: i++;
282:
283: }
284: }
285:
286: return lbl;
287: }
288:
289: public static java.lang.String setJDecLabelForContinue(int start,
290: int end) {
291:
292: // Skip If IFBlock under examination is a Loop
293: ArrayList loops = getContext().getBehaviourLoops();
294: for (int s1 = 0; s1 < loops.size(); s1++) {
295: Loop l = (Loop) loops.get(s1);
296: int st = l.getStartIndex();
297: int ed = l.getEndIndex();
298: if (st == start && ed == end) {
299: return "";
300: }
301: }
302:
303: byte[] info;
304: if (getContext() != null) {
305: info = getContext().getCode();
306: int inst = info[start];
307: int loadIndex = DecompilerHelper.getLoadInstIndex(inst,
308: info, start);
309: if (loadIndex == -1)
310: return "";
311: else {
312: int pos = DecompilerHelper.getStoreInstPosInCode(info,
313: end, loadIndex);
314: if (pos != -1) {
315: GlobalVariableStore.getLABELS().put(
316: new Integer(pos), "jdecLABEL" + pos);
317: return "jdecLABEL" + pos;
318: }
319:
320: }
321: }
322:
323: return "";
324: }
325:
326: /***************************************************************************
327: * NOTE: This is not general purpose method tofind load inst...Skips
328: * ceratian loads see usages
329: */
330: public static boolean continueFindingBranchType(int i, byte info[]) {
331: // chkIndex is the index of the goto instruction.
332:
333: switch (info[i]) {
334:
335: case JvmOpCodes.ALOAD:
336:
337: case JvmOpCodes.ALOAD_0:
338:
339: case JvmOpCodes.ALOAD_1:
340:
341: case JvmOpCodes.ALOAD_2:
342:
343: case JvmOpCodes.ALOAD_3:
344:
345: case JvmOpCodes.DLOAD:
346:
347: case JvmOpCodes.DLOAD_0:
348:
349: case JvmOpCodes.DLOAD_1:
350:
351: case JvmOpCodes.DLOAD_2:
352:
353: case JvmOpCodes.DLOAD_3:
354:
355: case JvmOpCodes.FLOAD:
356:
357: case JvmOpCodes.FLOAD_0:
358:
359: case JvmOpCodes.FLOAD_1:
360:
361: case JvmOpCodes.FLOAD_2:
362:
363: case JvmOpCodes.FLOAD_3:
364:
365: case JvmOpCodes.ILOAD:
366:
367: case JvmOpCodes.ILOAD_0:
368:
369: case JvmOpCodes.ILOAD_1:
370:
371: case JvmOpCodes.ILOAD_2:
372:
373: case JvmOpCodes.ILOAD_3:
374:
375: case JvmOpCodes.LLOAD:
376:
377: case JvmOpCodes.LLOAD_0:
378:
379: case JvmOpCodes.LLOAD_1:
380:
381: case JvmOpCodes.LLOAD_2:
382:
383: case JvmOpCodes.LLOAD_3:
384: return true;
385:
386: }
387:
388: return false;
389: }
390:
391: public static int getSwitchOffset(byte[] info, int counter,
392: java.lang.String lbl) {
393: int b1 = info[++counter];
394: int b2 = info[++counter];
395: int b3 = info[++counter];
396: int b4 = info[++counter];
397:
398: if (b1 < 0)
399: b1 = (256 + b1);
400: if (b2 < 0)
401: b2 = (256 + b2);
402: if (b3 < 0)
403: b3 = (256 + b3);
404: if (b4 < 0)
405: b4 = (256 + b4);
406:
407: int jmp = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
408: if (jmp > 65535)
409: jmp = jmp - 65536;
410: if (lbl.equals("label"))
411: return jmp;
412: if (jmp < 0)
413: jmp = 512 + jmp;
414: return jmp;
415:
416: }
417:
418: public static void addBranchLabel(int classIndex, int i,
419: IFBlock ifst, int currentForIndex, byte[] info) {
420:
421: boolean add = true;
422: boolean continuetofind = false;
423: if (getGenericFinder().isThisInstrStart(classIndex - 3)
424: && info[classIndex - 3] == JvmOpCodes.GOTO) // GOTO_W?
425: {
426:
427: int resetVal = IFHelper.checkIfElseCloseNumber(
428: classIndex - 3, ifst);
429: ifst.setIfCloseLineNumber(resetVal);
430: } else {
431:
432: int resetVal = IFHelper.checkIfElseCloseNumber(classIndex,
433: ifst);
434: ifst.setIfCloseLineNumber(resetVal);
435: }
436:
437: // }
438:
439: // Added check here for detecting any other enclosing if whose end if
440: // less than
441: // current if close line number
442: // problem arose in case of short cut if operators where parent if block
443: // is not detected properly
444: if (ifst.getIfCloseLineNumber() != -1) {
445: int fromenclosing = IFHelper
446: .checkForIfEndFromEnclosingSetIfs(info, ifst);
447: if ((fromenclosing < ifst.getIfCloseLineNumber())
448: && fromenclosing != -1) {
449: ifst.setIfCloseLineNumber(fromenclosing);
450: }
451: }
452:
453: int if_start = ifst.getIfStart();
454: int if_end = ifst.getIfCloseLineNumber();
455: if (if_end == -1 || if_end < if_start) {
456: boolean b = false;
457: int bytecodeend = ifst.getIfCloseFromByteCode();
458: b = LoopHelper.isPositionALoopStart(getContext()
459: .getBehaviourLoops(), bytecodeend);
460: if (b) {
461: int loopend = LoopHelper.getloopEndForStart(
462: getContext().getBehaviourLoops(), bytecodeend);
463: if (loopend != -1) {
464: ifst.setIfCloseLineNumber(loopend);
465: // CHECK IF IFEND SET AS LOOP END IS SAME AS IF START
466: if (ifst.getIfStart() == ifst
467: .getIfCloseLineNumber()) {
468: ifst
469: .setIfCloseLineNumber(ifst.getIfStart() + 2 + 1);
470: }
471: }
472: }
473: }
474:
475: // Now check w.r.t do while kind of loops
476: int dowhileloopstart = IFHelper
477: .attachMarkerToIfInDoWhileKindOfLoop(ifst.getIfStart());
478: if (dowhileloopstart != -1) {
479: Loop someloop = LoopHelper
480: .getLoopGivenStart(dowhileloopstart);
481: if (someloop != null) {
482: int newLE = ifst.getIfStart() + 2 + 1;
483: if (newLE > someloop.getStartIndex()) {
484: ifst
485: .setIfCloseLineNumber(ifst.getIfStart() + 2 + 1);
486: someloop.setLoopendreset(true);
487: someloop
488: .setLoopendDueToReset(ifst.getIfStart() + 2 + 1);
489: }
490: }
491: }
492:
493: int k = ifst.getIfCloseFromByteCode();
494: k = k - 3;
495: ShortcutAnalyser sanalyser = getContext().getShortCutAnalyser();
496: if (getGenericFinder().isThisInstrStart(k)
497: && k > ifst.getIfStart()) {
498: boolean IF = getBranchFinder().isInstructionIF(k);
499: int nextifjump = getGenericFinder().getJumpAddress(k);
500: boolean ok = nextifjump > k;
501: if (IF
502: && k != ifst.getIfStart()
503: && ok
504: && (sanalyser.getShortCutStoreGivenIfStart(ifst
505: .getIfStart()) != null)) {
506: ifst.setDonotclose(true);
507: }
508: }
509:
510: k = ifst.getIfCloseLineNumber();
511: k = k - 3;
512: if (getGenericFinder().isThisInstrStart(k)
513: && ifst.getIfCloseFromByteCode() < ifst.getIfStart()) {
514: boolean IF = getBranchFinder().isInstructionIF(k);
515: if (IF
516: && k != ifst.getIfStart()
517: && (sanalyser.getShortCutStoreGivenIfStart(ifst
518: .getIfStart()) != null)) {
519: ifst.setDonotclose(true);
520: }
521: }
522:
523: java.lang.String s = "";
524: StringBuffer sb = new StringBuffer("");
525: int gotos = -1;
526: if (getGenericFinder().isThisInstrStart(currentForIndex + 3)
527: && info[currentForIndex + 3] == JvmOpCodes.GOTO) {
528: s = getBranchType(currentForIndex, currentForIndex + 3,
529: info, getContext().getBehaviourLoops(), sb, true);
530: if (s.trim().length() == 0) {
531: int end = LoopHelper.getClosestLoopEndForThisIf(
532: currentForIndex, getContext()
533: .getBehaviourLoops(), info);
534: if (end != -1) {
535: s = "break";
536: }
537:
538: }
539: // TODO
540: gotos = currentForIndex + 3;
541: } else {
542: int x = getReqdGoto(currentForIndex, info, ifst
543: .getIfCloseLineNumber());
544: if (x != -1) {
545: s = getBranchType(currentForIndex, x, info,
546: getContext().getBehaviourLoops(), sb);
547: gotos = x;
548: }
549:
550: }
551: if (gotos != -1) {
552: // TODO: Skip if IFSTRUCTURE is a loop
553:
554: int gotoj = getGenericFinder().getJumpAddress(gotos);
555: if (getGenericFinder().isThisInstrStart(gotoj)
556: && info[gotoj] == JvmOpCodes.RETURN) {
557: Iterator it = GlobalVariableStore.getRetAtIfElseEnd()
558: .keySet().iterator();
559: int gtJump = -1;
560: boolean skip = false;
561: if (ifst.getIfCloseLineNumber() + 2 < info.length) {
562: gtJump = getGenericFinder().getJumpAddress(
563: ifst.getIfCloseLineNumber());
564:
565: while (it.hasNext()) {
566: Integer ing = (Integer) it.next();
567: int jp = -1;
568: if (ing.intValue() + 2 < info.length) {
569: jp = getGenericFinder().getJumpAddress(
570: ing.intValue());
571: if (jp == gtJump) {
572: skip = true;
573: break;
574: }
575: }
576: }
577:
578: }
579: if (!skip)
580: GlobalVariableStore.getRetAtIfElseEnd().put(
581: new Integer(ifst.getIfCloseLineNumber()),
582: "return");
583: add = false;
584: }
585: }
586: if (s.length() == 0 && add) {
587:
588: ArrayList loops = getContext().getBehaviourLoops();
589: for (int z = ifst.getIfStart() + 3; z < ifst
590: .getIfCloseLineNumber(); z++) {
591: int temp = info[z];
592: if (getGenericFinder().isThisInstrStart(z)
593: && temp == JvmOpCodes.GOTO) {
594: int jump = getGenericFinder().getJumpAddress(z);
595: Object[] sortedLoops = LoopHelper.sortLoops(loops);
596: int parentLoopStart = LoopHelper
597: .getParentLoopStartForIf(sortedLoops, ifst
598: .getIfStart());
599: if (parentLoopStart != -1) {
600: int end = LoopHelper.getloopEndForStart(loops,
601: parentLoopStart);
602: if (end < jump
603: && ifst.getIfStart() > parentLoopStart
604: && ifst.getIfCloseLineNumber() < end) {
605: s = "break";
606: break;
607: }
608: }
609: }
610: }
611:
612: }
613: if (s.length() == 0 && add && gotos != -1) {
614: int y1 = gotos;
615: int z1 = getGenericFinder().getJumpAddress(y1);
616: ArrayList loops = getContext().getBehaviourLoops();
617: Object[] sortedLoops = LoopHelper.sortLoops(loops);
618: int parentLoopStart = LoopHelper.getParentLoopStartForIf(
619: sortedLoops, ifst.getIfStart());
620: if (parentLoopStart != -1) {
621: int end = LoopHelper.getloopEndForStart(loops,
622: parentLoopStart);
623: if (end < z1 && ifst.getIfStart() > parentLoopStart
624: && ifst.getIfCloseLineNumber() < end) {
625: s = "break";
626:
627: }
628: }
629:
630: }
631:
632: if (s.trim().length() == 0) {
633:
634: // detect here w.r.t switch case blocks
635: int byend = ifst.getIfCloseFromByteCode();
636: byend = byend - 3;
637: boolean st = getGenericFinder().isThisInstrStart(byend);
638: if (st) {
639:
640: if (info[byend] == JvmOpCodes.GOTO) {
641:
642: int jump = getGenericFinder().getJumpAddress(byend);
643: Case ecase = checkForEnclosingSwitchCase(info,
644: ifst, currentForIndex);
645: if (ecase != null) {
646: int ecaseend = ecase.getCaseEnd();
647: if (ecaseend < jump) {
648: add = true;
649: s = "break";
650: sb = new StringBuffer("");
651: }
652: }
653: }
654:
655: }
656: }
657:
658: if (s.trim().length() == 0) {
659:
660: ArrayList loops = getContext().getBehaviourLoops();
661: Object[] sortedLoops = LoopHelper.sortLoops(loops);
662: int parentLoopStart = LoopHelper.getParentLoopStartForIf(
663: sortedLoops, ifst.getIfStart());
664: if (parentLoopStart != -1) {
665: int loopEnd = LoopHelper.getloopEndForStart(loops,
666: parentLoopStart);
667: if (loopEnd == ifst.getIfStart()) {
668: add = true;
669: s = "break";
670: sb = new StringBuffer("");
671: }
672: }
673:
674: }
675:
676: if (add)
677: GlobalVariableStore.getBranchLabels().put(
678: DecompilerHelper.newBranchLabel(ifst, s, sb
679: .toString()),
680: new Integer(ifst.getIfCloseLineNumber()));
681:
682: int ifby = ifst.getIfCloseFromByteCode();
683: if (ifby == ifst.getIfCloseLineNumber()) {
684: TryHelper.checkIFEndWRTExceptionTables(ifst);
685: }
686:
687: // Finally just check if -3 is goto
688: int currentIfEnd = ifst.getIfCloseLineNumber();
689: if (currentIfEnd != -1) {
690: int p = currentIfEnd - 3;
691: boolean pst = getGenericFinder().isThisInstrStart(p);
692: if (pst) {
693: if (info[p] == JvmOpCodes.GOTO) {
694:
695: ifst.setIfCloseLineNumber(p);
696: // update branchLabels if any
697: Iterator entrys = GlobalVariableStore
698: .getBranchLabels().entrySet().iterator();
699: DecompilerHelper.BranchLabel reqdbrl = null;
700: while (entrys.hasNext()) {
701:
702: Map.Entry e = (Map.Entry) entrys.next();
703: BranchLabel brl = (BranchLabel) e.getKey();
704: Integer close = (Integer) e.getValue();
705: IFBlock storedIf = brl.getIF();
706: if (close != null
707: && (close.intValue() == currentIfEnd)
708: && storedIf == ifst) {
709: reqdbrl = brl;
710: break;
711: }
712: }
713: if (reqdbrl != null) {
714: GlobalVariableStore.getBranchLabels().remove(
715: reqdbrl);
716: GlobalVariableStore.getBranchLabels().put(
717: reqdbrl, new Integer(p));
718: }
719:
720: }
721: }
722:
723: }
724:
725: }
726:
727: public static java.lang.String getBranchType(int if_else_begin,
728: int GotoStart, byte[] info, ArrayList loops,
729: StringBuffer sb, boolean b) {
730: java.lang.String lbl = "";
731: boolean done = false;
732: int immGotoJmp = getGenericFinder().getJumpAddress(GotoStart);
733: int i = immGotoJmp;
734: boolean end = LoopHelper.isIndexEndOfLoop(loops, GotoStart);
735: int lend = -1;
736: if (end)
737: lend = GotoStart;
738:
739: if (!end) {
740: StringBuffer S = new StringBuffer("");
741: end = LoopHelper.checkForMatchingLoopAgain(loops,
742: immGotoJmp, S);
743: if (end)
744: lend = Integer.parseInt(S.toString());
745: }
746: if (end) {
747: int start = LoopHelper.getLoopStartForEnd(lend, loops);
748: if (start > if_else_begin) {
749: return lbl;
750: }
751: Object[] sortedLoops = LoopHelper.sortLoops(loops);
752: int parentLoopStart = LoopHelper.getParentLoopStartForIf(
753: sortedLoops, if_else_begin);
754: if (parentLoopStart == start) {
755: java.lang.String s = setJDecLabelForContinue(
756: parentLoopStart, lend);
757: sb.append(s);
758: lbl = "continue";
759: GlobalVariableStore.getContinue_JumpOffsets().add(
760: new Integer(immGotoJmp));
761:
762: } else {
763: int nextstart = LoopHelper.getNextLoopStart(start);
764: if (nextstart != -1) {
765: int loopend = LoopHelper.getloopEndForStart(loops,
766: nextstart);
767: if (loopend != -1) {
768: if (if_else_begin > loopend
769: && nextstart < GotoStart) {
770: sb.append("jdecLABEL" + start);
771: lbl = "continue";
772: done = true;
773: GlobalVariableStore.getLABELS().put(
774: new Integer(start),
775: "jdecLABEL" + start);
776: }
777: }
778: if (done == false && (nextstart < GotoStart)) {
779: GlobalVariableStore.getBreak_JumpOffsets().add(
780: new Integer(nextstart));
781: sb.append("jdecLABEL" + nextstart);
782: GlobalVariableStore.getLABELS().put(
783: new Integer(nextstart),
784: "jdecLABEL" + nextstart);
785: lbl = "break";
786: }
787: }
788:
789: }
790:
791: } else {
792: lbl = "";
793:
794: }
795: return lbl;
796: }
797:
798: public static Case checkForEnclosingSwitchCase(byte[] info,
799: IFBlock ifst, int currentForIndex) {
800:
801: ArrayList switches = getContext().getAllSwitchBlks();
802: if (switches == null || switches.size() == 0)
803: return null;
804: int ifstart = ifst.getIfStart();
805: HashMap caseblk_cends = new HashMap();
806: for (int z = 0; z < switches.size(); z++) {
807:
808: Switch s = (Switch) switches.get(z);
809: ArrayList cases = s.getAllCases();
810:
811: for (int k = 0; k < cases.size(); k++) {
812:
813: Case c = (Case) cases.get(k);
814: int cs = c.getCaseStart();
815: int ce = c.getCaseEnd();
816: if (ifstart > cs && ifstart < ce) {
817: caseblk_cends.put(new Integer(cs), c);
818: }
819:
820: }
821:
822: }
823: if (caseblk_cends.size() > 0) {
824: Set keys = caseblk_cends.keySet();
825: Integer sortedkeys[] = (Integer[]) keys
826: .toArray(new Integer[keys.size()]);
827: Arrays.sort(sortedkeys);
828: int len = sortedkeys.length;
829: Integer in = sortedkeys[len - 1];
830: return (Case) caseblk_cends.get(in);
831: }
832:
833: return null;
834: }
835:
836: public static boolean addReturnInIfBlock(int current, IFBlock ifb) {
837: if (GlobalVariableStore.isAthrowseen()) {
838: int athrowpos = GlobalVariableStore.getAthrowseenpos();
839: if (athrowpos != -1) {
840: if (current > athrowpos) {
841: if (current <= ifb.getIfCloseLineNumber()) {
842: if (current > ifb.getIfStart()
843: && athrowpos > ifb.getIfStart()) {
844: return false;
845: }
846: }
847:
848: }
849: }
850: }
851: return true;
852: }
853:
854: public static boolean addReturnInIfBlock(int current) {
855:
856: if (GlobalVariableStore.isAthrowseen()) {
857: int athrowpos = GlobalVariableStore.getAthrowseenpos();
858: Set ifs = getContext().getMethodIfs();
859: Iterator all = ifs.iterator();
860: while (all.hasNext()) {
861: IFBlock ifb = (IFBlock) all.next();
862: if (athrowpos != -1) {
863: if (current > athrowpos) {
864: if (current <= ifb.getIfCloseLineNumber()) {
865: if (current > ifb.getIfStart()
866: && athrowpos > ifb.getIfStart()) {
867: return false;
868: }
869: }
870:
871: }
872: }
873: }
874: }
875: return true;
876: }
877:
878: }
|