17
17
*/
18
18
package gov .nasa .jpf .jvm .bytecode ;
19
19
20
+ import gov .nasa .jpf .vm .ThreadInfo ;
21
+ import gov .nasa .jpf .vm .Instruction ;
22
+ import gov .nasa .jpf .vm .MethodInfo ;
23
+ import gov .nasa .jpf .vm .ClassInfo ;
24
+ import gov .nasa .jpf .vm .RecordComponentInfo ;
25
+ import gov .nasa .jpf .JPFException ;
20
26
21
27
22
28
/**
@@ -29,8 +35,14 @@ public INVOKEVIRTUAL () {}
29
35
protected INVOKEVIRTUAL (String clsDescriptor , String methodName , String signature ){
30
36
super (clsDescriptor , methodName , signature );
31
37
}
32
-
33
-
38
+ @ Override
39
+ public MethodInfo getInvokedMethod (ThreadInfo ti ) {
40
+ ClassInfo ci = ti .resolveReferencedClass (cname );
41
+ if (ci != null ) {
42
+ return ci .getMethod (mname , true );
43
+ }
44
+ return null ;
45
+ }
34
46
@ Override
35
47
public int getByteCode () {
36
48
return 0xB6 ;
@@ -46,4 +58,33 @@ public String toString() {
46
58
public void accept (JVMInstructionVisitor insVisitor ) {
47
59
insVisitor .visit (this );
48
60
}
61
+ @ Override
62
+ public Instruction execute (ThreadInfo ti ) {
63
+ MethodInfo mi = getInvokedMethod (ti );
64
+
65
+ if (mi == null ) {
66
+ throw new JPFException ("Method not found: " + cname + '.' + mname );
67
+ }
68
+
69
+ // Handle record accessors
70
+ if (mi .isRecordAccessor ()) {
71
+ Object target = ti .getTopFrame ().getThis ();
72
+ if (target instanceof Record ) {
73
+ try {
74
+ RecordComponentInfo [] components = ((ClassInfo ) mi .getClassInfo ()).getRecordComponents ();
75
+ for (RecordComponentInfo component : components ) {
76
+ if (mi .getName ().equals (component .getName ())) {
77
+ Object result = component .getAccessor ().invoke (target );
78
+ ti .getTopFrame ().setReturnValue (result );
79
+ return ti .getPC ().getNext ();
80
+ }
81
+ }
82
+ } catch (Exception e ) {
83
+ throw new JPFException ("Failed to invoke accessor for record: " + mi .getName ());
84
+ }
85
+ }
86
+ }
87
+
88
+ return super .execute (ti );
89
+ }
49
90
}
0 commit comments