// Copyright 2011 Google Inc. All Rights Reserved.
// Author: irogers@google.com (Ian Rogers)

#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_position_ = 0;
    itr_longs_and_doubles_ = 0;
  }

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

  // position along argument list
  unsigned int itr_position_;
  // 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 IsCurrentParamPossiblyNull();
  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();

  DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
};

}  // namespace art

#endif  // ART_SRC_CALLING_CONVENTION_H_
