001: package net.sf.jdec.jvminstructions.commands;
002:
003: import net.sf.jdec.blockhelpers.BranchHelper;
004: import net.sf.jdec.blockhelpers.IFHelper;
005: import net.sf.jdec.blockhelpers.LoopHelper;
006: import net.sf.jdec.blockhelpers.TryHelper;
007: import net.sf.jdec.blocks.IFBlock;
008: import net.sf.jdec.blocks.Switch.Case;
009: import net.sf.jdec.constantpool.ClassDescription;
010: import net.sf.jdec.core.DecompilerHelper;
011: import net.sf.jdec.core.GlobalVariableStore;
012: import net.sf.jdec.core.JvmOpCodes;
013: import net.sf.jdec.core.Operand;
014: import net.sf.jdec.reflection.Behaviour;
015: import net.sf.jdec.util.Util;
016:
017: import java.util.ArrayList;
018: import java.util.Iterator;
019: import java.util.Set;
020:
021: public class GotoCommand extends AbstractInstructionCommand {
022:
023: public GotoCommand(Behaviour context) {
024: super (context);
025:
026: }
027:
028: public int getSkipBytes() {
029: return 2;
030: }
031:
032: public void execute() {
033: Behaviour behavior = getContext();
034:
035: int currentForIndex = getCurrentInstPosInCode();
036: int i = currentForIndex;
037: int instructionPos = i;
038: int this GotoJump = -1;
039: byte[] info = getCode();
040: int b1 = info[++i]; // TODO: Replace by jumpaddress
041: int b2 = info[++i];
042: int z;
043: if (b1 < 0)
044: b1 = (256 + b1);
045: if (b2 < 0)
046: b2 = (256 + b2);
047:
048: int indexInst = ((((b1 << 8) | b2)) + (i - 2));
049: if (indexInst > 65535)
050: indexInst = indexInst - 65536;
051: if (indexInst < 0)
052: indexInst = 256 + indexInst;
053: this GotoJump = indexInst;
054: StringBuffer tend = new StringBuffer("");
055: Set methodifs = getContext().getMethodIfs();
056: int elseCloseLineNo = GlobalVariableStore.getElseCloseLineNo();
057: boolean isIfInScope = GlobalVariableStore.isIfInScope();
058: ClassDescription cd = getContext().getClassRef().getCd();
059: boolean ternaryCond = false;// isIFForThisElseATernaryIF(currentForIndex,
060: // methodifs, tend, info);
061:
062: if (ternaryCond) {
063: boolean prec = DecompilerHelper.isGotoPrecededByDUPSTORE(
064: currentForIndex, info);
065: java.lang.String val;
066: if (!prec) {
067: Operand f = getStack().getTopOfStack();
068: Operand f1 = getStack().getTopOfStack();
069:
070: if (tend.toString().equals("end") == false)
071: val = f1.getOperandValue() + f.getOperandValue()
072: + ":";
073: else
074: val = f1.getOperandValue() + f.getOperandValue()
075: + ")";
076: } else {
077: Operand f = getStack().getTopOfStack();
078: if (tend.toString().equals("end") == false)
079: val = f.getOperandValue() + ":";
080: else
081: val = f.getOperandValue() + ")";
082: }
083: Operand res = new Operand();
084: res.setOperandValue(val);
085: getStack().push(res);
086:
087: }
088: if (isIfInScope && !ternaryCond) {
089: Iterator iterIfHash = methodifs.iterator();
090: whileloop: while (iterIfHash.hasNext()) {
091: IFBlock ifs = (IFBlock) iterIfHash.next();
092: boolean prevGotoPresent = false;
093: int if_start = ifs.getIfStart();
094: boolean loop_start = getBranchFinder().isThisLoopStart(
095: ifs);
096: int this ifclose = ifs.getIfCloseLineNumber();
097: boolean donotgeneratelese = false;
098: if (getGenericFinder().isThisInstrStart(
099: (this ifclose - 3))
100: && getBranchFinder().isInstructionIF(
101: this ifclose - 3)) {
102: donotgeneratelese = true;
103: }
104: if ((ifs.getIfCloseLineNumber() - (i - 2)) == 0
105: && !loop_start && !donotgeneratelese
106: && !ifs.getDonotclose()) { // Removed
107: // Math.abs
108: // :
109: // belurs
110: elseCloseLineNo = indexInst;
111: // System.out.println("elseCloseLineNo "+elseCloseLineNo);
112: java.lang.String checkAgain = "";
113: // if(elseCloseLineNo > i)
114: // {
115:
116: Object ifsSorted[] = IFHelper.sortIFStructures();
117: IFBlock parent = IFHelper.getParentBlock(ifsSorted,
118: ifs.getIfStart());
119: ArrayList loopList = getContext()
120: .getBehaviourLoops();
121: int loopSize = loopList.size();
122: java.lang.String checkSwitch = "";
123: StringBuffer again = new StringBuffer("");
124: if (parent == null) {
125: ifs.setHasElse(true);
126: if (loopSize > 0) {
127: ifs.setElseCloseLineNumber(elseCloseLineNo);
128: checkAgain = "true";
129: } else
130: ifs.setElseCloseLineNumber(elseCloseLineNo);
131:
132: // ifs.setHasMatchingElseBeenGenerated(true);
133: if (!checkAgain.equalsIgnoreCase("true")
134: && getContext().getAllSwitchBlks() != null
135: && getContext().getAllSwitchBlks()
136: .size() > 0)
137: checkSwitch = "true";
138: elseCloseLineNo = ifs.getElseCloseLineNumber();
139: }
140:
141: else {
142: ifs.setHasElse(true);
143: ifs.setElseCloseLineNumber(elseCloseLineNo); // Check
144: // This
145: // logic
146: // ifs.setHasMatchingElseBeenGenerated(true);
147:
148: int tmpend = IFHelper.checkElseCloseLineNumber(
149: ifsSorted, parent, ifs, ifs
150: .getIfStart(), elseCloseLineNo,
151: again);
152: if (tmpend != -1
153: && !again.toString().equals("true")) {
154: ifs.setElseCloseLineNumber(tmpend);
155: elseCloseLineNo = ifs
156: .getElseCloseLineNumber();
157: }
158:
159: }
160: if (checkAgain.equals("true")
161: || again.toString().equals("true")) {
162: elseCloseLineNo = ifs.getElseCloseLineNumber(); //
163: elseCloseLineNo = IFHelper
164: .resetElseCloseNumber(loopList, ifs,
165: currentForIndex);
166: ifs.setElseCloseLineNumber(elseCloseLineNo);
167:
168: }
169: ArrayList switches = getContext()
170: .getAllSwitchBlks();
171:
172: int newelseend = -1;
173: if (switches != null && switches.size() > 0) {
174: newelseend = IFHelper
175: .resetEndofIFElseWRTSwitch(switches,
176: ifs,
177: ifs.getElseCloseLineNumber(),
178: currentForIndex, "else");
179: boolean valid = IFHelper.isNewEndValid(
180: newelseend, ifs, "else", ifs
181: .getElseCloseLineNumber());
182: if (valid) {
183: ifs.setElseCloseLineNumber(newelseend);
184: elseCloseLineNo = ifs
185: .getElseCloseLineNumber();
186: }
187: }
188:
189: //
190: if (GlobalVariableStore.getContinue_JumpOffsets()
191: .size() > 0) {
192: elseCloseLineNo = IFHelper
193: .resetElseCloseNumber(currentForIndex,
194: elseCloseLineNo);
195: ifs.setElseCloseLineNumber(elseCloseLineNo);
196: }
197:
198: if (elseCloseLineNo < (currentForIndex + 3)
199: && getContext().getAllSwitchBlks() != null
200: && getContext().getAllSwitchBlks().size() > 0) {
201: Case caseblk = null;
202: caseblk = IFHelper.isIFInCase(getContext(),
203: currentForIndex, ifs);
204: if (caseblk != null) {
205: elseCloseLineNo = IFHelper
206: .getElseEndwrtcaseblk(caseblk,
207: info, currentForIndex + 3);
208: ifs.setElseCloseLineNumber(elseCloseLineNo);
209: }
210:
211: }
212: // }
213: /*
214: * else if(elseCloseLineNo < i) // TODO: DOUBLE CHECK IF
215: * THIS IS REQD!!! { elseCloseLineNo =
216: * findElseCloseLineNumber(i,elseCloseLineNo,info); }
217: */
218: // TOFIX Problem of generating an else when it is not reqd
219: boolean loopEndalso = LoopHelper.isThisLoopEndAlso(
220: getContext().getBehaviourLoops(),
221: currentForIndex, ifs.getIfStart());
222: if (loopEndalso)
223: ifs.setElseCloseLineNumber(-1);
224: ArrayList gotos = cd.getGotoStarts();
225: ArrayList gotoj = cd.getGotojumps();
226: boolean skipElse = IFHelper.skipGeneratingElse(
227: gotos, gotoj, currentForIndex, ifs);
228: if (skipElse)
229: ifs.setElseCloseLineNumber(-1);
230:
231: if (!loopEndalso && !skipElse) {
232: if ((elseCloseLineNo > ifs
233: .getIfCloseLineNumber()) == false) {
234:
235: elseCloseLineNo = IFHelper
236: .getElseCloseFromInRangeIfStructures(
237: ifs, currentForIndex);
238: if (elseCloseLineNo != -1) {
239: ifs
240: .setElseCloseLineNumber(elseCloseLineNo);
241: }
242: }
243: if (elseCloseLineNo == -1) {
244: elseCloseLineNo = IFHelper
245: .checkElseCloseWRTAnyParentLoop(
246: ifs, currentForIndex, info);
247: }
248: boolean addelsestart = IFHelper
249: .addElseStart(currentForIndex);
250: if (elseCloseLineNo == -1) {
251: ArrayList lps = getContext()
252: .getBehaviourLoops();
253: if (lps != null && lps.size() > 0) {
254: Object[] sortedLoops = LoopHelper
255: .sortLoops(lps);
256: int parentLoopStart = LoopHelper
257: .getParentLoopStartForIf(
258: sortedLoops, ifs
259: .getIfStart());
260: if (parentLoopStart == -1) {
261: int by = ifs
262: .getIfCloseFromByteCode();
263: if (by > currentForIndex) {
264: for (int z1 = by; z1 < info.length; z1++) {
265: if (getGenericFinder()
266: .isThisInstrStart(
267: z1)) {
268: if (info[z1] == JvmOpCodes.ATHROW) {
269: elseCloseLineNo = z1;
270: break;
271: }
272: boolean retb = BranchHelper
273: .checkForReturn(
274: info,
275: z1);
276: if (retb) {
277: elseCloseLineNo = z1;
278: break;
279: }
280: }
281: }
282:
283: if (elseCloseLineNo != -1
284: && elseCloseLineNo > this GotoJump
285: && this GotoJump > currentForIndex) {
286: elseCloseLineNo = this GotoJump;
287: }
288:
289: }
290: }
291: }
292: }
293: if (addelsestart) {
294: addelsestart = IFHelper
295: .checkForInvalidElse(
296: currentForIndex, ifs, info);
297: }
298: if (addelsestart) {
299: if (elseCloseLineNo == this GotoJump) {
300: elseCloseLineNo = TryHelper
301: .checkForElseEndWRTExcepionTables(
302: ifs, elseCloseLineNo);
303: }
304: }
305: if (addelsestart) {
306:
307: IFBlock parElseBlock = IFHelper
308: .getParentElseBlockForThisElse(
309: currentForIndex, info);
310: if (parElseBlock != null) {
311: boolean elseg = parElseBlock
312: .hasMatchingElseBeenGenerated();
313: int ec = parElseBlock
314: .getElseCloseLineNumber();
315: int ifcl = parElseBlock
316: .getIfCloseLineNumber();
317: if (elseg) {
318: if (info[ifcl] == JvmOpCodes.GOTO) {
319: if ((ec - 3) == currentForIndex) {
320: addelsestart = false;
321: }
322: }
323: }
324: }
325:
326: }
327: if (addelsestart && elseCloseLineNo == -1) {
328: elseCloseLineNo = this GotoJump;
329: }
330: if (addelsestart
331: && elseCloseLineNo != -1
332: && elseCloseLineNo != ifs
333: .getIfCloseLineNumber()
334: && elseCloseLineNo > ifs
335: .getIfCloseLineNumber()) // changed
336: // by
337: // belurs
338: {
339: boolean breaks = IFHelper
340: .checkForBreakInAssociatedIf(ifs);
341: if (!breaks) {
342: ifs
343: .setHasMatchingElseBeenGenerated(true);
344: ifs
345: .setElseCloseLineNumber(elseCloseLineNo);
346: java.lang.String s = "";
347: int x = BranchHelper.getReqdGoto(
348: currentForIndex, info,
349: ifs.getElseCloseLineNumber());
350: StringBuffer sb = new StringBuffer("");
351: if (x != -1)
352: s = BranchHelper
353: .getBranchType(
354: currentForIndex,
355: x,
356: info,
357: getContext()
358: .getBehaviourLoops(),
359: sb);
360: GlobalVariableStore
361: .getBranchLabels()
362: .put(
363: DecompilerHelper
364: .newBranchLabel(
365: ifs,
366: s,
367: sb
368: .toString()),
369: new Integer(
370: ifs
371: .getElseCloseLineNumber()));
372: behavior.appendToBuffer("\n");
373: String tempString = "else\n{\n";
374: if (ifs.isElsebreakadded())
375:
376: ifs.setElsebreakinvalid(true);
377: GlobalVariableStore
378: .getElsestartadded()
379: .add(
380: new Integer(
381: currentForIndex));
382: behavior
383: .appendToBuffer(Util
384: .formatDecompiledStatement(tempString));
385: GlobalVariableStore
386: .setElsehasbegun(true);
387: }
388: // System.out.println("else has begun for else at
389: // "+currentForIndex);
390: } else // TODO : Recheck this else blk
391: {
392: if (elseCloseLineNo > ifs
393: .getIfCloseLineNumber()) {
394: // ifs.setHasMatchingElseBeenGenerated(true);
395: ifs
396: .setElseCloseLineNumber(elseCloseLineNo);
397: }
398: }
399: }
400: /////}
401: // ifs.setIfCloseLineNumber(-1);
402:
403: ifs.setIfHasBeenClosed(true);
404: }
405: }
406: }
407: /*if (isWhileInScope) // TODO: Check if this can be removed
408: {
409: if (whileIndex == 1)
410: isWhileInScope = false;
411: whileIndex--;
412: // Changed by belurs ..This line was producing an extra bracket in
413: // output
414: // tempString="\n}\n";
415: // behaviour.appendToBuffer( Util.formatDecompiledStatement(tempString); //
416: // Definitly source of bug
417: }*/
418:
419: GlobalVariableStore.setElseCloseLineNo(elseCloseLineNo);
420: GlobalVariableStore.setIfInScope(isIfInScope);
421: }
422:
423: }
|