001: package net.sf.jdec.jvminstructions.commands;
002:
003: import net.sf.jdec.constantpool.ClassInfo;
004: import net.sf.jdec.constantpool.ClassDescription;
005: import net.sf.jdec.util.Util;
006: import net.sf.jdec.util.Constants;
007: import net.sf.jdec.reflection.Behaviour;
008: import net.sf.jdec.config.Configuration;
009: import net.sf.jdec.core.*;
010: import net.sf.jdec.main.ConsoleLauncher;
011:
012: import java.util.Stack;
013:
014: /*
015: * AnewarrayCommand.java Copyright (c) 2006,07 Swaroop Belur
016: *
017: * This program is free software; you can redistribute it and/or
018: * modify it under the terms of the GNU General Public License
019: * as published by the Free Software Foundation; either version 2
020: * of the License, or (at your option) any later version.
021:
022: * This program is distributed in the hope that it will be useful,
023: * but WITHOUT ANY WARRANTY; without even the implied warranty of
024: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025: * GNU General Public License for more details.
026:
027: * You should have received a copy of the GNU General Public License
028: * along with this program; if not, write to the Free Software
029: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
030: *
031: */
032:
033: /**
034: * @author swaroop belur
035: * @since 1.2.1
036: */
037: public class AnewarrayCommand extends AbstractInstructionCommand {
038:
039: public AnewarrayCommand(Behaviour context) {
040: super (context);
041: }
042:
043: public int getSkipBytes() {
044: return 2;
045: }
046:
047: public void execute() {
048:
049: Behaviour behavior = getContext();
050: int arraytimespush = GlobalVariableStore.getArraytimespush();
051: Stack arraytimesstack = GlobalVariableStore
052: .getArraytimesstack();
053: boolean embeddedANEWARRAY = GlobalVariableStore
054: .isEmbeddedANEWARRAY();
055: boolean embeddedANEWARRAYCopy = GlobalVariableStore
056: .isEmbeddedANEWARRAYCopy();
057: byte[] info = getContext().getCode();
058: OperandStack opStack = getContext().getOpStack();
059: int currentForIndex = getCurrentInstPosInCode();
060: ClassDescription cd = getContext().getClassRef().getCd();
061: int classIndex = getGenericFinder().getOffset(currentForIndex);//(temp1 << 8) | temp2);
062: ClassInfo cinfo = cd.getClassInfoAtCPoolPosition(classIndex);
063: java.lang.String Type = cd
064: .getUTF8String(cinfo.getUtf8pointer());
065: int bracketCount = Type.lastIndexOf("[");
066: bracketCount = bracketCount + 2; // the one which is required.
067: java.lang.String tempString = "";
068: Type = DecompilerHelper.parse(Type);
069: int brk = Type.indexOf("[");
070: if (brk >= 0)
071: Type = Type.substring(0, brk);
072: Type = Type.replace('/', '.');
073: if (Configuration.getShowImport().equals("true")) {
074: java.lang.String fullName = Type;
075: java.lang.String simpleName = "";
076: int lastdot = fullName.lastIndexOf(".");
077: if (lastdot != -1) {
078: simpleName = fullName.substring(lastdot + 1);
079: Type = simpleName;
080: ConsoleLauncher.addImportClass(fullName);
081: }
082: }
083:
084: tempString += Type;
085: java.lang.String brackets = "";
086:
087: for (int counter = 0; counter < bracketCount; counter++) {
088: brackets += "[]";
089: }
090: java.lang.String Ref = "JdecGeneratedVar"
091: + (currentForIndex + 2);
092: tempString += " " + brackets + " " + Ref + "= new " + Type;
093: brackets = "";
094: Operand count = (Operand) opStack.pop();
095: Integer intsize = null;
096: java.lang.String SizeofArray = "";
097:
098: SizeofArray = count.getOperandValue();
099: boolean dup = DecompilerHelper.isInstDup(info,
100: (currentForIndex + 3));
101: for (int counter = 0; counter < bracketCount; counter++) {
102: if (counter == 0 && !dup)
103: brackets += "[" + SizeofArray + "]";
104: else
105: brackets += "[]";
106: }
107:
108: if (!dup) {
109: tempString += brackets + ";";
110: behavior.appendToBuffer(Util
111: .formatDecompiledStatement(tempString)
112: + "\n");
113: tempString = "";
114: Operand op = new Operand();
115: op.setOperandValue(Ref);
116: op.setOperandType(Constants.IS_ARRAY_REF);
117: op.setClassType(Type);
118: opStack.push(op);
119: } else {
120: if (newfound()) {
121: Operand op = new Operand();
122: op.setOperandType(Constants.IS_ARRAY_REF);
123: java.lang.String Reference = Ref;
124: op.setClassType(Type + brackets);
125: Util.forceStartSpace = false;
126: op.setOperandValue("new " + Type + brackets + "\n{\n");
127: boolean r = false;//checkIFLoadInstIsPartOFTernaryCond(currentForIndex);
128: if (r) {
129: if (opStack.size() > 0) {
130: java.lang.String str = opStack.getTopOfStack()
131: .getOperandValue();
132: str = str + op.getOperandValue();
133: op.setOperandValue(str);
134: }
135: }
136:
137: opStack.push(op);
138:
139: try {
140: arraytimespush = Integer.parseInt(SizeofArray);
141: } catch (NumberFormatException ne) {
142: //Check whether prev was bipush or sipush
143: int currentPos = currentForIndex;
144: int prevs = getGenericFinder().getPrevStartOfInst(
145: currentPos);
146: if (info[prevs] == JvmOpCodes.BIPUSH) {
147: int bipushvalue = info[(prevs + 1)];
148: arraytimespush = bipushvalue;
149: } else {
150: if (info[prevs] == JvmOpCodes.SIPUSH) {
151: int sipushvalue = getGenericFinder()
152: .getOffset(prevs);
153: arraytimespush = sipushvalue;
154: } else {
155: arraytimespush = 0;
156: }
157:
158: }
159:
160: }
161: arraytimesstack.push("" + arraytimespush);
162: } else {
163: Operand op = new Operand();
164: op.setOperandType(Constants.IS_ARRAY_REF);
165: java.lang.String Reference = Ref;
166: op.setClassType(Type + brackets);
167: tempString += brackets;
168: if (arraytimesstack.size() == 0) {
169: Util.forceNewLine = false;
170: Util.forceStartSpace = true;
171: Util.forceTrimLines = false;
172: behavior
173: .appendToBuffer("\n"
174: + Util
175: .formatDecompiledStatement(tempString));
176: boolean specialtypearray = DecompilerHelper
177: .getArrayDimensionForAnewArrayCase(currentForIndex);
178: if (specialtypearray
179: && (bracketCount == 0 || bracketCount == 1)) {
180: behavior.appendToBuffer(Util
181: .formatDecompiledStatement("\n{\n"));
182: } else
183: behavior.appendToBuffer(Util
184: .formatDecompiledStatement("\n{\n"));
185: }
186:
187: else {
188: Util.forceNewLine = false;
189: Util.forceStartSpace = true;
190: Util.forceTrimLines = false;
191: java.lang.String c = "new " + Type + brackets;
192: behavior.appendToBuffer("\n"
193: + Util.formatDecompiledStatement(c));
194: boolean specialtypearray = DecompilerHelper
195: .getArrayDimensionForAnewArrayCase(currentForIndex);
196: if (specialtypearray
197: && (bracketCount == 0 || bracketCount == 1)) {
198: behavior.appendToBuffer(Util
199: .formatDecompiledStatement("\n{\n"));
200: } else
201: behavior.appendToBuffer(Util
202: .formatDecompiledStatement("\n{\n"));
203:
204: }
205:
206: boolean embed = DecompilerHelper.isAnewArrayEmbedded(
207: currentForIndex, info);
208: if (!embed) {
209: op.setOperandValue(Reference);
210: opStack.push(op);
211: } else {
212: if (opStack.size() > 0) {
213: opStack.getTopOfStack();
214: }
215: embeddedANEWARRAY = true;
216: embeddedANEWARRAYCopy = true;
217: }
218:
219: try {
220: arraytimespush = Integer.parseInt(SizeofArray);
221:
222: } catch (NumberFormatException ne) {
223: //Check whether prev was bipush or sipush
224: int currentPos = currentForIndex;
225: int prevs = getGenericFinder().getPrevStartOfInst(
226: currentPos);
227: if (info[prevs] == JvmOpCodes.BIPUSH) {
228: int bipushvalue = info[(prevs + 1)];
229: arraytimespush = bipushvalue;
230: } else {
231: if (info[prevs] == JvmOpCodes.SIPUSH) {
232: int sipushvalue = getGenericFinder()
233: .getOffset(prevs);
234: arraytimespush = sipushvalue;
235: } else {
236: arraytimespush = 0;
237: }
238:
239: }
240:
241: }
242: arraytimesstack.push("" + arraytimespush);
243: }
244: }
245:
246: GlobalVariableStore.setArraytimespush(arraytimespush);
247: GlobalVariableStore.setArraytimesstack(arraytimesstack);
248: GlobalVariableStore.setEmbeddedANEWARRAY(embeddedANEWARRAY);
249: GlobalVariableStore
250: .setEmbeddedNewArrayCopy(embeddedANEWARRAYCopy);
251: Util.forceTrimLines = true;
252: Util.forceNewLine = true;
253:
254: }
255: }
|