2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.test.mc.basic;
20 import gov.nasa.jpf.ListenerAdapter;
21 import gov.nasa.jpf.jvm.bytecode.GETFIELD;
22 import gov.nasa.jpf.jvm.bytecode.IRETURN;
23 import gov.nasa.jpf.jvm.bytecode.JVMInvokeInstruction;
24 import gov.nasa.jpf.util.test.TestJPF;
25 import gov.nasa.jpf.vm.ClassInfo;
26 import gov.nasa.jpf.vm.Instruction;
27 import gov.nasa.jpf.vm.VM;
28 import gov.nasa.jpf.vm.MethodInfo;
29 import gov.nasa.jpf.vm.StackFrame;
30 import gov.nasa.jpf.vm.ThreadInfo;
31 import gov.nasa.jpf.vm.choice.IntChoiceFromList;
33 import org.junit.Test;
35 public class SkipInstructionTest extends TestJPF {
37 //--- replacing field access
41 public static class GetFieldListener extends ListenerAdapter {
44 public void executeInstruction(VM vm, ThreadInfo ti, Instruction insnToExecute) {
45 Instruction pc = ti.getPC();
47 if (pc instanceof GETFIELD) {
48 GETFIELD gf = (GETFIELD) pc;
49 if (gf.getVariableId().equals(SkipInstructionTest.class.getName() + ".answer")) {
50 System.out.println("now intercepting: " + pc);
52 // simulate the operand stack behavior of the skipped insn
53 StackFrame frame = ti.getModifiableTopFrame();
58 ti.skipInstruction(pc.getNext());
65 public void testGETFIELD () {
67 if (verifyNoPropertyViolation("+listener=gov.nasa.jpf.test.mc.basic.SkipInstructionTest$GetFieldListener")){
68 int i = answer; // to be intercepted by listener
70 System.out.println(i);
71 assert (i == 42) : "get_field not intercepted: " + i;
75 //--- replacing method execution
76 // this is not using skipInstruction but is setting the next one to enter, which
77 // means it can skip over a whole bunch of things. The use that comes to mind is to
78 // skip over method bodies, but still preserve the invoke processing so that we
79 // preserve the locking/sync (which we otherwise would have to do explicitly from
80 // a pre-exec listener
82 // the intercepted method
83 int foo (int a, int b) {
92 // the listener that does the interception
93 public static class InvokeListener extends ListenerAdapter {
94 MethodInfo interceptedMethod;
97 public void classLoaded (VM vm, ClassInfo ci) {
98 if (ci.getName().equals("gov.nasa.jpf.test.mc.basic.SkipInstructionTest")) {
99 interceptedMethod = ci.getMethod("foo(II)I", false);
100 assert interceptedMethod != null : "foo(II)I not found";
101 System.out.println("method to intercept: " + interceptedMethod);
106 public void instructionExecuted (VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn) {
107 MethodInfo mi = ti.getTopFrameMethodInfo();
108 if (mi == interceptedMethod) {
109 System.out.println("in " + mi);
111 if (!ti.isFirstStepInsn()) {
112 System.out.println("in top half: " + executedInsn);
113 if (executedInsn instanceof JVMInvokeInstruction) { // we just entered the interceptedMethod
114 IntChoiceFromList cg = new IntChoiceFromList("Test", 42, 43);
115 if (vm.setNextChoiceGenerator(cg)) {
116 return; // we are done here, next insn in this method will skip to return
120 // note - this is the first insn WITHIN the interceptedMethod
121 System.out.println("in bottom half: " + executedInsn);
122 IntChoiceFromList cg = vm.getCurrentChoiceGenerator("Test", IntChoiceFromList.class);
124 int choice = cg.getNextChoice();
125 Instruction lastInsn = mi.getLastInsn();
126 assert lastInsn instanceof IRETURN : "last instruction not an IRETURN ";
127 StackFrame frame = ti.getModifiableTopFrame(); // we are modifying it
128 System.out.println("listener is skipping method body of " + mi + " returning " + choice);
130 ti.setNextPC(lastInsn);
132 System.out.println("unexpected CG: " + cg);
140 public void testSkipMethodBody() {
141 if (verifyNoPropertyViolation("+listener=gov.nasa.jpf.test.mc.basic.SkipInstructionTest$InvokeListener")){
142 int ret = foo( 3, 4);
143 System.out.println(ret);
144 //assertTrue( ret == 42);