Skip to content

Commit

Permalink
Add new constructor BootstrapMethodInfo(enclosingClass, cpArgs)
Browse files Browse the repository at this point in the history
JVMClassInfo.Initializer#setBootstrapMethod assumes to have a bootstrap
method with a structure similar to the following (with 3 bootstrap
method arguments)

BootstrapMethods:
  0: javapathfinder#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:
      javapathfinder#84 (Ljava/lang/Object;)Ljava/lang/Object;
      javapathfinder#85 REF_invokeInterface java/lang/annotation/Annotation.annotationType:()Ljava/lang/Class;
      javapathfinder#86 (Ljava/lang/annotation/Annotation;)Ljava/lang/Class;

But if JPF encounters an bootstrap method with arbitary numer of
arguments such as the StringConcatFactory.makeConcatWithConstants which
have only one bootstrap method argument it results in an
ArrayIndexOutOfBoundsException exception:

[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)

This prevents the above exception from being thrown, by adding a new
constructor BootstrapMethodInfo#BootstrapMethodInfo(enclosingClass,
cpArgs) for handling bootstrap methods with arbitrary number of
bootstrap method arguments, without evaluating cpArgs in
JVMClassInfo.Initializer#setBootstrapMethod.
  • Loading branch information
gayanW committed Jul 19, 2018
1 parent 7e2c8c0 commit 1208367
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
8 changes: 6 additions & 2 deletions src/main/gov/nasa/jpf/jvm/JVMClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,12 @@ public void setBootstrapMethodCount (ClassFile cf, Object tag, int count) {
}

@Override
public void setBootstrapMethod (ClassFile cf, Object tag, int idx, int refKind, String cls, String mth, String descriptor, int[] cpArgs) {

public void setBootstrapMethod (ClassFile cf, Object tag, int idx, int refKind, String cls, String mth, String descriptor, int[] cpArgs) {
if (cls.equals("java/lang/invoke/StringConcatFactory")) {
bootstrapMethods[idx] = new BootstrapMethodInfo(JVMClassInfo.this, cpArgs);
return;
}

int lambdaRefKind = cf.mhRefTypeAt(cpArgs[1]);

int mrefIdx = cf.mhMethodRefIndexAt(cpArgs[1]);
Expand Down
11 changes: 10 additions & 1 deletion src/main/gov/nasa/jpf/vm/BootstrapMethodInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,16 @@ public BootstrapMethodInfo(int lambdaRefKind, ClassInfo enclosingClass, MethodIn
this.lambdaBody = lambdaBody;
this.samDescriptor = samDescriptor;
}


/**
* Constructor for constructing {@link BootstrapMethodInfo} for bootstrap methods
* with arbitrary number of bootstrap method arguments
*/
public BootstrapMethodInfo(ClassInfo enclosingClass, int[] cpArgs) {
this.enclosingClass = enclosingClass;
// TODO: find a way to parse lambdaBody, samDescriptor etc
}

@Override
public String toString() {
return "BootstrapMethodInfo[" + enclosingClass.getName() + "." + lambdaBody.getBaseName() +
Expand Down

0 comments on commit 1208367

Please sign in to comment.