/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_METHOD_HANDLES_H_
#define ART_RUNTIME_METHOD_HANDLES_H_

#include <ostream>

#include "dex_instruction.h"
#include "handle.h"
#include "jvalue.h"
#include "mirror/class.h"

namespace art {

namespace mirror {
  class MethodHandle;
  class MethodType;
}  // namespace mirror

class ShadowFrame;

// Returns true if there is a possible conversion from |from| to |to|
// for a MethodHandle parameter.
bool IsParameterTypeConvertible(ObjPtr<mirror::Class> from,
                                ObjPtr<mirror::Class> to);

// Returns true if there is a possible conversion from |from| to |to|
// for the return type of a MethodHandle.
bool IsReturnTypeConvertible(ObjPtr<mirror::Class> from,
                             ObjPtr<mirror::Class> to);

// Performs a conversion from type |from| to a distinct type |to| as
// part of conversion of |caller_type| to |callee_type|. The value to
// be converted is in |value|. Returns true on success and updates
// |value| with the converted value, false otherwise.
bool ConvertJValueCommon(Handle<mirror::MethodType> callsite_type,
                         Handle<mirror::MethodType> callee_type,
                         ObjPtr<mirror::Class> from,
                         ObjPtr<mirror::Class> to,
                         JValue* value)
    REQUIRES_SHARED(Locks::mutator_lock_);

// Converts the value of the argument at position |index| from type
// expected by |callee_type| to type used by |callsite_type|. |value|
// represents the value to be converted. Returns true on success and
// updates |value|, false otherwise.
ALWAYS_INLINE bool ConvertArgumentValue(Handle<mirror::MethodType> callsite_type,
                                        Handle<mirror::MethodType> callee_type,
                                        int index,
                                        JValue* value)
    REQUIRES_SHARED(Locks::mutator_lock_);

// Converts the return value from return type yielded by
// |callee_type| to the return type yielded by
// |callsite_type|. |value| represents the value to be
// converted. Returns true on success and updates |value|, false
// otherwise.
ALWAYS_INLINE bool ConvertReturnValue(Handle<mirror::MethodType> callsite_type,
                                      Handle<mirror::MethodType> callee_type,
                                      JValue* value)
    REQUIRES_SHARED(Locks::mutator_lock_);

// Perform argument conversions between |callsite_type| (the type of the
// incoming arguments) and |callee_type| (the type of the method being
// invoked). These include widening and narrowing conversions as well as
// boxing and unboxing. Returns true on success, on false on failure. A
// pending exception will always be set on failure.
//
// The values to be converted are read from an input source (of type G)
// that provides three methods :
//
// class G {
//   // Used to read the next boolean/short/int or float value from the
//   // source.
//   uint32_t Get();
//
//   // Used to the read the next reference value from the source.
//   ObjPtr<mirror::Object> GetReference();
//
//   // Used to read the next double or long value from the source.
//   int64_t GetLong();
// }
//
// After conversion, the values are written to an output sink (of type S)
// that provides three methods :
//
// class S {
//   void Set(uint32_t);
//   void SetReference(ObjPtr<mirror::Object>)
//   void SetLong(int64_t);
// }
//
// The semantics and usage of the Set methods are analagous to the getter
// class.
//
// This method is instantiated in three different scenarions :
// - <S = ShadowFrameSetter, G = ShadowFrameGetter> : copying from shadow
//   frame to shadow frame, used in a regular polymorphic non-exact invoke.
// - <S = EmulatedShadowFrameAccessor, G = ShadowFrameGetter> : entering into
//   a transformer method from a polymorphic invoke.
// - <S = ShadowFrameStter, G = EmulatedStackFrameAccessor> : entering into
//   a regular poly morphic invoke from a transformer method.
//
// TODO(narayan): If we find that the instantiations of this function take
// up too much space, we can make G / S abstract base classes that are
// overridden by concrete classes.
template <typename G, typename S>
bool PerformConversions(Thread* self,
                        Handle<mirror::MethodType> callsite_type,
                        Handle<mirror::MethodType> callee_type,
                        G* getter,
                        S* setter,
                        int32_t num_conversions) REQUIRES_SHARED(Locks::mutator_lock_);

// A convenience class that allows for iteration through a list of
// input argument registers |arg| for non-range invokes or a list of
// consecutive registers starting with a given based for range
// invokes.
//
// This is used to iterate over input arguments while performing standard
// argument conversions.
template <bool is_range>
class ShadowFrameGetter {
 public:
  ShadowFrameGetter(size_t first_src_reg,
                    const uint32_t (&arg)[Instruction::kMaxVarArgRegs],
                    const ShadowFrame& shadow_frame) :
      first_src_reg_(first_src_reg),
      arg_(arg),
      shadow_frame_(shadow_frame),
      arg_index_(0) {
  }

  ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) {
    const uint32_t next = (is_range ? first_src_reg_ + arg_index_ : arg_[arg_index_]);
    ++arg_index_;

    return shadow_frame_.GetVReg(next);
  }

  ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) {
    const uint32_t next = (is_range ? first_src_reg_ + arg_index_ : arg_[arg_index_]);
    arg_index_ += 2;

    return shadow_frame_.GetVRegLong(next);
  }

  ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) {
    const uint32_t next = (is_range ? first_src_reg_ + arg_index_ : arg_[arg_index_]);
    ++arg_index_;

    return shadow_frame_.GetVRegReference(next);
  }

 private:
  const size_t first_src_reg_;
  const uint32_t (&arg_)[Instruction::kMaxVarArgRegs];
  const ShadowFrame& shadow_frame_;
  size_t arg_index_;
};

// A convenience class that allows values to be written to a given shadow frame,
// starting at location |first_dst_reg|.
class ShadowFrameSetter {
 public:
  ShadowFrameSetter(ShadowFrame* shadow_frame,
                    size_t first_dst_reg) :
    shadow_frame_(shadow_frame),
    arg_index_(first_dst_reg) {
  }

  ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame_->SetVReg(arg_index_++, value);
  }

  ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame_->SetVRegReference(arg_index_++, value.Ptr());
  }

  ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame_->SetVRegLong(arg_index_, value);
    arg_index_ += 2;
  }

 private:
  ShadowFrame* shadow_frame_;
  size_t arg_index_;
};

template <bool is_range>
bool DoInvokePolymorphic(Thread* self,
                         ArtMethod* invoke_method,
                         ShadowFrame& shadow_frame,
                         Handle<mirror::MethodHandle> method_handle,
                         Handle<mirror::MethodType> callsite_type,
                         const uint32_t (&args)[Instruction::kMaxVarArgRegs],
                         uint32_t first_arg,
                         JValue* result)
    REQUIRES_SHARED(Locks::mutator_lock_);

}  // namespace art

#endif  // ART_RUNTIME_METHOD_HANDLES_H_
