/ src / exec / return.c
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  }