@Test public void testGetPcodeForInvoke() throws IOException{ ArrayList<Byte> classFile = new ArrayList<>(); TestClassFileCreator.appendMagic(classFile); TestClassFileCreator.appendVersions(classFile); TestClassFileCreator.appendCount(classFile, (short) 5); TestClassFileCreator.appendInvokeDynamicInfo(classFile, (short) 0, (short)2); TestClassFileCreator.appendNameAndType(classFile, (short) 3, (short) 4); TestClassFileCreator.appendUtf8(classFile, "dynamicMethodName"); TestClassFileCreator.appendUtf8(classFile,"(JJII)I"); byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile); AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes); String pCode = InvokeMethods.getPcodeForInvoke(1, constantPool, JavaInvocationType.INVOKE_DYNAMIC); StringBuilder expected = new StringBuilder(); String descriptor = DescriptorDecoder.getDescriptorForInvoke(1, constantPool, JavaInvocationType.INVOKE_DYNAMIC); List<JavaComputationalCategory> categories = DescriptorDecoder.getParameterCategories(descriptor); InvokeMethods.emitPcodeToMoveParams(expected, categories, false, 24); InvokeMethods.emitPcodeToResolveMethodReference(expected, 1, constantPool, JavaInvocationType.INVOKE_DYNAMIC); PcodeTextEmitter.emitIndirectCall(expected, InvokeMethods.CALL_TARGET); PcodeTextEmitter.emitPushCat1Value(expected, InvokeMethods.CAT_1_RETURN); System.out.println(pCode); System.out.println(expected); assertEquals("incorrect pcode for invoke dynamic: (JJII)I", expected.toString(), pCode); }
public static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type) { StringBuilder pCode = new StringBuilder(); String descriptor = DescriptorDecoder.getDescriptorForInvoke(offset, constantPool, type); List<JavaComputationalCategory> categories = DescriptorDecoder.getParameterCategories(descriptor); boolean includeThisPointer = type.equals(JavaInvocationType.INVOKE_VIRTUAL) || type.equals(JavaInvocationType.INVOKE_SPECIAL) || type.equals(JavaInvocationType.INVOKE_INTERFACE); int stackPurge = DescriptorDecoder.getStackPurge(descriptor); if (includeThisPointer){ stackPurge += 4; } emitPcodeToMoveParams(pCode, categories, includeThisPointer, stackPurge); emitPcodeToResolveMethodReference(pCode, offset, constantPool, type); PcodeTextEmitter.emitIndirectCall(pCode, CALL_TARGET); JavaComputationalCategory retType = DescriptorDecoder.getReturnCategoryOfMethodDescriptor(descriptor); switch (retType){ case CAT_1: PcodeTextEmitter.emitPushCat1Value(pCode, CAT_1_RETURN); break; case CAT_2: PcodeTextEmitter.emitPushCat2Value(pCode, CAT_2_RETURN); break; default: break; } return pCode.toString(); }
InvokeMethods { public static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type) { StringBuilder pCode = new StringBuilder(); String descriptor = DescriptorDecoder.getDescriptorForInvoke(offset, constantPool, type); List<JavaComputationalCategory> categories = DescriptorDecoder.getParameterCategories(descriptor); boolean includeThisPointer = type.equals(JavaInvocationType.INVOKE_VIRTUAL) || type.equals(JavaInvocationType.INVOKE_SPECIAL) || type.equals(JavaInvocationType.INVOKE_INTERFACE); int stackPurge = DescriptorDecoder.getStackPurge(descriptor); if (includeThisPointer){ stackPurge += 4; } emitPcodeToMoveParams(pCode, categories, includeThisPointer, stackPurge); emitPcodeToResolveMethodReference(pCode, offset, constantPool, type); PcodeTextEmitter.emitIndirectCall(pCode, CALL_TARGET); JavaComputationalCategory retType = DescriptorDecoder.getReturnCategoryOfMethodDescriptor(descriptor); switch (retType){ case CAT_1: PcodeTextEmitter.emitPushCat1Value(pCode, CAT_1_RETURN); break; case CAT_2: PcodeTextEmitter.emitPushCat2Value(pCode, CAT_2_RETURN); break; default: break; } return pCode.toString(); } }
InvokeMethods { public static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type) { StringBuilder pCode = new StringBuilder(); String descriptor = DescriptorDecoder.getDescriptorForInvoke(offset, constantPool, type); List<JavaComputationalCategory> categories = DescriptorDecoder.getParameterCategories(descriptor); boolean includeThisPointer = type.equals(JavaInvocationType.INVOKE_VIRTUAL) || type.equals(JavaInvocationType.INVOKE_SPECIAL) || type.equals(JavaInvocationType.INVOKE_INTERFACE); int stackPurge = DescriptorDecoder.getStackPurge(descriptor); if (includeThisPointer){ stackPurge += 4; } emitPcodeToMoveParams(pCode, categories, includeThisPointer, stackPurge); emitPcodeToResolveMethodReference(pCode, offset, constantPool, type); PcodeTextEmitter.emitIndirectCall(pCode, CALL_TARGET); JavaComputationalCategory retType = DescriptorDecoder.getReturnCategoryOfMethodDescriptor(descriptor); switch (retType){ case CAT_1: PcodeTextEmitter.emitPushCat1Value(pCode, CAT_1_RETURN); break; case CAT_2: PcodeTextEmitter.emitPushCat2Value(pCode, CAT_2_RETURN); break; default: break; } return pCode.toString(); } private  InvokeMethods(); }
InvokeMethods { public static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type) { StringBuilder pCode = new StringBuilder(); String descriptor = DescriptorDecoder.getDescriptorForInvoke(offset, constantPool, type); List<JavaComputationalCategory> categories = DescriptorDecoder.getParameterCategories(descriptor); boolean includeThisPointer = type.equals(JavaInvocationType.INVOKE_VIRTUAL) || type.equals(JavaInvocationType.INVOKE_SPECIAL) || type.equals(JavaInvocationType.INVOKE_INTERFACE); int stackPurge = DescriptorDecoder.getStackPurge(descriptor); if (includeThisPointer){ stackPurge += 4; } emitPcodeToMoveParams(pCode, categories, includeThisPointer, stackPurge); emitPcodeToResolveMethodReference(pCode, offset, constantPool, type); PcodeTextEmitter.emitIndirectCall(pCode, CALL_TARGET); JavaComputationalCategory retType = DescriptorDecoder.getReturnCategoryOfMethodDescriptor(descriptor); switch (retType){ case CAT_1: PcodeTextEmitter.emitPushCat1Value(pCode, CAT_1_RETURN); break; case CAT_2: PcodeTextEmitter.emitPushCat2Value(pCode, CAT_2_RETURN); break; default: break; } return pCode.toString(); } private  InvokeMethods(); static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type); }
InvokeMethods { public static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type) { StringBuilder pCode = new StringBuilder(); String descriptor = DescriptorDecoder.getDescriptorForInvoke(offset, constantPool, type); List<JavaComputationalCategory> categories = DescriptorDecoder.getParameterCategories(descriptor); boolean includeThisPointer = type.equals(JavaInvocationType.INVOKE_VIRTUAL) || type.equals(JavaInvocationType.INVOKE_SPECIAL) || type.equals(JavaInvocationType.INVOKE_INTERFACE); int stackPurge = DescriptorDecoder.getStackPurge(descriptor); if (includeThisPointer){ stackPurge += 4; } emitPcodeToMoveParams(pCode, categories, includeThisPointer, stackPurge); emitPcodeToResolveMethodReference(pCode, offset, constantPool, type); PcodeTextEmitter.emitIndirectCall(pCode, CALL_TARGET); JavaComputationalCategory retType = DescriptorDecoder.getReturnCategoryOfMethodDescriptor(descriptor); switch (retType){ case CAT_1: PcodeTextEmitter.emitPushCat1Value(pCode, CAT_1_RETURN); break; case CAT_2: PcodeTextEmitter.emitPushCat2Value(pCode, CAT_2_RETURN); break; default: break; } return pCode.toString(); } private  InvokeMethods(); static String getPcodeForInvoke(int offset, AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type);  }