Scenario P5:f.set(obj,val); SEr(inUo,f)← VCALL(invo,f,mtd),MTDSTRING(mtd, "java.lang.reflect.Field:void set(java.lang.Object,java.lang.Object)"). FLDPOINTSTo(baseHeap,Ad,valHeap)+ SeT(invo,f),VARPOINTSTo(f,AdHeap).FLD-FLDHEAP(Ald,AdHeap): ACTUALARC(invo,1,obj),VARPOINTSTo(obj,baseHeap), ACTUALARC(invo,2,val).VARPOINTSTo(val,valHeap). Scenario P6:Method m clz.getHethod("string const",f...); GETMETHOD(invo,clz) VCALL(invo,clz,mtd),MTDSTRING(mtd, "java.lang.Class:java.lang.reflect.Method getMethod(java.lang.String,java.lang.Class()"). RESOLVEDMETHOD(invo,mtd) GETMETHOD(invo,clz),VARPOINTSTo(clz,clzHeap), TYPE-CLASSHEAP(type,clzHeap),ACTUALARC(invo,1,arg). VARPOINTSTo(arg,mtdName),PUBLICMTD(type,mtdName,mtd). VARPOINTSTo(m,mtdHeap)+ RESOLVEDMETHOD(invo,mtd):MTD-MTDHEAP(mtd,mtdHeap),ACTUALRETURN(invo,m). Scenario PT:Object to m.invoke(obj,1...); INVOKE(invo,m)←- VCALL(invo,m,mtd),MTDSICSTRINC(mtd,"java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object,java.lang.Object)"). REPCALLGRAPH(invo,virtualMtd),VARPOINTSTo(this,heap) INVOKE(invo,m).VARPOINTSTo(m,mtdHeap),MTD-MTDHEAP(mtd,mtdHeap). ACTUALARC(invo,1,obj),VARPOINTSTo(obj,heap):HEAPTYPE(heap,type). MTDDECL(,mtdName,mtdDescriptor,mtd),THIsVAR(virtualMtd,this), LooKUPMETHOD(type,mtdName,mtdDescriptor,virtualMtd). Scenario I2:Fieldl fsHclz.getDeclaredFields();f2=fs2/il;a=(A)f1.get(obj). The post-dominating type (A)is used to infer the target fields reflectively accessed at get()on the Field objects that are initially stored into fs1 and later pointed to by fl.Note that cle is known in this case. Scenario I3:Fieldll fs1=clz.getDeclaredFields();f2=fs2/il;f1.set(obj,val). The dynamic types of val are used to infer the target fields modified. Scenario 14:Method m1=clz.getMethod(?,params);a=m2.invoke(obj,args). The dynamic types of args will be used to infer the target methods called on the Method objects that are pointed to by m2 but initially created at a call to m1=clz.getMethod(),where clz is known. Figure 7 gives a few new relations used for handling these four scenar- ios.The first three are used to identify metaobjects with non-constant names (called placeholder objects).CLAssPH identifies all the invocation sites,e.g., Class.forName(?),where Class objects with unknown class names are cre- ated.MEMBERPH identifies the invocation sites,e.g.,calls to clz.getMethod(?, ...)(clz.getField(?)),where Method(Field)objects are created to represent unknown method(field)names'?'in a known class clz of type type.If clz is also unknown,a different relation (not used here)is called for.Furthermore,MEM- BERPHARRAY identifies which placeholder objects represent arrays.For example, a call to clz.getDeclaredFields()returns an array of Field objects.Scenario P5: f.set(obj, val); Set(invo, f ) ← Vcall(invo, f, mtd), MtdString(mtd, “java.lang.reflect.Field: void set(java.lang.Object, java.lang.Object)”). FldPointsTo(baseHeap, fld, valHeap) ← Set(invo, f ), VarPointsTo(f, fldHeap), Fld-FldHeap(fld, fldHeap), ActualArg(invo, 1, obj ), VarPointsTo(obj, baseHeap), ActualArg(invo, 2, val), VarPointsTo(val, valHeap). Scenario P6: Method m = clz.getMethod(“string const”, {...}); GetMethod(invo, clz ) ← Vcall(invo, clz, mtd), MtdString(mtd, “java.lang.Class: java.lang.reflect.Method getMethod(java.lang.String, java.lang.Class[])” ). ResolvedMethod(invo, mtd) ← GetMethod(invo, clz ), VarPointsTo(clz, clzHeap), Type-ClassHeap(type, clzHeap), ActualArg(invo, 1, arg), VarPointsTo(arg, mtdName), PublicMtd(type, mtdName, mtd). VarPointsTo(m, mtdHeap) ← ResolvedMethod(invo, mtd), Mtd-MtdHeap(mtd, mtdHeap), ActualReturn(invo, m). Scenario P7: Object to = m.invoke(obj, {...}); Invoke(invo, m) ← Vcall(invo, m, mtd), MtdSigString(mtd, “java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object, java.lang.Object[])”). RefCallGraph(invo, virtualMtd), VarPointsTo(this, heap) ← Invoke(invo, m), VarPointsTo(m, mtdHeap), Mtd-MtdHeap(mtd, mtdHeap), ActualArg(invo, 1, obj ), VarPointsTo(obj, heap), HeapType(heap, type), MtdDecl(_, mtdName, mtdDescriptor, mtd), ThisVar(virtualMtd, this), LookUpMethod(type, mtdName, mtdDescriptor, virtualMtd). Scenario I2: Field[] fs1=clz.getDeclaredFields(); f2= fs2[i]; a= (A)f1.get(obj). The post-dominating type (A) is used to infer the target fields reflectively accessed at get() on the Field objects that are initially stored into fs1 and later pointed to by f1. Note that clz is known in this case. Scenario I3: Field[] fs1= clz.getDeclaredFields(); f2 = fs2[i]; f1.set(obj, val). The dynamic types of val are used to infer the target fields modified. Scenario I4: Method m1 = clz.getMethod(?, params); a = m2.invoke(obj, args). The dynamic types of args will be used to infer the target methods called on the Method objects that are pointed to by m2 but initially created at a call to m1=clz.getMethod(), where clz is known. Figure 7 gives a few new relations used for handling these four scenarios. The first three are used to identify metaobjects with non-constant names (called placeholder objects). ClassPh identifies all the invocation sites, e.g., Class.forName(?), where Class objects with unknown class names are created. MemberPh identifies the invocation sites, e.g., calls to clz.getMethod(?, ...) (clz.getField(?)), where Method (Field) objects are created to represent unknown method (field) names ‘?’ in a known class clz of type type. If clz is also unknown, a different relation (not used here) is called for. Furthermore, MemberPhArray identifies which placeholder objects represent arrays. For example, a call to clz.getDeclaredFields() returns an array of Field objects