// Copyright (c) 2011, 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_DART_ENTRY_H_
#define RUNTIME_VM_DART_ENTRY_H_

#include "vm/allocation.h"
#include "vm/growable_array.h"
#include "vm/object.h"
#include "vm/raw_object.h"

namespace dart {

// Forward declarations.
class Array;
class Closure;
class FlowGraphDeserializer;
class FlowGraphSerializer;
class Function;
class Instance;
class Integer;
class Library;
class Object;
class String;

// An arguments descriptor array consists of the type argument vector length (0
// if none); total argument count (not counting type argument vector); total
// arguments size (not counting type argument vector); the positional argument
// count; a sequence of (name, position) pairs, sorted by name, for each named
// optional argument; and a terminating null to simplify iterating in generated
// code.
class ArgumentsDescriptor : public ValueObject {
 public:
  explicit ArgumentsDescriptor(const Array& array);

  // Accessors.
  intptr_t TypeArgsLen() const;  // 0 if no type argument vector is passed.
  intptr_t FirstArgIndex() const { return TypeArgsLen() > 0 ? 1 : 0; }
  intptr_t CountWithTypeArgs() const { return FirstArgIndex() + Count(); }
  intptr_t Count() const;  // Excluding type arguments vector.
  intptr_t Size() const;   // Excluding type arguments vector.
  intptr_t SizeWithTypeArgs() const { return FirstArgIndex() + Size(); }
  intptr_t PositionalCount() const;  // Excluding type arguments vector.
  intptr_t NamedCount() const { return Count() - PositionalCount(); }
  StringPtr NameAt(intptr_t i) const;
  intptr_t PositionAt(intptr_t i) const;
  bool MatchesNameAt(intptr_t i, const String& other) const;
  // Returns array of argument names in the arguments order.
  ArrayPtr GetArgumentNames() const;
  void PrintTo(BaseTextBuffer* buffer, bool show_named_positions = false) const;
  const char* ToCString() const;

  // Generated code support.
  static intptr_t type_args_len_offset() {
    return Array::element_offset(kTypeArgsLenIndex);
  }

  static intptr_t count_offset() { return Array::element_offset(kCountIndex); }

  static intptr_t size_offset() { return Array::element_offset(kSizeIndex); }

  static intptr_t positional_count_offset() {
    return Array::element_offset(kPositionalCountIndex);
  }

  static intptr_t first_named_entry_offset() {
    return Array::element_offset(kFirstNamedEntryIndex);
  }

  static intptr_t name_offset() { return kNameOffset * kCompressedWordSize; }
  static intptr_t position_offset() {
    return kPositionOffset * kCompressedWordSize;
  }
  static intptr_t named_entry_size() {
    return kNamedEntrySize * kCompressedWordSize;
  }

  // Constructs an argument descriptor where all arguments are boxed and
  // therefore number of parameters equals parameter size.
  //
  // Right now this is for example the case for all closure functions.
  // Functions marked as entry-points may also be created by NewUnboxed because
  // we rely that TFA will mark the arguments as nullable for such cases.
  static ArrayPtr NewBoxed(intptr_t type_args_len,
                           intptr_t num_arguments,
                           const Array& optional_arguments_names,
                           Heap::Space space = Heap::kOld) {
    return New(type_args_len, num_arguments, num_arguments,
               optional_arguments_names, space);
  }

  // Allocate and return an arguments descriptor.  The first
  // (num_arguments - optional_arguments_names.Length()) arguments are
  // positional and the remaining ones are named optional arguments.
  // The presence of a type argument vector as first argument (not counted in
  // num_arguments) is indicated by a non-zero type_args_len.
  static ArrayPtr New(intptr_t type_args_len,
                      intptr_t num_arguments,
                      intptr_t size_arguments,
                      const Array& optional_arguments_names,
                      Heap::Space space = Heap::kOld);

  // Constructs an argument descriptor where all arguments are boxed and
  // therefore number of parameters equals parameter size.
  //
  // Right now this is for example the case for all closure functions.
  static ArrayPtr NewBoxed(intptr_t type_args_len,
                           intptr_t num_arguments,
                           Heap::Space space = Heap::kOld) {
    return New(type_args_len, num_arguments, num_arguments, space);
  }

  // Allocate and return an arguments descriptor that has no optional
  // arguments. All arguments are positional. The presence of a type argument
  // vector as first argument (not counted in num_arguments) is indicated
  // by a non-zero type_args_len.
  static ArrayPtr New(intptr_t type_args_len,
                      intptr_t num_arguments,
                      intptr_t size_arguments,
                      Heap::Space space = Heap::kOld);

  // Initialize the preallocated fixed length arguments descriptors cache.
  static void Init();

  // Clear the preallocated fixed length arguments descriptors cache.
  static void Cleanup();

  static constexpr intptr_t kMaxTypeArgsForCachedDescriptor = 1;
  static constexpr intptr_t
      kMaxNumArgumentsForCachedDescriptor[kMaxTypeArgsForCachedDescriptor + 1] =
          {31, 2};
  static constexpr intptr_t kCachedDescriptorCount = []() -> intptr_t {
    intptr_t result = 0;
    for (intptr_t i = 0; i <= kMaxTypeArgsForCachedDescriptor; ++i) {
      result += kMaxNumArgumentsForCachedDescriptor[i] + 1;
    }
    return result;
  }();

  // For creating ArgumentDescriptor Slots.
  static constexpr bool ContainsCompressedPointers() {
    // Use the same state as the backing store.
    return Array::ContainsCompressedPointers();
  }

  void Write(FlowGraphSerializer* s) const;
  static ArrayPtr Read(FlowGraphDeserializer* d);

 private:
  // Absolute indices into the array.
  // Keep these in sync with the constants in invocation_mirror_patch.dart.
  enum {
    kTypeArgsLenIndex,
    kCountIndex,
    kSizeIndex,
    kPositionalCountIndex,
    kFirstNamedEntryIndex,
  };

 private:
  // Relative indexes into each named argument entry.
  enum {
    kNameOffset,
    // The least significant bit of the entry in 'kPositionOffset' (second
    // least-significant after Smi-encoding) holds the strong-mode checking bit
    // for the named argument.
    kPositionOffset,
    kNamedEntrySize,
  };

  static intptr_t LengthFor(intptr_t num_named_arguments) {
    // Add 1 for the terminating null.
    return kFirstNamedEntryIndex + (kNamedEntrySize * num_named_arguments) + 1;
  }

  static ArrayPtr NewNonCached(intptr_t type_args_len,
                               intptr_t num_arguments,
                               intptr_t size_arguments,
                               bool canonicalize,
                               Heap::Space space);

  // Used by Simulator to parse argument descriptors.
  static intptr_t name_index(intptr_t index) {
    return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
  }

  static intptr_t position_index(intptr_t index) {
    return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset;
  }

  bool IsCached() const;

  static intptr_t CacheIndexFor(intptr_t type_args_len, intptr_t num_arguments);
  static bool CanUseCachedDescriptor(intptr_t type_args_len,
                                     intptr_t num_arguments);

  const Array& array_;

  // A cache of VM heap allocated arguments descriptors.
  static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount];

  friend class Interpreter;
  friend class InterpreterHelpers;
  friend class VMSerializationRoots;
  friend class VMDeserializationRoots;
  DISALLOW_COPY_AND_ASSIGN(ArgumentsDescriptor);
};

// DartEntry abstracts functionality needed to resolve dart functions
// and invoke them from C++.
class DartEntry : public AllStatic {
 public:
  // Invokes the specified instance function or static function.
  // The first argument of an instance function is the receiver.
  // On success, returns an InstancePtr.  On failure, an ErrorPtr.
  // This is used when there is no type argument vector and
  // no named arguments in the call.
  static ObjectPtr InvokeFunction(const Function& function,
                                  const Array& arguments);

#if defined(TESTING)
  // Invokes the specified code as if it was a Dart function.
  // On success, returns an InstancePtr.  On failure, an ErrorPtr.
  static ObjectPtr InvokeCode(const Code& code,
                              const Array& arguments_descriptor,
                              const Array& arguments,
                              Thread* thread);
#endif

  // Invokes the specified instance, static, or closure function.
  // On success, returns an InstancePtr.  On failure, an ErrorPtr.
  static ObjectPtr InvokeFunction(const Function& function,
                                  const Array& arguments,
                                  const Array& arguments_descriptor);

  // Invokes the first argument in the provided arguments array as a callable
  // object, performing any needed dynamic checks if the callable cannot receive
  // dynamic invocation.
  //
  // On success, returns an InstancePtr.  On failure, an ErrorPtr.
  //
  // Used when an ArgumentsDescriptor is not required, that is, when there
  // are no type arguments or named arguments.
  static ObjectPtr InvokeClosure(Thread* thread, const Array& arguments);

  // Invokes the first argument in the provided arguments array as a callable
  // object, performing any needed dynamic checks if the callable cannot receive
  // dynamic invocation.
  //
  // On success, returns an InstancePtr.  On failure, an ErrorPtr.
  static ObjectPtr InvokeClosure(Thread* thread,
                                 const Array& arguments,
                                 const Array& arguments_descriptor);

  // Invokes the noSuchMethod instance function on the receiver.
  // On success, returns an InstancePtr.  On failure, an ErrorPtr.
  static ObjectPtr InvokeNoSuchMethod(Thread* thread,
                                      const Instance& receiver,
                                      const String& target_name,
                                      const Array& arguments,
                                      const Array& arguments_descriptor);

 private:
  // Resolves the first argument in the provided arguments array to a callable
  // compatible with the arguments. Helper method used within InvokeClosure.
  //
  // If no errors occur, the first argument is changed to be either the resolved
  // callable or, if Function::null() is returned, an appropriate target for
  // invoking noSuchMethod.
  //
  // On success, returns a FunctionPtr. On failure, an ErrorPtr.
  static ObjectPtr ResolveCallable(Thread* thread,
                                   const Array& arguments,
                                   const Array& arguments_descriptor);

  // Invokes a function returned by ResolveCallable, performing any dynamic
  // checks needed if the function cannot receive dynamic invocation. Helper
  // method used within InvokeClosure.
  //
  // On success, returns an InstancePtr. On failure, an ErrorPtr.
  static ObjectPtr InvokeCallable(Thread* thread,
                                  const Function& callable_function,
                                  const Array& arguments,
                                  const Array& arguments_descriptor);
};

// Utility functions to call from VM into Dart bootstrap libraries.
// Each may return an exception object.
class DartLibraryCalls : public AllStatic {
 public:
  // On success, returns an InstancePtr. On failure, an ErrorPtr.
  static ObjectPtr InstanceCreate(const Library& library,
                                  const String& exception_name,
                                  const String& constructor_name,
                                  const Array& arguments);

  // On success, returns an InstancePtr. On failure, an ErrorPtr.
  static ObjectPtr ToString(const Instance& receiver);

  // On success, returns an InstancePtr. On failure, an ErrorPtr.
  static ObjectPtr HashCode(const Instance& receiver);

  // On success, returns an InstancePtr. On failure, an ErrorPtr.
  static ObjectPtr Equals(const Instance& left, const Instance& right);

  // Returns the handler if one has been registered for this port id.
  static ObjectPtr LookupHandler(Dart_Port port_id);

  // Returns handler on success, an ErrorPtr on failure, null if can't find
  // handler for this port id.
  static ObjectPtr HandleMessage(Dart_Port port_id, const Instance& message);

  // Invokes the finalizer to run its callbacks.
  static ObjectPtr HandleFinalizerMessage(const FinalizerBase& finalizer);

  // Returns a list of open ReceivePorts.
  static ObjectPtr LookupOpenPorts();

  // Returns null on success, an ErrorPtr on failure.
  static ObjectPtr DrainMicrotaskQueue();

  // Ensures that the isolate's _pendingImmediateCallback is set to
  // _startMicrotaskLoop from dart:async.
  // Returns null on success, an ErrorPtr on failure.
  static ObjectPtr EnsureScheduleImmediate();

  // Runs the `_rehashObjects()` function in `dart:compact_hash`.
  static ObjectPtr RehashObjectsInDartCompactHash(
      Thread* thread,
      const Object& array_or_growable_array);

  // Runs the `_rehashObjects()` function in `dart:core`.
  static ObjectPtr RehashObjectsInDartCore(
      Thread* thread,
      const Object& array_or_growable_array);
};

}  // namespace dart

#endif  // RUNTIME_VM_DART_ENTRY_H_
