// 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 ZoneAllocated {
 public:
  ParsedFunction(Thread* thread, const Function& function);

  const Function& function() const { return function_; }
  const Code& code() const { return code_; }

  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* finally_return_temp_var() const {
    ASSERT(has_finally_return_temp_var());
    return finally_return_temp_var_;
  }
  void set_finally_return_temp_var(LocalVariable* value) {
    ASSERT(!has_finally_return_temp_var());
    finally_return_temp_var_ = value;
  }
  bool has_finally_return_temp_var() const {
    return finally_return_temp_var_ != nullptr;
  }
  void EnsureFinallyReturnTemp(bool is_async);

  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 AllocateIrregexpVariables(intptr_t num_stack_locals);

  void record_await() { have_seen_await_expr_ = true; }
  bool have_seen_await() const { return have_seen_await_expr_; }
  bool is_forwarding_stub() const {
    return forwarding_stub_super_target_ != nullptr;
  }
  const Function* forwarding_stub_super_target() const {
    return forwarding_stub_super_target_;
  }
  void MarkForwardingStub(const Function* forwarding_target) {
    forwarding_stub_super_target_ = forwarding_target;
  }

  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);

  bool HasCovariantParametersInfo() const {
    return covariant_parameters_ != nullptr;
  }

  // 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 : ZoneAllocated {
    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)

#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_;
  Code& code_;
  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_;
  LocalVariable* finally_return_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_;

  const Function* forwarding_stub_super_target_ = nullptr;
  kernel::ScopeBuildingResult* kernel_scopes_;

  const BitVector* covariant_parameters_ = nullptr;
  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_
