// Copyright 2011 Google Inc. All Rights Reserved.

#ifndef ART_SRC_CALLING_CONVENTION_H_
#define ART_SRC_CALLING_CONVENTION_H_

#include <vector>
#include "managed_register.h"
#include "object.h"
#include "stack_indirect_reference_table.h"
#include "thread.h"

namespace art {

// Top-level abstraction for different calling conventions
class CallingConvention {
 public:
  bool IsReturnAReference() const { return method_->IsReturnAReference(); }

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

  // Register that holds result of this method
  virtual ManagedRegister ReturnRegister() = 0;
  // Register reserved for scratch usage during procedure calls
  virtual ManagedRegister InterproceduralScratchRegister() = 0;

  // 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_refs_ = 0;
    itr_longs_and_doubles_ = 0;
  }

  virtual ~CallingConvention() {}

 protected:
  explicit CallingConvention(const Method* method)
      : displacement_(0), method_(const_cast<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 number of references iterated past
  unsigned int itr_refs_;
  // 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:
  Method* method_;
};

// Abstraction for managed code's calling conventions
// | { Incoming stack args } |
// | { Prior Method* }       | <-- Prior SP
// | { Return address }      |
// | { Callee saves }        |
// | { Spills ... }          |
// | { Outgoing stack args } |
// | { Method* }             | <-- SP
class ManagedRuntimeCallingConvention : public CallingConvention {
 public:
  static ManagedRuntimeCallingConvention* Create(const Method* native_method,
                                                 InstructionSet instruction_set);

  size_t FrameSize();

  // Register that holds the incoming method argument
  virtual ManagedRegister MethodRegister() = 0;

  // Iterator interface
  bool HasNext();
  void Next();
  bool IsCurrentParamAReference();
  bool IsCurrentArgExplicit();  // ie a non-implict argument such as this
  bool IsCurrentArgPossiblyNull();
  size_t CurrentParamSize();
  virtual bool IsCurrentParamInRegister() = 0;
  virtual bool IsCurrentParamOnStack() = 0;
  virtual ManagedRegister CurrentParamRegister() = 0;
  virtual FrameOffset CurrentParamStackOffset() = 0;

  virtual ~ManagedRuntimeCallingConvention() {}

 protected:
  explicit ManagedRuntimeCallingConvention(const Method* method) :
                                           CallingConvention(method) {}
};

// Abstraction for JNI calling conventions
// | { Incoming stack args }         | <-- Prior SP
// | { Return address }              |
// | { Callee saves }                |     ([1])
// | { Return value spill }          |     (live on return slow paths)
// | { Local Ref. Table State }      |
// | { Stack Indirect Ref. Table     |
// |   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                    |
//
// [1] We must save all callee saves here to enable any exception throws to restore
// callee saves for frames above this one.
class JniCallingConvention : public CallingConvention {
 public:
  static JniCallingConvention* Create(const Method* native_method,
                                      InstructionSet instruction_set);

  // 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.
  virtual size_t FrameSize() = 0;
  // Size of outgoing arguments, including alignment
  virtual size_t OutArgSize() = 0;
  // Number of references in stack indirect reference table
  size_t ReferenceCount() const;
  // Location where the segment state of the local indirect reference table is saved
  FrameOffset SavedLocalReferenceCookieOffset() const;
  // Location where the return value of a call can be squirreled if another
  // call is made following the native call
  FrameOffset ReturnValueSaveLocation() const;

  // Callee save registers to spill prior to native code (which may clobber)
  virtual const std::vector<ManagedRegister>& CalleeSaveRegisters() const = 0;

  // Spill mask values
  virtual uint32_t CoreSpillMask() const = 0;
  virtual uint32_t FpSpillMask() const = 0;

  // Returns true if the method register will have been clobbered during argument
  // set up
  virtual bool IsMethodRegisterClobberedPreCall() = 0;

  // An extra scratch register live after the call
  virtual ManagedRegister ReturnScratchRegister() const = 0;

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

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

  // Position of SIRT and interior fields
  FrameOffset SirtOffset() const {
    return FrameOffset(displacement_.Int32Value() +
                       kPointerSize);  // above Method*
  }
  FrameOffset SirtNumRefsOffset() const {
    return FrameOffset(SirtOffset().Int32Value() +
                       StackIndirectReferenceTable::NumberOfReferencesOffset());
  }
  FrameOffset SirtLinkOffset() const {
    return FrameOffset(SirtOffset().Int32Value() +
                       StackIndirectReferenceTable::LinkOffset());
  }

  virtual ~JniCallingConvention() {}

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

  explicit JniCallingConvention(const Method* native_method) :
      CallingConvention(native_method) {}

  // Number of stack slots for outgoing arguments, above which the SIRT is
  // located
  virtual size_t NumberOfOutgoingStackArgs() = 0;

 protected:
  static size_t NumberOfExtraArgumentsForJni(const Method* method);
};

}  // namespace art

#endif  // ART_SRC_CALLING_CONVENTION_H_
