// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_NATIVE_ARGUMENTS_H_
#define RUNTIME_VM_NATIVE_ARGUMENTS_H_

#include "platform/assert.h"
#include "platform/memory_sanitizer.h"
#include "vm/globals.h"
#include "vm/simulator.h"
#include "vm/stub_code.h"

namespace dart {

// Forward declarations.
class BootstrapNatives;
class Object;
class Simulator;
class Thread;

#if defined(TESTING) || defined(DEBUG)

#if defined(USING_SIMULATOR)
#define CHECK_STACK_ALIGNMENT                                                  \
  {                                                                            \
    uword current_sp = Simulator::Current()->get_register(SPREG);              \
    ASSERT(Utils::IsAligned(current_sp, OS::ActivationFrameAlignment()));      \
  }
#elif defined(DART_HOST_OS_WINDOWS)
// The compiler may dynamically align the stack on Windows, so do not check.
#define CHECK_STACK_ALIGNMENT                                                  \
  {}
#else
#define CHECK_STACK_ALIGNMENT                                                  \
  {                                                                            \
    uword (*func)() = reinterpret_cast<uword (*)()>(                           \
        StubCode::GetCStackPointer().EntryPoint());                            \
    uword current_sp = func();                                                 \
    ASSERT(Utils::IsAligned(current_sp, OS::ActivationFrameAlignment()));      \
  }
#endif

void VerifyOnTransition();

#define DEOPTIMIZE_ALOT                                                        \
  if (FLAG_deoptimize_alot) {                                                  \
    DeoptimizeFunctionsOnStack();                                              \
  }

#else

#define CHECK_STACK_ALIGNMENT                                                  \
  {}
#define DEOPTIMIZE_ALOT                                                        \
  {}

#endif

// Class NativeArguments is used to access arguments passed in from
// generated dart code to a runtime function or a dart library native
// function. It is also used to set the return value if any at the slot
// reserved for return values.
// All runtime function/dart library native functions have the
// following signature:
//   void function_name(NativeArguments arguments);
// Inside the function, arguments are accessed as follows:
//   const Instance& arg0 = Instance::CheckedHandle(arguments.NativeArgAt(0));
//   const Smi& arg1 = Smi::CheckedHandle(arguments.NativeArgAt(1));
// If the function is generic, type arguments are accessed as follows:
//   const TypeArguments& type_args =
//       TypeArguments::Handle(arguments.NativeTypeArgs());
// The return value is set as follows:
//   arguments.SetReturn(result);
// NOTE: Since we pass 'this' as a pass-by-value argument in the stubs we don't
// have DISALLOW_COPY_AND_ASSIGN in the class definition and do not make it a
// subclass of ValueObject.
class NativeArguments {
 public:
  Thread* thread() const { return thread_; }

  // Includes type arguments vector.
  int ArgCount() const { return ArgcBits::decode(argc_tag_); }

  ObjectPtr ArgAt(int index) const {
    ASSERT((index >= 0) && (index < ArgCount()));
    ObjectPtr* arg_ptr =
        &(argv_[ReverseArgOrderBit::decode(argc_tag_) ? index : -index]);
    // Tell MemorySanitizer the ObjectPtr was initialized (by generated code).
    MSAN_UNPOISON(arg_ptr, kWordSize);
    return *arg_ptr;
  }

  void SetArgAt(int index, const Object& value) const {
    ASSERT(thread_->execution_state() == Thread::kThreadInVM);
    ASSERT((index >= 0) && (index < ArgCount()));
    ObjectPtr* arg_ptr =
        &(argv_[ReverseArgOrderBit::decode(argc_tag_) ? index : -index]);
    *arg_ptr = value.ptr();
  }

  // Does not include hidden type arguments vector.
  int NativeArgCount() const {
    int function_bits = FunctionBits::decode(argc_tag_);
    return ArgCount() - NumHiddenArgs(function_bits);
  }

  ObjectPtr NativeArg0() const {
    int function_bits = FunctionBits::decode(argc_tag_);
    if ((function_bits & (kClosureFunctionBit | kInstanceFunctionBit)) ==
        (kClosureFunctionBit | kInstanceFunctionBit)) {
      // Retrieve the receiver from the context.
      const int closure_index =
          (function_bits & kGenericFunctionBit) != 0 ? 1 : 0;
      const Object& closure = Object::Handle(ArgAt(closure_index));
      const Context& context =
          Context::Handle(Closure::Cast(closure).context());
      return context.At(0);
    }
    return ArgAt(NumHiddenArgs(function_bits));
  }

  ObjectPtr NativeArgAt(int index) const {
    ASSERT((index >= 0) && (index < NativeArgCount()));
    if (index == 0) {
      return NativeArg0();
    }
    int function_bits = FunctionBits::decode(argc_tag_);
    const int actual_index = index + NumHiddenArgs(function_bits);
    return ArgAt(actual_index);
  }

  TypeArgumentsPtr NativeTypeArgs() const {
    ASSERT(ToGenericFunction());
    return TypeArguments::RawCast(ArgAt(0));
  }

  int NativeTypeArgCount() const {
    if (ToGenericFunction()) {
      TypeArguments& type_args = TypeArguments::Handle(NativeTypeArgs());
      if (type_args.IsNull()) {
        // null vector represents infinite list of dynamics
        return INT_MAX;
      }
      return type_args.Length();
    }
    return 0;
  }

  AbstractTypePtr NativeTypeArgAt(int index) const {
    ASSERT((index >= 0) && (index < NativeTypeArgCount()));
    TypeArguments& type_args = TypeArguments::Handle(NativeTypeArgs());
    if (type_args.IsNull()) {
      // null vector represents infinite list of dynamics
      return Type::dynamic_type().ptr();
    }
    return type_args.TypeAt(index);
  }

  void SetReturn(const Object& value) const {
    ASSERT(thread_->execution_state() == Thread::kThreadInVM);
    *retval_ = value.ptr();
  }

  ObjectPtr ReturnValue() const {
    // Tell MemorySanitizer the retval_ was initialized (by generated code).
    MSAN_UNPOISON(retval_, kWordSize);
    return *retval_;
  }

  static intptr_t thread_offset() {
    return OFFSET_OF(NativeArguments, thread_);
  }
  static intptr_t argc_tag_offset() {
    return OFFSET_OF(NativeArguments, argc_tag_);
  }
  static intptr_t argv_offset() { return OFFSET_OF(NativeArguments, argv_); }
  static intptr_t retval_offset() {
    return OFFSET_OF(NativeArguments, retval_);
  }

  static intptr_t ParameterCountForResolution(const Function& function) {
    ASSERT(function.is_native());
    ASSERT(!function.IsGenerativeConstructor());  // Not supported.
    intptr_t count = function.NumParameters();
    if (function.is_static() && function.IsClosureFunction()) {
      // The closure object is hidden and not accessible from native code.
      // However, if the function is an instance closure function, the captured
      // receiver located in the context is made accessible in native code at
      // index 0, thereby hiding the closure object at index 0.
      count--;
    }
    return count;
  }

  static int ComputeArgcTag(const Function& function) {
    ASSERT(function.is_native());
    ASSERT(!function.IsGenerativeConstructor());  // Not supported.
    int argc = function.NumParameters();
    int function_bits = 0;
    if (!function.is_static()) {
      function_bits |= kInstanceFunctionBit;
    }
    if (function.IsClosureFunction()) {
      function_bits |= kClosureFunctionBit;
    }
    if (function.IsGeneric()) {
      function_bits |= kGenericFunctionBit;
      argc++;
    }
    int tag = ArgcBits::encode(argc);
    tag = FunctionBits::update(function_bits, tag);
    return tag;
  }

 private:
  enum {
    kInstanceFunctionBit = 1,
    kClosureFunctionBit = 2,
    kGenericFunctionBit = 4,
  };
  enum ArgcTagBits {
    kArgcBit = 0,
    kArgcSize = 24,
    kFunctionBit = kArgcBit + kArgcSize,
    kFunctionSize = 3,
    kReverseArgOrderBit = kFunctionBit + kFunctionSize,
    kReverseArgOrderSize = 1,
  };
  class ArgcBits : public BitField<intptr_t, int32_t, kArgcBit, kArgcSize> {};
  class FunctionBits
      : public BitField<intptr_t, int, kFunctionBit, kFunctionSize> {};
  class ReverseArgOrderBit
      : public BitField<intptr_t, bool, kReverseArgOrderBit, 1> {};
  friend class Api;
  friend class NativeEntry;
  friend class Simulator;

  // Allow simulator to create NativeArguments in reverse order
  // on the stack.
  NativeArguments(Thread* thread,
                  int argc_tag,
                  ObjectPtr* argv,
                  ObjectPtr* retval)
      : thread_(thread),
        argc_tag_(ReverseArgOrderBit::update(true, argc_tag)),
        argv_(argv),
        retval_(retval) {}

  // Since this function is passed a RawObject directly, we need to be
  // exceedingly careful when we use it.  If there are any other side
  // effects in the statement that may cause GC, it could lead to
  // bugs.
  void SetReturnUnsafe(ObjectPtr value) const {
    ASSERT(thread_->execution_state() == Thread::kThreadInVM);
    *retval_ = value;
  }

  // Returns true if the arguments are those of an instance function call.
  bool ToInstanceFunction() const {
    return (FunctionBits::decode(argc_tag_) & kInstanceFunctionBit) != 0;
  }

  // Returns true if the arguments are those of a closure function call.
  bool ToClosureFunction() const {
    return (FunctionBits::decode(argc_tag_) & kClosureFunctionBit) != 0;
  }

  // Returns true if the arguments are those of a generic function call.
  bool ToGenericFunction() const {
    return (FunctionBits::decode(argc_tag_) & kGenericFunctionBit) != 0;
  }

  int NumHiddenArgs(int function_bits) const {
    int num_hidden_args = 0;
    // For static closure functions, the closure at index 0 is hidden.
    // In the instance closure function case, the receiver is accessed from
    // the context and the closure at index 0 is hidden, so the apparent
    // argument count remains unchanged.
    if ((function_bits & kClosureFunctionBit) == kClosureFunctionBit) {
      num_hidden_args++;
    }
    if ((function_bits & kGenericFunctionBit) == kGenericFunctionBit) {
      num_hidden_args++;
    }
    return num_hidden_args;
  }

  Thread* thread_;      // Current thread pointer.
  intptr_t argc_tag_;   // Encodes argument count and invoked native call type.
  ObjectPtr* argv_;     // Pointer to an array of arguments to runtime call.
  ObjectPtr* retval_;   // Pointer to the return value area.
};

}  // namespace dart

#endif  // RUNTIME_VM_NATIVE_ARGUMENTS_H_
