001: package net.sf.jdec.jvminstructions.commands;
002:
003: import java.util.ArrayList;
004:
005: import net.sf.jdec.core.DecompilerHelper;
006: import net.sf.jdec.core.GlobalVariableStore;
007: import net.sf.jdec.core.JvmOpCodes;
008: import net.sf.jdec.core.Operand;
009: import net.sf.jdec.core.OperandStack;
010: import net.sf.jdec.reflection.Behaviour;
011: import net.sf.jdec.util.Util;
012:
013: public class CastoreCommand extends AbstractInstructionCommand {
014:
015: public CastoreCommand(Behaviour context) {
016: super (context);
017:
018: }
019:
020: public int getSkipBytes() {
021: return 0;
022: }
023:
024: public void execute() {
025:
026: Behaviour behaviour = getContext();
027: byte[] info = behaviour.getCode();
028: Operand op = null;
029: Operand op1 = null;
030: Operand op2 = null;
031: boolean specialIASTORE = GlobalVariableStore.isSpecialIASTORE();
032:
033: int currentForIndex = getCurrentInstPosInCode();
034: OperandStack opStack = behaviour.getOpStack();
035: StringBuffer addtype = new StringBuffer();
036: int arraytimespush = GlobalVariableStore.getArraytimespush();
037: boolean primitiveastore = GlobalVariableStore
038: .isPrimitiveastore();
039: ArrayList starts = behaviour.getInstructionStartPositions();
040: boolean b = DecompilerHelper.checkForArrayPostIncrement(
041: currentForIndex, opStack, behaviour.getCode(),
042: "category1", addtype);
043: boolean bl2 = DecompilerHelper
044: .checkForArrayMultiAssignablePostIncrement(
045: currentForIndex, opStack, behaviour.getCode(),
046: "category1");
047: if (b && opStack.size() > 0
048: && GlobalVariableStore.getArraytimesstack().size() == 0) {
049: op = (Operand) opStack.pop();
050: op1 = (Operand) opStack.pop();
051: op2 = (Operand) opStack.pop();
052:
053: java.lang.String temp = "";
054: if (addtype.toString().equals("add"))
055: temp += op2.getOperandValue() + "["
056: + op1.getOperandValue() + "]" + "++";
057: else
058: temp += op2.getOperandValue() + "["
059: + op1.getOperandValue() + "]" + "--";
060: Operand o = opStack.peekTopOfStack();
061: o.setOperandValue(temp);
062:
063: } else if (bl2 && opStack.size() > 0
064: && GlobalVariableStore.getArraytimesstack().size() == 0) {
065: op = (Operand) opStack.pop();
066: op1 = (Operand) opStack.pop();
067: op2 = (Operand) opStack.pop();
068:
069: java.lang.String temp = "";
070: temp += op2.getOperandValue() + "[" + op1.getOperandValue()
071: + "]" + "=";
072: Operand o = opStack.peekTopOfStack();
073: temp = temp + o.getOperandValue();
074: o.setOperandValue(temp);
075: }
076:
077: else {
078: if (GlobalVariableStore.getSkipPrimitiveArrayStores()
079: .contains(new Integer(currentForIndex)) == false) {
080: java.lang.String tempString = "";
081: op = (Operand) opStack.pop();
082: op1 = (Operand) opStack.pop();
083: if (opStack.size() > 0) {
084: op2 = (Operand) opStack.pop();
085: tempString = op2.getOperandValue() + "["
086: + op1.getOperandValue() + "]="
087: + op.getOperandValue() + ";\n";
088: }
089: if (GlobalVariableStore.getArraytimesstack().size() == 0) {
090: int curpos = currentForIndex;
091: if (curpos - 3 > 0
092: && (info[curpos - 1] == JvmOpCodes.DUP_X2
093: || info[curpos - 1] == JvmOpCodes.DUP
094: || info[curpos - 1] == JvmOpCodes.DUP2
095: || info[curpos - 1] == JvmOpCodes.DUP_X1
096: || info[curpos - 1] == JvmOpCodes.DUP2_X1 || info[curpos - 1] == JvmOpCodes.DUP2_X2)
097: && info[curpos - 2] == JvmOpCodes.I2C
098: && info[curpos - 3] == JvmOpCodes.IADD) {
099: tempString = "++" + op2.getOperandValue() + "["
100: + op1.getOperandValue() + "]";
101: java.lang.String v1 = op2.getOperandValue()
102: + "[" + op1.getOperandValue() + "]";
103: java.lang.String v2 = opStack.peekTopOfStack()
104: .getOperandValue();
105: if (v2.equals(v1)) {
106: opStack.pop();
107: }
108:
109: opStack.push(createOperand(tempString));
110: } else if (curpos - 3 > 0
111: && (info[curpos - 1] == JvmOpCodes.DUP_X2
112: || info[curpos - 1] == JvmOpCodes.DUP
113: || info[curpos - 1] == JvmOpCodes.DUP2
114: || info[curpos - 1] == JvmOpCodes.DUP_X1
115: || info[curpos - 1] == JvmOpCodes.DUP2_X1 || info[curpos - 1] == JvmOpCodes.DUP2_X2)
116: && info[curpos - 2] == JvmOpCodes.I2C
117: && info[curpos - 3] == JvmOpCodes.ISUB) {
118: tempString = "--" + op2.getOperandValue() + "["
119: + op1.getOperandValue() + "]";
120: java.lang.String v1 = op2.getOperandValue()
121: + "[" + op1.getOperandValue() + "]";
122: java.lang.String v2 = opStack.peekTopOfStack()
123: .getOperandValue();
124: if (v2.equals(v1)) {
125: opStack.pop();
126: }
127: opStack.push(createOperand(tempString));
128: } else if (curpos - 4 > 0
129: && info[curpos - 1] == JvmOpCodes.I2C
130: && info[curpos - 2] == JvmOpCodes.IADD
131: && info[curpos - 3] == JvmOpCodes.ICONST_1
132: && (info[curpos - 4] == JvmOpCodes.DUP_X2
133: || info[curpos - 4] == JvmOpCodes.DUP
134: || info[curpos - 4] == JvmOpCodes.DUP2
135: || info[curpos - 4] == JvmOpCodes.DUP_X1
136: || info[curpos - 4] == JvmOpCodes.DUP2_X1 || info[curpos - 4] == JvmOpCodes.DUP2_X2)) {
137: tempString = op2.getOperandValue() + "["
138: + op1.getOperandValue() + "]++";
139: java.lang.String v1 = op2.getOperandValue()
140: + "[" + op1.getOperandValue() + "]";
141: java.lang.String v2 = opStack.peekTopOfStack()
142: .getOperandValue();
143: if (v2.equals(v1)) {
144: opStack.pop();
145: }
146: opStack.push(createOperand(tempString));
147: } else if (curpos - 4 > 0
148: && info[curpos - 1] == JvmOpCodes.I2C
149: && info[curpos - 2] == JvmOpCodes.ISUB
150: && info[curpos - 3] == JvmOpCodes.ICONST_1
151: && (info[curpos - 4] == JvmOpCodes.DUP_X2
152: || info[curpos - 4] == JvmOpCodes.DUP
153: || info[curpos - 4] == JvmOpCodes.DUP2
154: || info[curpos - 4] == JvmOpCodes.DUP_X1
155: || info[curpos - 4] == JvmOpCodes.DUP2_X1 || info[curpos - 4] == JvmOpCodes.DUP2_X2)) {
156: tempString = op2.getOperandValue() + "["
157: + op1.getOperandValue() + "]--";
158: java.lang.String v1 = op2.getOperandValue()
159: + "[" + op1.getOperandValue() + "]";
160: java.lang.String v2 = opStack.peekTopOfStack()
161: .getOperandValue();
162: if (v2.equals(v1)) {
163: opStack.pop();
164: }
165: opStack.push(createOperand(tempString));
166: } else {
167: if (GlobalVariableStore
168: .getSkipPrimitiveArrayStores()
169: .contains(new Integer(currentForIndex)) == false) {
170: behaviour
171: .appendToBuffer(Util
172: .formatDecompiledStatement(tempString));
173: }
174: }
175: } else {
176:
177: primitiveastore = true;
178: java.lang.String newvalue = "";
179: arraytimespush = Integer
180: .parseInt(GlobalVariableStore
181: .getArraytimesstack().peek()
182: .toString());
183: if (arraytimespush > 0) {
184:
185: int curpos = currentForIndex;
186:
187: if (curpos - 3 > 0
188: && DecompilerHelper
189: .isArrayElement(curpos + 1)
190: && (info[curpos - 1] == JvmOpCodes.DUP_X2
191: || info[curpos - 1] == JvmOpCodes.DUP
192: || info[curpos - 1] == JvmOpCodes.DUP2
193: || info[curpos - 1] == JvmOpCodes.DUP_X1
194: || info[curpos - 1] == JvmOpCodes.DUP2_X1 || info[curpos - 1] == JvmOpCodes.DUP2_X2)
195: && info[curpos - 2] == JvmOpCodes.I2C
196: && info[curpos - 3] == JvmOpCodes.IADD) {
197: if (!newfound())
198: newvalue = "++" + op2.getOperandValue()
199: + "[" + op1.getOperandValue()
200: + "]";
201: else {
202: if (opStack.size() > 0) {
203: java.lang.String topv = opStack
204: .getTopOfStack()
205: .getOperandValue();
206: if (topv.trim().startsWith("++")) {
207: newvalue = op2
208: .getOperandValue()
209: + topv;
210: } else
211: newvalue = "++"
212: + op2.getOperandValue()
213: + topv;
214: if (topv.equals(opStack
215: .peekTopOfStack()
216: .getOperandValue())) {
217: opStack.pop();
218: }
219: }
220: }
221:
222: } else if (curpos - 3 > 0
223: && DecompilerHelper
224: .isArrayElement(curpos + 1)
225: && (info[curpos - 1] == JvmOpCodes.DUP_X2
226: || info[curpos - 1] == JvmOpCodes.DUP
227: || info[curpos - 1] == JvmOpCodes.DUP2
228: || info[curpos - 1] == JvmOpCodes.DUP_X1
229: || info[curpos - 1] == JvmOpCodes.DUP2_X1 || info[curpos - 1] == JvmOpCodes.DUP2_X2)
230: && info[curpos - 2] == JvmOpCodes.I2C
231: && info[curpos - 3] == JvmOpCodes.ISUB) {
232: if (!newfound())
233: newvalue = "--" + op2.getOperandValue()
234: + "[" + op1.getOperandValue()
235: + "]";
236: else {
237: if (opStack.size() > 0) {
238:
239: java.lang.String topv = opStack
240: .getTopOfStack()
241: .getOperandValue();
242: if (topv.trim().startsWith("--")) {
243: newvalue = op2
244: .getOperandValue()
245: + topv;
246: } else
247: newvalue = "--"
248: + op2.getOperandValue()
249: + topv;//
250: if (topv.equals(opStack
251: .peekTopOfStack()
252: .getOperandValue())) {
253: opStack.pop();
254: }
255:
256: }
257: }
258:
259: } else if (curpos - 4 > 0
260: && DecompilerHelper
261: .isArrayElement(curpos + 1)
262: && info[curpos - 1] == JvmOpCodes.I2C
263: && info[curpos - 2] == JvmOpCodes.IADD
264: && (info[curpos - 3] == JvmOpCodes.ICONST_1
265: || info[curpos - 4] == JvmOpCodes.DUP_X2
266: || info[curpos - 4] == JvmOpCodes.DUP
267: || info[curpos - 4] == JvmOpCodes.DUP2
268: || info[curpos - 4] == JvmOpCodes.DUP_X1
269: || info[curpos - 4] == JvmOpCodes.DUP2_X1 || info[curpos - 4] == JvmOpCodes.DUP2_X2)) {
270: if (!newfound())
271: newvalue = op2.getOperandValue() + "["
272: + op1.getOperandValue() + "]++";
273: else {
274: if (opStack.size() > 0) {
275:
276: java.lang.String topv = opStack
277: .getTopOfStack()
278: .getOperandValue();
279: newvalue = op2.getOperandValue()
280: + topv + "++";
281: if (topv.equals(opStack
282: .peekTopOfStack()
283: .getOperandValue())) {
284: opStack.pop();
285: }
286:
287: }
288: }
289:
290: } else if (curpos - 4 > 0
291: && DecompilerHelper
292: .isArrayElement(curpos + 1)
293: && info[curpos - 1] == JvmOpCodes.I2C
294: && info[curpos - 2] == JvmOpCodes.ISUB
295: && (info[curpos - 3] == JvmOpCodes.ICONST_1
296: || info[curpos - 4] == JvmOpCodes.DUP_X2
297: || info[curpos - 4] == JvmOpCodes.DUP
298: || info[curpos - 4] == JvmOpCodes.DUP2
299: || info[curpos - 4] == JvmOpCodes.DUP_X1
300: || info[curpos - 4] == JvmOpCodes.DUP2_X1 || info[curpos - 4] == JvmOpCodes.DUP2_X2)) {
301:
302: if (!newfound())
303: newvalue = op2.getOperandValue() + "["
304: + op1.getOperandValue() + "]--";
305: else {
306: if (opStack.size() > 0) {
307:
308: java.lang.String topv = opStack
309: .getTopOfStack()
310: .getOperandValue();
311: newvalue = op2.getOperandValue()
312: + topv + "--";
313: if (topv.equals(opStack
314: .peekTopOfStack()
315: .getOperandValue())) {
316: opStack.pop();
317: }
318: }
319: }
320:
321: } else
322: newvalue = "";
323: if (newvalue.length() > 0) {
324: StringBuffer v = new StringBuffer("");
325: int c = getGenericFinder()
326: .isNextInstructionConversionInst(
327: currentForIndex + 1, v);
328: if (c != -1
329: && newvalue.indexOf(v.toString()) == -1) {
330: newvalue = "(" + v.toString() + ")"
331: + newvalue;
332: }
333: }
334:
335: // ///////////////
336: if (GlobalVariableStore
337: .getSkipPrimitiveArrayStores()
338: .contains(new Integer(currentForIndex)) == false) {
339:
340: if (newfound()) {
341: // z=createOperand(op.getOperandValue());
342: // Operand y=opStack.getTopOfStack();
343: java.lang.String newv = op2
344: .getOperandValue()
345: + op.getOperandValue();
346: if (newvalue.length() > 0) {
347: newv = newvalue;
348: specialIASTORE = true;
349: }
350: arraytimespush = Integer
351: .parseInt(GlobalVariableStore
352: .getArraytimesstack()
353: .pop().toString());
354: arraytimespush--;
355: if (arraytimespush == 0) {
356: newv += "}";
357: } else {
358: GlobalVariableStore
359: .getArraytimesstack()
360: .push("" + arraytimespush);
361: newv += ",";
362: }
363: opStack.push(createOperand(newv));
364: } else {
365: arraytimespush = Integer
366: .parseInt(GlobalVariableStore
367: .getArraytimesstack()
368: .pop().toString());
369: arraytimespush--;
370: if (arraytimespush == 0) {
371:
372: boolean closeImmediate = false; // for the
373: // parent
374: // actually
375: if (GlobalVariableStore
376: .getArraytimesstack()
377: .size() > 0) {
378: int oldstacksize = Integer
379: .parseInt(GlobalVariableStore
380: .getArraytimesstack()
381: .pop()
382: .toString());
383: int newstacksize = oldstacksize - 1;
384: if (newstacksize != 0)
385: GlobalVariableStore
386: .getArraytimesstack()
387: .push(
388: ""
389: + newstacksize);
390: else
391: closeImmediate = true;
392: // codeStatements+="}";
393: }
394:
395: if (GlobalVariableStore
396: .getArraytimesstack()
397: .isEmpty()) {
398: if (newvalue.length() > 0) {
399: behaviour
400: .appendToBuffer(newvalue
401: + "}");
402: int count = arrayClosingBracketCount(currentForIndex);
403: java.lang.String temp = "";
404: for (int z = 1; z <= count; z++) {
405: temp += "\n}";
406: if (z < count)
407: temp += "\n";
408:
409: }
410: // Util.forceNewLine=false;
411: Util.forceTrimLines = false;
412: behaviour
413: .appendToBuffer(Util
414: .formatDecompiledStatement(temp)
415: + ";\n");
416: Util.forceNewLine = true;
417: Util.forceTrimLines = true;
418: specialIASTORE = true;
419: } else {
420: behaviour.appendToBuffer(op
421: .getOperandValue()
422: + "}");
423: int count = arrayClosingBracketCount(currentForIndex);
424: java.lang.String temp = "";
425: for (int z = 1; z <= count; z++) {
426: temp += "\n}";
427: if (z < count)
428: temp += "\n";
429: }
430: Util.forceStartSpace = false;
431: Util.forceNewLine = false;
432: Util.forceTrimLines = false;
433: behaviour
434: .appendToBuffer(Util
435: .formatDecompiledStatement(temp)
436: + ";\n");
437: Util.forceStartSpace = true;
438: Util.forceTrimLines = false;
439: Util.forceNewLine = true;
440: }
441: } else {
442: if (newvalue.length() > 0) {
443: behaviour
444: .appendToBuffer(newvalue
445: + "},");
446: specialIASTORE = true;
447: } else {
448: behaviour.appendToBuffer(op
449: .getOperandValue()
450: + "},");
451: }
452: if (closeImmediate) {
453: do {
454: Util.forceStartSpace = false;
455: Util.forceNewLine = false;
456: Util.forceTrimLines = false;
457: if (GlobalVariableStore
458: .getArraytimesstack()
459: .size() > 0)
460: behaviour
461: .appendToBuffer(Util
462: .formatDecompiledStatement("\n},\n"));
463: else {
464: behaviour
465: .appendToBuffer(Util
466: .formatDecompiledStatement("\n};\n"));
467: }
468: Util.forceStartSpace = true;
469: Util.forceNewLine = true;
470: Util.forceTrimLines = true;
471:
472: if (GlobalVariableStore
473: .getArraytimesstack()
474: .size() > 0) {
475: int oldstacksize = Integer
476: .parseInt(GlobalVariableStore
477: .getArraytimesstack()
478: .pop()
479: .toString());
480: int newstacksize = oldstacksize - 1;
481: if (newstacksize != 0) {
482: GlobalVariableStore
483: .getArraytimesstack()
484: .push(
485: ""
486: + newstacksize);
487: closeImmediate = false;
488: } else {
489: closeImmediate = true;
490: }
491: } else {
492: closeImmediate = false;
493: }
494:
495: } while (closeImmediate);
496:
497: }
498:
499: }
500:
501: } else {
502: GlobalVariableStore
503: .getArraytimesstack()
504: .push("" + arraytimespush);
505: /*
506: * if(isThisInstrStart(starts,(currentForIndex-1)) &&
507: * isInstructionAnyDUP(info[currentForIndex-1]) &&
508: * newvalue!=null &&
509: * newvalue.trim().length() > 0){
510: * if(newvalue!=null &&
511: * (newvalue.trim().startsWith("++") ||
512: * newvalue.trim().startsWith("--")) &&
513: * opStack.size() > 0) { java.lang.String
514: * tpv=opStack.peekTopOfStack().getOperandValue().trim();
515: * if("++".concat(tpv).equals(newvalue) ||
516: * "--".concat(tpv).equals(newvalue)){
517: * opStack.pop(); } }
518: *
519: * opStack.push(createOperand(newvalue)); }
520: */
521: // else{
522: if (newvalue.length() > 0) {
523: behaviour
524: .appendToBuffer(newvalue
525: + ",");
526: specialIASTORE = true;
527: } else {
528:
529: if (getStoreFinder()
530: .isInstPrimitiveArrayStore(
531: info[(currentForIndex + 1)])
532: && tempString != null
533: && tempString.length() > 0)
534: behaviour
535: .appendToBuffer(tempString);
536: else
537: behaviour.appendToBuffer(op
538: .getOperandValue()
539: + ",");
540: }
541: // }
542: }
543: }
544: }
545: }
546: }
547: } else {
548:
549: if (opStack.size() > 2 && !newfound()) {
550: opStack.pop();
551: opStack.pop();
552: }
553:
554: }
555: int nextinst = info[currentForIndex + 1];
556: if (getGenericFinder()
557: .isThisInstrStart(currentForIndex + 1)
558: && nextinst == JvmOpCodes.AASTORE) {
559: GlobalVariableStore.getSkipaastores().add(
560: new Integer(currentForIndex + 1));
561: }
562:
563: }
564:
565: GlobalVariableStore.setSpecialIASTORE(specialIASTORE);
566: GlobalVariableStore.setArraytimespush(arraytimespush);
567: GlobalVariableStore.setPrimitiveastore(primitiveastore);
568: }
569:
570: }
|