Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JVMClassInfo$Initializer.setBootstrapMethod ArrayIndexOutOfBoundsException #53

Closed
gayanW opened this issue May 22, 2018 · 17 comments
Closed

Comments

@gayanW
Copy link
Collaborator

gayanW commented May 22, 2018

[junit] Picked up _JAVA_OPTIONS: -Xmx2048m -Xms512m
[junit] Running TypeNameTest
[junit]   running jpf with args:
[junit] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.701 sec
[junit] java.lang.ArrayIndexOutOfBoundsException: 1
[junit] 	at gov.nasa.jpf.jvm.JVMClassInfo$Initializer.setBootstrapMethod(JVMClassInfo.java:93)
[junit] 	at gov.nasa.jpf.jvm.ClassFile.setBootstrapMethod(ClassFile.java:659)
[junit] 	at gov.nasa.jpf.jvm.ClassFile.parseBootstrapMethodAttr(ClassFile.java:1422)
[junit] 	at gov.nasa.jpf.jvm.JVMClassInfo$Initializer.setClassAttribute(JVMClassInfo.java:80)
[junit] 	at gov.nasa.jpf.jvm.ClassFile.setClassAttribute(ClassFile.java:636)
[junit] 	at gov.nasa.jpf.jvm.ClassFile.parseClassAttributes(ClassFile.java:1306)
[junit] 	at gov.nasa.jpf.jvm.ClassFile.parse(ClassFile.java:875)
[junit] 	at gov.nasa.jpf.jvm.JVMClassInfo$Initializer.<init>(JVMClassInfo.java:48)
[junit] 	at gov.nasa.jpf.jvm.JVMClassInfo.<init>(JVMClassInfo.java:619)
[junit] 	at gov.nasa.jpf.jvm.JVMClassFileContainer$JVMClassFileMatch.createClassInfo(JVMClassFileContainer.java:58)
[junit] 	at gov.nasa.jpf.jvm.JVMClassFileContainer$JVMClassFileMatch.createClassInfo(JVMClassFileContainer.java:33)
[junit] 	at gov.nasa.jpf.vm.ClassLoaderInfo.getResolvedClassInfo(ClassLoaderInfo.java:353)
[junit] 	at gov.nasa.jpf.vm.SystemClassLoaderInfo.getResolvedClassInfo(SystemClassLoaderInfo.java:147)
[junit] 	at gov.nasa.jpf.vm.VM.getStartupSystemClassInfos(VM.java:445)
[junit] 	at gov.nasa.jpf.vm.VM.initializeMainThread(VM.java:564)
[junit] 	at gov.nasa.jpf.vm.SingleProcessVM.initialize(SingleProcessVM.java:130)
[junit] 	at gov.nasa.jpf.JPF.run(JPF.java:611)
[junit] 	at gov.nasa.jpf.util.test.TestJPF.createAndRunJPF(TestJPF.java:675)
[junit] 	at gov.nasa.jpf.util.test.TestJPF.noPropertyViolation(TestJPF.java:806)
[junit] 	at gov.nasa.jpf.util.test.TestJPF.verifyNoPropertyViolation(TestJPF.java:830)
[junit] 	at TypeNameTest.testArrayCloning(TypeNameTest.java:58)

The ClassFile parser seems to find just single bootstrap method argument, whereas in JVMClassInfo$Initializer.setBootstrapMethod it expects an element with index 1 in the bmArgs array.

/**
* BootstrapMethods_attribute {
* u2 attribute_name_index;
* u4 attribute_length;
* u2 num_bootstrap_methods;
* { u2 bootstrap_method_ref; -> MethodHandle
* u2 num_bootstrap_arguments;
* u2 bootstrap_arguments[num_bootstrap_arguments];
* } bootstrap_methods[num_bootstrap_methods];
* }
*
* pos is at num_bootstrap_methods
*/
public void parseBootstrapMethodAttr (ClassFileReader reader, Object tag){
int nBootstrapMethods = readU2();
setBootstrapMethodCount(reader, tag, nBootstrapMethods);
for (int i=0; i<nBootstrapMethods; i++){
int cpMhIdx = readU2();
int nArgs = readU2();
int[] bmArgs = new int[nArgs];
for (int j=0; j<nArgs; j++){
bmArgs[j] = readU2();
}
// kind of this method handle
int refKind = mhRefTypeAt(cpMhIdx);
// CONSTANT_Methodref_info structure
int mrefIdx = mhMethodRefIndexAt(cpMhIdx);
String clsName = methodClassNameAt(mrefIdx);
String mthName = methodNameAt(mrefIdx);
String descriptor = methodDescriptorAt(mrefIdx);
setBootstrapMethod(reader, tag, i, refKind, clsName, mthName, descriptor, bmArgs);

public void setBootstrapMethod (ClassFile cf, Object tag, int idx, int refKind, String cls, String mth, String descriptor, int[] cpArgs) {
int lambdaRefKind = cf.mhRefTypeAt(cpArgs[1]);

This seems to happen when trying to create ClassInfo for startupSystemClasses. So for instance sysCl.getResolvedClassInfo("java.lang.Class") would throw java.lang.ArrayIndexOutOfBoundsException' exception.

sysCl.getResolvedClassInfo("java.lang.Object") however resolves fine.

References

Saved diff of Class.class for Java 8 and 10:
https://www.diffchecker.com/0A0yIEXK

Travis log:
https://travis-ci.org/javapathfinder/jpf-core/builds/381994510#L3057-L3083

@cyrille-artho
Copy link
Member

It seems that support for this attribute in jpf-core is specific to lambda expressions. The current code does not even check the number of arguments and whether a given bootstrap method is a lamba expression.
As a fix, please copy the entire array (which may be longer or shorter than two elements), and if you can find out how to check whether the bootstrap method is a lambda expression, check this in the method that returns element 1.
We don't need more accessor methods for the general case, as this functionality seems currently unused. Therefore, I'd like to focus on making this functionality safe and robust for the current special case.

@cyrille-artho
Copy link
Member

This affects method public void setBootstrapMethod (ClassFile cf, Object tag, int idx, int refKind, String cls, String mth, String descriptor, int[] cpArgs) in JVMClassInfo.java.

cpArgs is bmArgs in ClassFile.java, which calls this function. The current code handles just a fixed number of arguments, and uses them in a specific way, to know how to use the lambda expression.

To make the code robust against crashes, the code should use the existing functionality if the length of cpArgs == 3, and otherwise just store that array but not evaluate it further.

@cyrille-artho
Copy link
Member

It seems that to resolve this properly, we also need to look at ClassInfo.java:
Looking at this SO post again:

https://stackoverflow.com/questions/50831654/what-is-a-bootstrap-method-argument-java-bytecode/50836081#50836081

The first case is the one that's handled correctly by the current specific code in JPF:

#883 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory

This deals with lamdba expressions, which have a very specific structure. Perhaps arg 0 is always java/lang/Object, which is why it was ignored.

I suggest to check the u2 bootstrap_method_ref entry in the bytecode.

This is passed as "refKind" to setBootstrapMethod, and currently unchecked. If it matches the type above, we can execute the current code.

Otherwise, we should store the cpArgs information and NOT evaluate the specific arguments. We may still have to evaluate these arguments in a different way, e.g.:

#284 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#285 \u0001\u0001

This creates a method that appends a particular string. If we do not cover this case (and only the lambda meta factory case), I hope we get rid of ArrayBounds problems, but we may get an incorrect output in some cases; we can fix this in a separate step.

@cyrille-artho
Copy link
Member

I understand this better now: Lambda expressions get compiled into specific cases of bootstrap methods. Bootstrap methods are templates of methods, which are generated at run time, when the expression is encountered for the first time. The code in setLambdaDirectCallCode (JVMClassInfo) parses the necessary type descriptors and creates a new method that loads the arguments and calls the actual method that is referred to in the constant pool.

As I wrote in the new comment on the issue tracker, the first step would be to check whether we deal with the specific case that was (so far) the only case in Java 8. After that, we can try to generalize the code.

I hope we can see from the examples why arg0 was not used before, and how to update the code to find the right type descriptors for a different number of arguments.

@cyrille-artho
Copy link
Member

cyrille-artho commented Jun 13, 2018

It seems that input parameters start deliberately at 1; see the first loop (from 0) and the second one (from 1) in JVMClassInfo.setLambdaDirectCallCode:

    // expression and captured by the lexical scope. These variables  
    // are stored by the fields of the synthetic function object class
    int n = callerCi.getNumberOfInstanceFields();
    for(int i=0; i<n; i++) {
      cb.aload(0);
      FieldInfo fi = callerCi.getInstanceField(i);
      cb.getfield(fi.getName(), callerCi.getName(), Types.getTypeSignature(fi.getSignature(), false));
    }
    // adding bytecode instructions to load input parameters of the lambda expression
    n = miDirectCall.getArgumentsSize();
    for(int i=1; i<n; i++) {
      cb.aload(i);
    }```

@gayanW
Copy link
Collaborator Author

gayanW commented Jun 19, 2018

The value of the refKind parameter is always the same (6) for both working and failing scenarios.

As stated in below, BootstrapMethodInfo including setLambdaDirectCallCode, and setBootstrapMethod are written to handle only the special case where invokedynamic is used to compile lambda expressions.

* For now, this is only used to capture boostrap methods for lambda expression,
* which link the method representing the lambda body to a single abstract method
* (SAM) declared in a functional interface. References to bootstrap methods are
* provided by the invokedynamic bytecode instruction.
*/
public class BootstrapMethodInfo {

As stated in the SO post

Bootstrap methods are used to resolve invokedynamic instruction.
invokedynamic is a general purpose mechanism, not only for lambdas


We'll also have different descriptors for the bootstrap methods LambdaMetafactory.metafactory and LambdaMetafactory.altMetafactory.

clsName = "java/lang/invoke/LambdaMetafactory"
mthName = "metafactory"
descriptor = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"

clsName = "java/lang/invoke/LambdaMetafactory"
mthName = "altMetafactory"
descriptor = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"


So why not just check the value of clsName parameter, and only proceeds if it is equal to 'java/lang/invoke/LambdaMetafactory'? As it will make sure that only the bootstrap methods with lambda behavior is handled.

Working examples:

tag = {JVMClassInfo@1311} "ClassInfo[name=java.lang.CharSequence]"
nBootstrapMethods = 2

i = 0
cpMhIdx = 38
nArgs = 3
bmArgs = {int[3]@1312} 
refKind = 6
mrefIdx = 57
clsName = "java/lang/invoke/LambdaMetafactory"
mthName = "metafactory"
descriptor = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"

i = 1
cpMhIdx = 38
nArgs = 3
bmArgs = {int[3]@1321} 
refKind = 6
mrefIdx = 57
clsName = "java/lang/invoke/LambdaMetafactory"
mthName = "metafactory"
descriptor = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"

tag = {JVMClassInfo@1409} "ClassInfo[name=java.util.Map$Entry]"
nBootstrapMethods = 4

i = 0
cpMhIdx = 78
nArgs = 5
bmArgs = {int[5]@1410}
refKind = 6
mrefIdx = 119
clsName = "java/lang/invoke/LambdaMetafactory"
mthName = "altMetafactory"
descriptor = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"

Failing cases:

tag = {JVMClassInfo@1714} "ClassInfo[name=java.lang.Class]"

idx = 0
refKind = 6
cls = "java/lang/invoke/StringConcatFactory"
mth = "makeConcatWithConstants"
descriptor = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"

@cyrille-artho
Copy link
Member

cyrille-artho commented Jun 21, 2018

Let's try adding a check if "clsName" and see if this makes some of the tests pass. After that, let's look at the remaining cases.

  1. Fix the (currently supported) behavior of Lambda expressions by adding an extra check.
    (There should be at least one test failure less after this step; otherwise we need another test that shows a difference.)

  2. Add the simple example (StringAppendTest) as a new test.
    Please add this case first and try to ensure it fails. You may have to "print" statement to an assertion that compares the result against the expected value.

  3. Try to generalize the code that generates bootstrap methods to handle such cases (maybe we can solve this by calling MethodHandle.invoke).

Documentation:

https://docs.oracle.com/javase/10/docs/api/java/lang/invoke/package-summary.html

https://docs.oracle.com/javase/10/docs/api/java/lang/invoke/MethodHandle.html#invokeWithArguments%28java.lang.Object...%29

@cyrille-artho
Copy link
Member

public class StringAppendTest {
    public static void main(String[] args) {
	String str = new String("Hello, ");
	String out = str + "World!";
	assert(out.equals("Hello, World!"));
    }
}

@gayanW
Copy link
Collaborator Author

gayanW commented Jun 22, 2018

I added a clasName check in the setBootstrapMethod method like the following:

  if (!cls.equals("java/lang/invoke/LambdaMetafactory"))
     return;

After implementing the check, ArrayIndexOutOfBoundsException has disappeared . There's also a significant improvement in the test results:

Before:
Number of Tests Executed: 759
Number of Tests Failed: 564
Number of Test Errors: 1
Number of Tests Skipped: 0

After:
Number of Tests Executed: 760
Number of Tests Failed: 164
Number of Test Errors: 0
Number of Tests Skipped: 0


Before implementing clsName check:

[junit] Running gov.nasa.jpf.test.java.lang.StringTest
[junit] Tests run: 13, Failures: 13, Errors: 0, Skipped: 0, Time elapsed: 0.644 sec

After implementing clsName check:

[junit] Running gov.nasa.jpf.test.java.lang.StringTest
[junit] Tests run: 14, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.566 sec

In the After case, I added the suggested StringAppendTest in to StringTest.java. Surprisingly that test also do pass. I'm currently not sure why.


I also test the same changes in the master branch with Java 8

Master branch with Java 8

In Java 8 all the test cases pass, which somewhat verifies that the existing functionalities are not affected by the extra clsName check.

Travis log: https://travis-ci.org/gayanW/jpf-core/builds/395538672

@gayanW
Copy link
Collaborator Author

gayanW commented Jun 23, 2018

It seems to me that verifyNoPropertyViolation() in the tests is what initiates JPF which cause methods to run through JPF. If not the tests are invoked directly.

Test 1

This test pass with no errors printed in the console.

@Test
public void testConcat() {
    String str = new String("Hello, ");
    String out = str + "World!";
    assert out.equals("Hello, World!");
}

Test 2

@Test
public void testConcat() {
    if (verifyNoPropertyViolation()) {
    String str = new String("Hello, ");
    String out = str + "World!";
        assert out.equals("Hello, World!");
    }
}

The test above also passes, but print out the following stacktrace.

[junit] Running gov.nasa.jpf.test.java.lang.StringTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 sec

[junit] Running gov.nasa.jpf.test.java.lang.StringTest
[junit]   running jpf with args:
[junit] gov.nasa.jpf.vm.ClassInfoException: class not found: java.io.Serializable
[junit]     at gov.nasa.jpf.vm.ClassLoaderInfo.getResolvedClassInfo(ClassLoaderInfo.java:363)
[junit]     at gov.nasa.jpf.vm.SystemClassLoaderInfo.getResolvedClassInfo(SystemClassLoaderInfo.java:147)
[junit]     at gov.nasa.jpf.vm.SystemClassLoaderInfo.loadClass(SystemClassLoaderInfo.java:182)
[junit]     at gov.nasa.jpf.vm.ClassInfo.resolveReferencedClass(ClassInfo.java:2414)
[junit]     at gov.nasa.jpf.vm.ClassInfo.loadInterfaces(ClassInfo.java:2366)
[junit]     at gov.nasa.jpf.vm.ClassInfo.resolveClass(ClassInfo.java:2383)
[junit]     at gov.nasa.jpf.vm.ClassInfo.resolveAndLink(ClassInfo.java:548)
[junit]     at gov.nasa.jpf.jvm.JVMClassInfo.<init>(JVMClassInfo.java:624)
[junit]     at gov.nasa.jpf.jvm.JVMClassFileContainer$JVMClassFileMatch.createClassInfo(JVMClassFileContainer.java:58)
[junit]     at gov.nasa.jpf.jvm.JVMClassFileContainer$JVMClassFileMatch.createClassInfo(JVMClassFileContainer.java:33)
[junit]     at gov.nasa.jpf.vm.ClassLoaderInfo.getResolvedClassInfo(ClassLoaderInfo.java:353)
[junit]     at gov.nasa.jpf.vm.SystemClassLoaderInfo.getResolvedClassInfo(SystemClassLoaderInfo.java:147)
[junit]     at gov.nasa.jpf.vm.VM.getStartupSystemClassInfos(VM.java:445)
[junit]     at gov.nasa.jpf.vm.VM.initializeMainThread(VM.java:564)
[junit]     at gov.nasa.jpf.vm.SingleProcessVM.initialize(SingleProcessVM.java:130)
[junit]     at gov.nasa.jpf.JPF.run(JPF.java:611)
[junit]     at gov.nasa.jpf.util.test.TestJPF.createAndRunJPF(TestJPF.java:675)
[junit]     at gov.nasa.jpf.util.test.TestJPF.noPropertyViolation(TestJPF.java:806)
[junit]     at gov.nasa.jpf.util.test.TestJPF.verifyNoPropertyViolation(TestJPF.java:830)
[junit]     at gov.nasa.jpf.test.java.lang.StringTest.testConcat(StringTest.java:307)

It looks like that the test is still executed.without resolving the ClassInfos for the model classes as it fails when trying to resolve the StartupSystemClassInfos.

May be we will not be able to assert:

Add the simple example (StringAppendTest) as a new test.
Please add this case first and try to ensure it fails. You may have to "print" statement to an assertion that compares the result against the expected value.

.. before we could fix the system class loading issue.

Let me know if you want me to proceed with just the step 1?

@cyrille-artho
Copy link
Member

cyrille-artho commented Jun 23, 2018 via email

@gayanW
Copy link
Collaborator Author

gayanW commented Jun 23, 2018

Test 2 actually uses JPF. It is good that it fails, because it is a very small test that makes it easier to debug what exactly needs to be supported.

Test 2 also passes. But with the above stacktrace. What I meant was that we won't be able to reproduce the case 2, without fixing the class loading issue first. As shown in the stacktrace, Test 2 fails to resolve any ClassInfos, yet it continues with the assertion assert out.equals("Hello, World!"), hence passing the test.

@cyrille-artho
Copy link
Member

cyrille-artho commented Jun 23, 2018 via email

@gayanW
Copy link
Collaborator Author

gayanW commented Jun 24, 2018

ClassInfoException is related to the sun.boot.class.path issue and is not directly related to this one. It will be good to create a new issue for it. Once that is being fixed, StringAppend test inhere should also fail.

I'll create a new issue for it with detailed information, so we could come up with a solution. I expects it have more implementation changes in addition to be able to just retrive the boot class path. (Like changes to generated class URIs)

@cyrille-artho
Copy link
Member

cyrille-artho commented Jun 25, 2018 via email

@gayanW
Copy link
Collaborator Author

gayanW commented Jul 19, 2018

It is necessary to construct and handle BootstrapMethodInfo for the special case (StringConcatFactory#makeConcatWithConstants) for the tests with string concatenation to pass.

We can construct BootstrapMethodInfo using a constructor similar to BootstrapMethodInfo(JVMClassInfo.this, cpArgs) without evaluating the cpArgs further as discussed before, but it'll still fail in JVMClassInfo#setLambdaDirectCallCode as setLambdaDirectCallCode method expects a BootstrapMethodInfo with a lambdaBody and a samDescriptor.

[junit] java.lang.NullPointerException
[junit]     at gov.nasa.jpf.jvm.JVMClassInfo.setLambdaDirectCallCode(JVMClassInfo.java:839)
[junit]     at gov.nasa.jpf.jvm.JVMClassInfo.<init>(JVMClassInfo.java:669)
[junit]     at gov.nasa.jpf.jvm.JVMClassInfo.createFuncObjClassInfo(JVMClassInfo.java:650)
[junit]     at gov.nasa.jpf.vm.ClassLoaderInfo.getResolvedFuncObjType(ClassLoaderInfo.java:478)
[junit]     at gov.nasa.jpf.vm.FunctionObjectFactory.getFunctionObject(FunctionObjectFactory.java:30)
[junit]     at gov.nasa.jpf.jvm.bytecode.INVOKEDYNAMIC.execute(INVOKEDYNAMIC.java:121)
[junit]     at gov.nasa.jpf.vm.ThreadInfo.executeInstruction(ThreadInfo.java:1908)
[junit]     at gov.nasa.jpf.vm.ThreadInfo.executeTransition(ThreadInfo.java:1859)
[junit]     at gov.nasa.jpf.vm.SystemState.executeNextTransition(SystemState.java:765)
[junit]     at gov.nasa.jpf.vm.VM.forward(VM.java:1722)
[junit]     at gov.nasa.jpf.search.Search.forward(Search.java:579)
[junit]     at gov.nasa.jpf.search.DFSearch.search(DFSearch.java:79)
[junit]     at gov.nasa.jpf.JPF.run(JPF.java:614)
[junit]     at gov.nasa.jpf.util.test.TestJPF.createAndRunJPF(TestJPF.java:675)
[junit]     at gov.nasa.jpf.util.test.TestJPF.noPropertyViolation(TestJPF.java:806)
[junit]     at gov.nasa.jpf.util.test.TestMultiProcessJPF.mpVerifyNoPropertyViolation(TestMultiProcessJPF.java:72)
[junit]     at gov.nasa.jpf.vm.multiProcess.StringTest.testInterns(StringTest.java:36)

I'm still not sure how to evaluate the lambdaBody, and samDescriptor for the special case (with single bmArg).

Failing case

  1: #210 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #211 some text here

Working case

  0: #83 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #84 (Ljava/lang/Object;)Ljava/lang/Object;
      #85 REF_invokeInterface java/lang/annotation/Annotation.annotationType:()Ljava/lang/Class;
      #86 (Ljava/lang/annotation/Annotation;)Ljava/lang/Class;

FYI: evaluated values for an instance of the working case:

i = 0   cpMhIdx: 83     nArgs 3 bmArgs = 84 85 86
refKind = 6             #6 = Methodref
clsName                 java/lang/invoke/LambdaMetafactory
mthName                 metafactory
descriptor              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"

lambdaRefKind           9
clsName                 java.lang.annotation.Annotation
eclosingLambdaCls       ClassInfo[name=java.lang.annotation.Annotation]
mthName                 annotationType
signature               ()Ljava/lang/Class;

*lambdaBody             MethodInfo[java.lang.annotation.Annotation.annotationType()Ljava/lang/Class;]

*samDescriptor          (Ljava/lang/annotation/Annotation;)Ljava/lang/Class;

* - used in gov.nasa.jpf.jvm.JVMClassInfo#setLambdaDirectCallCode

@cyrille-artho
Copy link
Member

Resolved, at least for parsing the bytecode in several cases we tested, as part of PR#210.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants