// Copyright 2011 Google Inc. All Rights Reserved.

#ifndef ART_SRC_CALLING_CONVENTION_H_
#define ART_SRC_CALLING_CONVENTION_H_

#include "managed_register.h"
#include "object.h"
#include "thread.h"

namespace art {

// Top-level abstraction for different calling conventions
class CallingConvention {
 public:
  CallingConvention* GetCallingConvention(Method* method);

  bool IsReturnAReference() const { return method_->IsReturnAReference(); }

  size_t SizeOfReturnValue() const { return method_->ReturnSize(); }

  // Register that holds the incoming method argument
  ManagedRegister MethodRegister();
  // Register that holds result of this method
  ManagedRegister ReturnRegister();
  // Register reserved for scratch usage during procedure calls
  ManagedRegister InterproceduralScratchRegister();

  // Offset of Method within the frame
  FrameOffset MethodStackOffset();

  // Iterator interface

  // Place iterator at start of arguments. The displacement is applied to
  // frame offset methods to account for frames which may be on the stack
  // below the one being iterated over.
  void ResetIterator(FrameOffset displacement) {
    displacement_ = displacement;
    itr_slots_ = 0;
    itr_args_ = 0;
    itr_longs_and_doubles_ = 0;
  }

 protected:
  explicit CallingConvention(Method* method) : displacement_(0),
                                               method_(method) {}
  const Method* GetMethod() const { return method_; }

  // The slot number for current calling_convention argument.
  // Note that each slot is 32-bit. When the current argument is bigger
  // than 32 bits, return the first slot number for this argument.
  unsigned int itr_slots_;
  // The argument number along argument list for current argument
  unsigned int itr_args_;
  // Number of longs and doubles seen along argument list
  unsigned int itr_longs_and_doubles_;
  // Space for frames below this on the stack
  FrameOffset displacement_;

 private:
  const Method* method_;
};

// Abstraction for managed code's calling conventions
class ManagedRuntimeCallingConvention : public CallingConvention {
 public:
  explicit ManagedRuntimeCallingConvention(Method* method) :
                                          CallingConvention(method) {}

  size_t FrameSize();

  // Iterator interface
  bool HasNext();
  void Next();
  bool IsCurrentParamAReference();
  bool IsCurrentParamInRegister();
  bool IsCurrentParamOnStack();
  bool IsCurrentUserArg();
  size_t CurrentParamSize();
  ManagedRegister CurrentParamRegister();
  FrameOffset CurrentParamStackOffset();

  DISALLOW_COPY_AND_ASSIGN(ManagedRuntimeCallingConvention);
};

// Abstraction for JNI calling conventions
// | incoming stack args    | <-- Prior SP
// | { Spilled registers    |
// |   & return address }   |
// | { Return value spill } |     (live on return slow paths)
// | { Stack Handle Block   |
// |   ...                  |
// |   num. refs./link }    |     (here to prior SP is frame size)
// | Method*                | <-- Anchor SP written to thread
// | { Outgoing stack args  |
// |   ... }                | <-- SP at point of call
// | Native frame           |
class JniCallingConvention : public CallingConvention {
 public:
  explicit JniCallingConvention(Method* native_method) :
                      CallingConvention(native_method) {}

  // Size of frame excluding space for outgoing args (its assumed Method* is
  // always at the bottom of a frame, but this doesn't work for outgoing
  // native args). Includes alignment.
  size_t FrameSize();
  // Size of outgoing arguments, including alignment
  size_t OutArgSize();
  // Number of handles in stack handle block
  size_t HandleCount();
  // Location where the return value of a call can be squirreled if another
  // call is made following the native call
  FrameOffset ReturnValueSaveLocation();

  // Returns true if the register will be clobbered by an outgoing
  // argument value.
  bool IsOutArgRegister(ManagedRegister reg);

  // Iterator interface
  bool HasNext();
  void Next();
  bool IsCurrentParamAReference();
  bool IsCurrentParamInRegister();
  bool IsCurrentParamOnStack();
  size_t CurrentParamSize();
  ManagedRegister CurrentParamRegister();
  FrameOffset CurrentParamStackOffset();

  // Iterator interface extension for JNI
  FrameOffset CurrentParamHandleOffset();

  // Position of stack handle block and interior fields
  FrameOffset ShbOffset() {
    return FrameOffset(displacement_.Int32Value() +
                       kPointerSize);  // above Method*
  }
  FrameOffset ShbNumRefsOffset() {
    return FrameOffset(ShbOffset().Int32Value() +
                       StackHandleBlock::NumberOfReferencesOffset());
  }
  FrameOffset ShbLinkOffset() {
    return FrameOffset(ShbOffset().Int32Value() +
                       StackHandleBlock::LinkOffset());
  }

 private:
  // Named iterator positions
  enum IteratorPos {
    kJniEnv = 0,
    kObjectOrClass = 1
  };

  // Number of stack slots for outgoing arguments, above which handles are
  // located
  size_t NumberOfOutgoingStackArgs();

  static size_t NumberOfExtraArgumentsForJni(const Method* method);
  DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
};

}  // namespace art

#endif  // ART_SRC_CALLING_CONVENTION_H_
