Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / DIRECTCALLRETURN.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
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
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
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.
17  */
18
19 package gov.nasa.jpf.jvm.bytecode;
20
21 import gov.nasa.jpf.vm.Instruction;
22 import gov.nasa.jpf.vm.StackFrame;
23 import gov.nasa.jpf.vm.ThreadInfo;
24 import gov.nasa.jpf.vm.bytecode.ReturnInstruction;
25
26 /**
27  * this is used to return from a DirectCallStackFrame
28  *
29  * Note that it is NOT a ReturnInstruction, in case listeners monitor these
30  * and expect corresponding InvokeInstructions. Although this would seem intuitive, it
31  * would be pointless to derive because the ReturnInstruction.enter() does
32  * a lot of things we would have to cut off, i.e. it would require more effort
33  * to undo this (no sync, no return value, no pc advance on the returned-to
34  * stackframe etc.)
35  *
36  * However, having a dedicated direct call return instruction makes sense so
37  * that the ReturnInstruction of the called method does not have to handle
38  * direct calls specifically
39  */
40 public class DIRECTCALLRETURN extends ReturnInstruction implements JVMInstruction  {
41
42   @Override
43   public boolean isExtendedInstruction() {
44     return true;
45   }
46
47   public static final int OPCODE = 261;
48
49   @Override
50   public int getByteCode () {
51     return OPCODE;
52   }
53
54   @Override
55   public void accept(JVMInstructionVisitor insVisitor) {
56           insVisitor.visit(this);
57   }
58
59   @Override
60   public Instruction execute (ThreadInfo ti) {
61     if (ti.getStackDepth() == 1){ // thread exit point
62       // this can execute several times because of the different locks involved
63     
64       if (!ti.exit()){
65         return this; // repeat, we couldn't get the lock
66       } else {
67         return null;
68       }      
69       
70     } else {
71       // pop the current frame but do not advance the new top frame, and do
72       // not touch its operand stack
73     
74       StackFrame frame = ti.popDirectCallFrame();
75       return frame.getPC();
76     }
77   }
78 }