return.c
1 /* 2 * Bean Java VM 3 * Copyright (C) 2005-2015 Christian Lins <christian@lins.me> 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <debug.h> 19 #include <vm.h> 20 21 extern VM* vm; 22 23 void check_end_of_exec(Thread* thread) { 24 if (thread->frameStack->size == 0) { 25 dbgmsg("Execution has ended!"); 26 vm->alive = false; 27 } 28 } 29 30 /* 31 * The current method must have return type void. If the current method 32 * is a synchronized method, the monitor acquired or reentered on invocation 33 * of the method is released or exited (respectively) as if by execution 34 * of a monitorexit instruction. If no exception is thrown, any values on 35 * the operand stack of the current frame are discarded. 36 * The interpreter then returns control to the invoker of the method, 37 * reinstating the frame of the invoker. 38 */ 39 void do_RETURN(Thread *thread) { 40 dbgmsg("RETURN"); 41 42 Stackframe* frame; 43 44 // Pop stackframe of current method 45 Stack_pop(thread->frameStack, (void**)&frame); 46 frame = Stackframe_dispose(frame); 47 48 // Release monitor if existing 49 /*if (isAccessFlag(invokeStackFrame->method->Method, ACC_SYNCHRONIZED) == true) { 50 do_MONITOREXIT(thread); 51 current_frame(thread)->instPtr--; 52 }*/ 53 54 check_end_of_exec(thread); 55 } 56 57 void do_ARETURN(Thread *thread) 58 { 59 dbgmsg("ARETURN"); 60 61 Stackframe* frame; 62 63 // Pop stackframe of current method 64 Stack_pop(thread->frameStack, (void**)&frame); 65 66 // Pop the object reference from the current operand stacks and 67 // push it onto the invokers operand stack 68 Object* objref; 69 Stack_pop(&(frame->operandStack), (void **) &objref); 70 71 Stackframe* invokerFrame = current_frame(thread); 72 Stack_push(&(invokerFrame->operandStack), objref); 73 74 frame = Stackframe_dispose(frame); 75 } 76 77 void do_DRETURN(Thread *thread) 78 { 79 check_end_of_exec(thread); 80 dbgmsg("DRETURN"); 81 dbgmsg("Not implemented"); 82 exit(-10); 83 } 84 85 void do_FRETURN(Thread *thread) 86 { 87 check_end_of_exec(thread); 88 dbgmsg("FRETURN"); 89 dbgmsg("Not implemented"); 90 exit(-10); 91 } 92 93 void do_LRETURN(Thread *thread) 94 { 95 check_end_of_exec(thread); 96 dbgmsg("LRETURN"); 97 dbgmsg("Not implemented"); 98 exit(-10); 99 } 100 101 void do_IRETURN(Thread *thread) 102 { 103 check_end_of_exec(thread); 104 dbgmsg("IRETURN"); 105 dbgmsg("Not implemented"); 106 exit(-10); 107 } 108 109 void do_RET(Thread *thread) 110 { 111 check_end_of_exec(thread); 112 dbgmsg("RET"); 113 dbgmsg("Not implemented"); 114 exit(-10); 115 }