001: package net.sf.jdec.jvminstructions.commands;
002:
003: import java.util.ArrayList;
004: import java.util.Hashtable;
005:
006: import net.sf.jdec.config.Configuration;
007: import net.sf.jdec.constantpool.ClassDescription;
008: import net.sf.jdec.constantpool.MethodRef;
009: import net.sf.jdec.constantpool.NameAndType;
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.core.OperandStack;
015: import net.sf.jdec.main.ConsoleLauncher;
016: import net.sf.jdec.reflection.Behaviour;
017: import net.sf.jdec.util.Constants;
018: import net.sf.jdec.util.Util;
019:
020: public class InvokeStaticCommand extends AbstractInstructionCommand {
021:
022: public InvokeStaticCommand(Behaviour context) {
023: super (context);
024:
025: }
026:
027: public int getSkipBytes() {
028: return 2;
029: }
030:
031: public void execute() {
032: int dex;
033: boolean newfound = GlobalVariableStore.isNewfound();
034: boolean previnstwasinvoke = false;
035: int currentForIndex = getCurrentInstPosInCode();
036: int itemp = currentForIndex - 1;
037: boolean pushed = false;
038: Behaviour behavior = getContext();
039: boolean doNotPop = GlobalVariableStore.isDoNotPop();
040: String RET = "";
041: boolean codeStmtFormed = false;
042: String funcCall = "";
043: Operand op2;
044: ClassDescription cd = getContext().getClassRef().getCd();
045: cd.printAllUtf8StringInNameAndTypeObjects();
046: String tempString = "";
047: /*
048: * temp1=info[++i]; temp2=info[++i]; classIndex=((temp1 << 8) | temp2);
049: * if(classIndex < 0)classIndex=(temp1+1)*256-Math.abs(temp2);
050: */
051: byte[] info = getCode();
052: OperandStack opStack = getStack();
053: int i = getCurrentInstPosInCode();
054: int classIndex = getGenericFinder().getOffset(i);
055: i += 2;
056: MethodRef mref = cd.getMethodRefAtCPoolPosition(classIndex);
057: String classname = mref.getClassname();
058: String typeofmet = mref.getTypeofmethod();
059: Util.parseDescriptor(typeofmet);
060: ArrayList paramlist = Util.getParsedSignatureAsList();
061: boolean takeret = getStoreFinder().isNextInstAStore(
062: currentForIndex + 3);
063: int s1 = typeofmet.indexOf(")");
064: ArrayList returntype = null;
065: Operand op;
066: Operand op1;
067: String opvalue = "";
068: if (s1 != -1 && s1 + 1 < typeofmet.length()) {
069:
070: String rettp = typeofmet.substring(s1 + 1);
071:
072: Util.parseReturnType(rettp);
073: returntype = Util.getreturnSignatureAsList();
074: }
075: String pushStr = classname;
076:
077: if (returntype != null && returntype.size() > 0) {
078: pushStr = (java.lang.String) returntype.get(0);
079: }
080: if (pushStr != null && pushStr.trim().equalsIgnoreCase("void")) {
081: pushStr = classname;
082: }
083: DecompilerHelper.resetMethodParameters(opStack, paramlist,
084: currentForIndex);
085: DecompilerHelper.registerInnerClassIfAny(classname.replace('.',
086: '/'));
087: NameAndType ninfo = cd.getNameAndTypeAtCPoolPosition(mref
088: .getDescriptionPointer());
089: Hashtable methodLookUp = cd.getMethodLookUp();
090: Behaviour b = (Behaviour) methodLookUp.get(mref.getKey());
091:
092: int br = typeofmet.indexOf(")");
093: if (br != -1) {
094: char c;
095: if (typeofmet.length() >= (br + 1))
096: c = typeofmet.charAt(br + 1);
097: else
098: c = '?';
099: RET = "" + c;
100:
101: }
102: boolean argumentReturnTypeChecked = false;
103: String argumentRetType = "";
104: if (b != null) {
105: argumentRetType = b.getReturnType();
106: op1 = new Operand();
107: // op1.setCategory(Constants.CATEGORY1);
108: op1.setOperandType(Constants.IS_OBJECT_REF);
109: // if(!b.isHasBeenDissassembled()) {
110: int numParams = b.getMethodParams().length;
111: funcCall = b.getBehaviourName() + "(";
112: dex = 0;
113: /*
114: * for(int indx=numParams-1;indx>=0;indx--) { op2 =
115: * (Operand)opStack.pop();
116: * resetOperandValueIfNecessary(paramlist,indx,op2); if(indx > 0) {
117: * funcCall += op2.getOperandValue()+","; } else { funcCall +=
118: * op2.getOperandValue()+")"; } b.getOpStack().push(op2);
119: * op2.setClassType(classname); }
120: */
121: java.lang.String[] funcArray = new java.lang.String[numParams];
122: dex = 0;
123: for (int indx = numParams - 1; indx >= 0; indx--) {
124: op2 = (Operand) opStack.pop();
125: DecompilerHelper.resetOperandValueIfNecessary(
126: paramlist, indx, op2);
127: if (op2 != null && op2.getOperandValue() != null)
128: funcArray[dex++] = (op2.getOperandValue())
129: .toString();
130: else
131: funcArray[dex++] = "" + (op2.getOperandValue());
132:
133: }
134: for (int indx = funcArray.length - 1; indx >= 0; indx--) {
135: if (indx != 0) {
136: funcCall += funcArray[indx] + ",";
137: } else {
138: funcCall += funcArray[indx];
139: }
140:
141: }
142:
143: funcCall += ");\n";
144:
145: op1.setOperandValue(funcCall);
146: // opStack.push(op1);
147: /*
148: * b.setParentBehaviour(behaviour); Decompiler disassembler=new
149: * Decompiler(b,cd); disassembler.disassembleCode();
150: * disassembler=null;
151: */
152:
153: // behavior.appendToBuffer( Util.formatDecompiledStatement(funcCall);
154: // codeStatements+=";\n";
155: // codeStmtFormed=true;
156: // }
157: } else {
158: java.lang.String methodSignature = mref.getTypeofmethod(); // Should
159: // Be
160: // Refactored...Or
161: // getting
162: // called
163: // wrongly
164: br = methodSignature.indexOf(")");
165: if (br != -1) {
166: char c;
167: if (methodSignature.length() >= (br + 1))
168: c = methodSignature.charAt(br + 1);
169: else
170: c = '?';
171: argumentRetType = "" + c;
172:
173: }
174: methodSignature = methodSignature.substring(1,
175: methodSignature.indexOf(")"));
176: int numberOfParameters = paramlist.size();
177: // int numberOfParameters =
178: java.lang.String[] funcArray = new java.lang.String[numberOfParameters];
179: int index = 0;
180: int funcArrayIndex = 0;
181: dex = 0;
182: for (int indx = numberOfParameters - 1; indx >= 0; indx--) {
183: op2 = (Operand) opStack.pop();
184: DecompilerHelper.resetOperandValueIfNecessary(
185: paramlist, indx, op2);
186: if (op2 != null && op2.getOperandValue() != null)
187: funcArray[dex++] = (op2.getOperandValue())
188: .toString();
189: else
190: funcArray[dex++] = "" + (op2.getOperandValue());
191: funcArrayIndex++;
192: }
193:
194: // op2 = (Operand)opStack.pop();
195: // mref.getClassname()+"."+mref.getMethodName()
196: boolean funcCallFormed = false;
197: if (Configuration.getShowImport().equalsIgnoreCase("false")) {
198: funcCall += mref.getClassname().replace('/', '.') + "."
199: + mref.getMethodName() + "(";
200: funcCallFormed = true;
201: } else {
202: java.lang.String simplename = "";
203: java.lang.String fullName = mref.getClassname();
204: int lastSlash = mref.getClassname().lastIndexOf("/");
205: if (lastSlash == -1) {
206: lastSlash = mref.getClassname().lastIndexOf(".");
207: }
208: if (lastSlash != -1) {
209: simplename = fullName.substring(lastSlash + 1);
210: } else
211: simplename = fullName;
212: funcCall += simplename + "." + mref.getMethodName()
213: + "(";
214: fullName = fullName.replace('/', '.');
215: ConsoleLauncher.addImportClass(fullName);
216: funcCallFormed = true;
217:
218: }
219: for (int indx = funcArray.length - 1; indx >= 0; indx--) {
220: if (indx != 0) {
221: funcCall += funcArray[indx] + ",";
222: } else {
223: funcCall += funcArray[indx];
224: }
225:
226: }
227: if (funcCallFormed && funcCall.indexOf(";") == -1)
228: funcCall += ")";
229: op1 = new Operand();
230: // op1.setCategory(Constants.CATEGORY1);
231: op1.setOperandType(Constants.IS_OBJECT_REF);
232: op1.setOperandValue(funcCall);
233: // op3.setOperandValue(funcCall);
234: // opStack.push(op3);
235: }
236: /*
237: * if(isNextInstructionInvokeVirtual(info[i+1]) ||
238: * isNextInstructionInvokeSpecial(info[i+1]) ||
239: * isNextInstructionStore(info[i+1]) || isNextInstructionIf(info[i+1])) {
240: * //TODO need to check for other cases like switch /*java.lang.String
241: * Temp=op1.getOperandValue().toString();
242: *
243: * Temp+=";\n"; op1.setOperandValue(Temp); opStack.push(op1); } else {
244: * /*if(info[i+1] == JvmOpCodes.ATHROW && behaviour.getParentBehaviour() !=
245: * null) { // Can this be removed
246: * //behaviour.getParentBehaviour().getOpStack().push(op1);
247: * //behavior.appendToBuffer( funcCall+";\n"; } else {
248: *
249: * opStack.push(op1); // Commented by belurs // if(!codeStmtFormed) //
250: * behavior.appendToBuffer( Util.formatDecompiledStatement(funcCall); }
251: */
252: opvalue = (java.lang.String) op1.getOperandValue();
253: opvalue = opvalue.trim();
254: if (opvalue.endsWith(";")) {
255: opvalue = opvalue.substring(0, opvalue.lastIndexOf(";"));
256: }
257:
258: op1.setOperandValue(opvalue);
259: opvalue = (java.lang.String) op1.getOperandValue();
260: if (opvalue.startsWith("\n")) {
261: opvalue = opvalue.trim();
262: op1.setOperandValue(opvalue);
263: }
264: /*
265: * v=op1.getOperandValue(); bb=new StringBuffer("");
266: * Util.checkForImport(v,bb); // op1.setOperandValue(bb.toString());
267: */
268: if (getStoreFinder().isInstStore0(i + 1)) {
269: pushed = true;
270: opStack.push(op1);
271: op1.setClassType(pushStr);
272: } else if (getGenericFinder().isNextInstructionInvokeStatic(
273: (info[i + 1]))
274: || getGenericFinder().isNextInstructionInvokeVirtual(
275: info[i + 1])
276: || getGenericFinder().isNextInstructionInvokeInterface(
277: info[i + 1])
278: || getGenericFinder().isNextInstructionInvokeSpecial(
279: info[i + 1])
280: || getStoreFinder().isNextInstructionStore(i + 1)
281: || getBranchFinder().isNextInstructionIf(info[i + 1])
282: || (info[(i + 1)] == JvmOpCodes.PUTFIELD)
283: || (info[(i + 1)] == JvmOpCodes.PUTSTATIC)) { // TODO need to
284: // check for
285: // other cases
286: // like switch
287: if (RET.equalsIgnoreCase("V") == false) {
288:
289: pushed = true;
290: opStack.push(op1);
291: op1.setClassType(pushStr);
292:
293: } else {
294: tempString = Util.formatDecompiledStatement("\n"
295: + funcCall + ";\n");
296: behavior.appendToBuffer(tempString);
297: }
298: } else if (getLoadFinder().isNextInstructionLoad(i + 1)) {
299: if (RET.equalsIgnoreCase("V") == true) {
300: tempString = Util.formatDecompiledStatement("\n"
301: + funcCall + ";\n");
302: behavior.appendToBuffer(tempString);
303: } else {
304: pushed = true;
305: opStack.push(op1);
306: op1.setClassType(pushStr);
307: /*
308: * tempString=Util.formatDecompiledStatement(funcCall+";\n");
309: * behavior.appendToBuffer( tempString;
310: */
311: }
312:
313: } // ?
314: else if (getGenericFinder().isNextInstructionPop(i + 1)
315: || getBranchFinder().isNextInstructionReturn(i + 1)) {
316:
317: tempString = Util.formatDecompiledStatement("\n" + funcCall
318: + ";\n");
319: behavior.appendToBuffer(tempString);
320: opStack.push(op1);
321: op1.setClassType(pushStr);
322:
323: } else if (getGenericFinder().isNextInstructionConversionInst(
324: info[i + 1])) {
325: pushed = true;
326: opStack.push(op1);
327: op1.setClassType(pushStr);
328: }
329:
330: else if (DecompilerHelper.checkForValueReturn(info, (i + 1))) {
331: pushed = true;
332: opStack.push(op1);
333: op1.setClassType(pushStr);
334: } else if (getGenericFinder().checkForSomeSpecificInstructions(
335: info, (i + 1))) {
336: pushed = true;
337: opStack.push(op1);
338: op1.setClassType(pushStr);
339: } else {
340: // //opStack.push(op1);
341: if (RET.equalsIgnoreCase("V") == false) {
342: opStack.push(op1);
343: op1.setClassType(pushStr);
344: pushed = true;
345: } else {
346: tempString = Util.formatDecompiledStatement("\n"
347: + funcCall + ";\n");
348: behavior.appendToBuffer(tempString);
349: }
350: }
351:
352: if (pushed) {
353: boolean r = false;// checkIFLoadInstIsPartOFTernaryCond(currentForIndex);
354: if (r) {
355: if (opStack.size() > 0) {
356: java.lang.String str1 = opStack.getTopOfStack()
357: .getOperandValue();
358: java.lang.String str2 = opStack.getTopOfStack()
359: .getOperandValue();
360: java.lang.String str = str2 + str1;
361: Operand d = createOperand(str);
362: opStack.push(d);
363: }
364: }
365: }
366:
367: GlobalVariableStore.setNewfound(newfound);
368: GlobalVariableStore.setDoNotPop(doNotPop);
369:
370: }
371:
372: }
|