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.
19 package gov.nasa.jpf.jvm.bytecode;
21 import gov.nasa.jpf.vm.Instruction;
22 import gov.nasa.jpf.vm.NativeStackFrame;
23 import gov.nasa.jpf.vm.StackFrame;
24 import gov.nasa.jpf.vm.ThreadInfo;
25 import gov.nasa.jpf.vm.Types;
28 * synthetic return instruction for native method invocations, so that
29 * we don't have to do special provisions to copy the caller args in case
30 * a post exec listener wants them.
32 public class NATIVERETURN extends JVMReturnInstruction {
38 // this is more simple than a normal JVMReturnInstruction because NativeMethodInfos
39 // are not synchronized, and NativeStackFrames are never the first frame in a thread
41 public Instruction execute (ThreadInfo ti) {
42 if (!ti.isFirstStepInsn()) {
43 ti.leave(); // takes care of unlocking before potentially creating a CG
44 // NativeMethodInfo is never synchronized, so no thread CG here
47 StackFrame frame = ti.getModifiableTopFrame();
48 getAndSaveReturnValue(frame);
50 // NativeStackFrame can never can be the first stack frame, so no thread CG
52 frame = ti.popAndGetModifiableTopFrame();
54 // remove args, push return value and continue with next insn
55 frame.removeArguments(mi);
56 pushReturnValue(frame);
58 if (retAttr != null) {
59 setReturnAttr(ti, retAttr);
63 // this is in the clinit RETURN insn for non-MJIs so we have to duplicate here
64 // Duplication could be avoided in DIRECTCALLRETURN, but there is no reliable
65 // way to check if the direct call did return from a clinit since the corresponding
66 // synthetic method could do anything
67 mi.getClassInfo().setInitialized();
70 return frame.getPC().getNext();
74 public void cleanupTransients(){
81 public boolean isExtendedInstruction() {
85 public static final int OPCODE = 260;
88 public int getByteCode () {
93 public void accept(JVMInstructionVisitor insVisitor) {
94 insVisitor.visit(this);
98 protected void getAndSaveReturnValue (StackFrame frame) {
99 // it's got to be a NativeStackFrame since this insn is created by JPF
100 NativeStackFrame nativeFrame = (NativeStackFrame)frame;
102 returnFrame = nativeFrame;
104 ret = nativeFrame.getReturnValue();
105 retAttr = nativeFrame.getReturnAttr();
106 retType = nativeFrame.getMethodInfo().getReturnTypeCode();
110 public int getReturnTypeSize() {
112 case Types.T_BOOLEAN:
129 // this is only called internally right before we return
131 protected Object getReturnedOperandAttr (StackFrame frame) {
135 // <2do> this should use the getResult..() methods of NativeStackFrame
138 protected void pushReturnValue (StackFrame fr) {
143 // in case of a return type mismatch, we get a ClassCastException, which
144 // is handled in executeMethod() and reported as a InvocationTargetException
145 // (not completely accurate, but we rather go with safety)
148 case Types.T_BOOLEAN:
149 ival = Types.booleanToInt(((Boolean) ret).booleanValue());
154 fr.push(((Byte) ret).byteValue());
158 fr.push(((Character) ret).charValue());
162 fr.push(((Short) ret).shortValue());
166 fr.push(((Integer) ret).intValue());
170 fr.pushLong(((Long)ret).longValue());
175 ival = Types.floatToInt(((Float) ret).floatValue());
180 lval = Types.doubleToLong(((Double) ret).doubleValue());
186 // everything else is supposed to be a reference
187 fr.push(((Integer) ret).intValue(), true);
190 if (retAttr != null) {
192 fr.setOperandAttr(retAttr);
194 fr.setLongOperandAttr(retAttr);
201 public Object getReturnAttr (ThreadInfo ti) {
202 if (isCompleted(ti)){
205 NativeStackFrame nativeFrame = (NativeStackFrame) ti.getTopFrame();
206 return nativeFrame.getReturnAttr();
212 public Object getReturnValue(ThreadInfo ti) {
213 if (isCompleted(ti)){
216 NativeStackFrame nativeFrame = (NativeStackFrame) ti.getTopFrame();
217 return nativeFrame.getReturnValue();
222 public String toString(){
223 StringBuilder sb = new StringBuilder();
224 sb.append("nativereturn ");
225 sb.append(mi.getFullName());
227 return sb.toString();