// 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_PARSER_H_
#define RUNTIME_VM_PARSER_H_

#include "include/dart_api.h"

#include "lib/invocation_mirror.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "vm/allocation.h"
#include "vm/class_finalizer.h"
#include "vm/hash_table.h"
#include "vm/kernel.h"
#include "vm/object.h"
#include "vm/raw_object.h"
#include "vm/scopes.h"
#include "vm/token.h"

namespace dart {

// Forward declarations.

namespace kernel {

class ScopeBuildingResult;

}  // namespace kernel

class ArgumentsDescriptor;
class BitVector;
class Isolate;
class LocalScope;
class LocalVariable;
struct RegExpCompileData;
template <typename T>
class GrowableArray;
class Parser;

class FieldKeyValueTrait {
 public:
  // Typedefs needed for the DirectChainedHashMap template.
  typedef const Field* Key;
  typedef const Field* Value;
  typedef const Field* Pair;

  static Key KeyOf(Pair kv) { return kv; }

  static Value ValueOf(Pair kv) { return kv; }

  static inline uword Hash(Key key) {
    const TokenPosition token_pos = key->token_pos();
    if (token_pos.IsReal()) {
      return token_pos.Hash();
    }
    return key->kernel_offset();
  }

  static inline bool IsKeyEqual(Pair pair, Key key) {
    return pair->Original() == key->Original();
  }
};

typedef DirectChainedHashMap<FieldKeyValueTrait> FieldSet;

// The class ParsedFunction holds the result of parsing a function.
class ParsedFunction : public ZoneObject {
 public:
  ParsedFunction(Thread* thread, const Function& function);

  const Function& function() const { return function_; }

  LocalScope* scope() const { return scope_; }
  void set_scope(LocalScope* scope) {
    ASSERT(scope_ == nullptr);
    ASSERT(scope != nullptr);
    scope_ = scope;
  }

  RegExpCompileData* regexp_compile_data() const {
    return regexp_compile_data_;
  }
  void SetRegExpCompileData(RegExpCompileData* regexp_compile_data);

  LocalVariable* function_type_arguments() const {
    return function_type_arguments_;
  }
  void set_function_type_arguments(LocalVariable* function_type_arguments) {
    ASSERT(function_type_arguments != nullptr);
    function_type_arguments_ = function_type_arguments;
  }
  LocalVariable* parent_type_arguments() const {
    return parent_type_arguments_;
  }
  void set_parent_type_arguments(LocalVariable* parent_type_arguments) {
    ASSERT(parent_type_arguments != nullptr);
    parent_type_arguments_ = parent_type_arguments;
  }

  LocalVariable* suspend_state_var() const { return suspend_state_var_; }
  void set_suspend_state_var(LocalVariable* suspend_state_var) {
    ASSERT(suspend_state_var != nullptr);
    suspend_state_var_ = suspend_state_var;
  }

  void set_default_parameter_values(ZoneGrowableArray<const Instance*>* list) {
    default_parameter_values_ = list;
#if defined(DEBUG)
    if (list == nullptr) return;
    for (intptr_t i = 0; i < list->length(); i++) {
      DEBUG_ASSERT(list->At(i)->IsNotTemporaryScopedHandle());
    }
#endif
  }

  const Instance& DefaultParameterValueAt(intptr_t i) const {
    ASSERT(default_parameter_values_ != nullptr);
    return *default_parameter_values_->At(i);
  }

  ZoneGrowableArray<const Instance*>* default_parameter_values() const {
    return default_parameter_values_;
  }

  LocalVariable* current_context_var() const { return current_context_var_; }

  bool has_arg_desc_var() const { return arg_desc_var_ != nullptr; }
  LocalVariable* arg_desc_var() const { return arg_desc_var_; }

  LocalVariable* receiver_var() const {
    ASSERT(receiver_var_ != nullptr);
    return receiver_var_;
  }
  void set_receiver_var(LocalVariable* value) {
    ASSERT(receiver_var_ == nullptr);
    ASSERT(value != nullptr);
    receiver_var_ = value;
  }
  bool has_receiver_var() const { return receiver_var_ != nullptr; }

  void set_receiver_used() { receiver_used_ = true; }
  bool is_receiver_used() const {
    ASSERT(kernel_scopes_ != nullptr);
    ASSERT(!receiver_used_ || receiver_var() != nullptr);
    return receiver_used_;
  }

  LocalVariable* expression_temp_var() const {
    ASSERT(has_expression_temp_var());
    return expression_temp_var_;
  }
  void set_expression_temp_var(LocalVariable* value) {
    ASSERT(!has_expression_temp_var());
    expression_temp_var_ = value;
  }
  bool has_expression_temp_var() const {
    return expression_temp_var_ != nullptr;
  }

  LocalVariable* entry_points_temp_var() const {
    ASSERT(has_entry_points_temp_var());
    return entry_points_temp_var_;
  }
  void set_entry_points_temp_var(LocalVariable* value) {
    ASSERT(!has_entry_points_temp_var());
    entry_points_temp_var_ = value;
  }
  bool has_entry_points_temp_var() const {
    return entry_points_temp_var_ != nullptr;
  }

  LocalVariable* EnsureExpressionTemp();
  LocalVariable* EnsureEntryPointsTemp();

  const FieldSet* guarded_fields() const { return &guarded_fields_; }

  VariableIndex first_parameter_index() const { return first_parameter_index_; }
  int num_stack_locals() const { return num_stack_locals_; }

  void AllocateVariables();

  void record_await() { have_seen_await_expr_ = true; }
  bool have_seen_await() const { return have_seen_await_expr_; }

  Thread* thread() const { return thread_; }
  Isolate* isolate() const { return thread_->isolate(); }
  Zone* zone() const { return thread_->zone(); }

  // Adds only relevant fields: field must be unique and its guarded_cid()
  // relevant.
  void AddToGuardedFields(const Field* field) const;

  void Bailout(const char* origin, const char* reason) const;

  kernel::ScopeBuildingResult* EnsureKernelScopes();

  LocalVariable* RawTypeArgumentsVariable() const {
    return raw_type_arguments_var_;
  }

  void SetRawTypeArgumentsVariable(LocalVariable* raw_type_arguments_var) {
    raw_type_arguments_var_ = raw_type_arguments_var;
  }

  void SetRawParameters(ZoneGrowableArray<LocalVariable*>* raw_parameters) {
    raw_parameters_ = raw_parameters;
  }

  LocalVariable* RawParameterVariable(intptr_t i) const {
    return raw_parameters_->At(i);
  }

  LocalVariable* ParameterVariable(intptr_t i) const {
    ASSERT((i >= 0) && (i < function_.NumParameters()));
    ASSERT(scope() != nullptr);
    return scope()->VariableAt(i);
  }

  // Remembers the set of covariant parameters.
  // [covariant_parameters] is a bitvector of function.NumParameters() length.
  void SetCovariantParameters(const BitVector* covariant_parameters);

  // Remembers the set of generic-covariant-impl parameters.
  // [covariant_parameters] is a bitvector of function.NumParameters() length.
  void SetGenericCovariantImplParameters(
      const BitVector* generic_covariant_impl_parameters);

  // Returns true if i-th parameter is covariant.
  // SetCovariantParameters should be called before using this method.
  bool IsCovariantParameter(intptr_t i) const;

  // Returns true if i-th parameter is generic-covariant-impl.
  // SetGenericCovariantImplParameters should be called before using this
  // method.
  bool IsGenericCovariantImplParameter(intptr_t i) const;

  // Variables needed for the InvokeFieldDispatcher for dynamic closure calls,
  // because they are both read and written to by the builders.
  struct DynamicClosureCallVars : ZoneObject {
    DynamicClosureCallVars(Zone* zone, intptr_t num_named)
        : named_argument_parameter_indices(zone, num_named) {}

#define FOR_EACH_DYNAMIC_CLOSURE_CALL_VARIABLE(V)                              \
  V(current_function, Function, CurrentFunction)                               \
  V(current_num_processed, Smi, CurrentNumProcessed)                           \
  V(current_param_index, Smi, CurrentParamIndex)                               \
  V(current_type_param, Dynamic, CurrentTypeParam)                             \
  V(function_type_args, Dynamic, FunctionTypeArgs)                             \
  V(instantiator_type_args, Dynamic, InstantiatorTypeArgs)                     \
  V(parent_function_type_args, Dynamic, ParentFunctionTypeArgs)                \
  V(delayed_type_args, Dynamic, DelayedTypeArgs)

#define DEFINE_FIELD(Name, _, __) LocalVariable* Name = nullptr;
    FOR_EACH_DYNAMIC_CLOSURE_CALL_VARIABLE(DEFINE_FIELD)
#undef DEFINE_FIELD

    // An array of local variables, one for each named parameter in the
    // saved arguments descriptor.
    ZoneGrowableArray<LocalVariable*> named_argument_parameter_indices;
  };

  DynamicClosureCallVars* dynamic_closure_call_vars() const {
    return dynamic_closure_call_vars_;
  }
  DynamicClosureCallVars* EnsureDynamicClosureCallVars();

 private:
  Thread* thread_;
  const Function& function_;
  LocalScope* scope_;
  RegExpCompileData* regexp_compile_data_;
  LocalVariable* function_type_arguments_;
  LocalVariable* parent_type_arguments_;
  LocalVariable* suspend_state_var_ = nullptr;
  LocalVariable* current_context_var_;
  LocalVariable* arg_desc_var_;
  LocalVariable* receiver_var_ = nullptr;
  LocalVariable* expression_temp_var_;
  LocalVariable* entry_points_temp_var_;
  DynamicClosureCallVars* dynamic_closure_call_vars_;
  mutable FieldSet guarded_fields_;
  ZoneGrowableArray<const Instance*>* default_parameter_values_;
  bool receiver_used_ = false;

  LocalVariable* raw_type_arguments_var_;
  ZoneGrowableArray<LocalVariable*>* raw_parameters_ = nullptr;

  VariableIndex first_parameter_index_;
  int num_stack_locals_;
  bool have_seen_await_expr_;

  kernel::ScopeBuildingResult* kernel_scopes_;

  const BitVector* generic_covariant_impl_parameters_ = nullptr;

  friend class Parser;
  DISALLOW_COPY_AND_ASSIGN(ParsedFunction);
};

class Parser : public ValueObject {
 public:
  // Parse a function to retrieve parameter information that is not retained in
  // the Function object. Returns either an error if the parse fails (which
  // could be the case for local functions), or a flat array of entries for each
  // parameter. Each parameter entry contains: * a Dart bool indicating whether
  // the parameter was declared final * its default value (or null if none was
  // declared) * an array of metadata (or null if no metadata was declared).
  enum {
    kParameterIsFinalOffset,
    kParameterDefaultValueOffset,
    kParameterMetadataOffset,
    kParameterEntrySize,
  };

 private:
  DISALLOW_COPY_AND_ASSIGN(Parser);
};

}  // namespace dart

#endif  // RUNTIME_VM_PARSER_H_
