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

// 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 != NULL);
    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 != NULL);
    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 == NULL) return;
    for (intptr_t i = 0; i < list->length(); i++) {
      ASSERT(list->At(i)->IsZoneHandle() || list->At(i)->InVMIsolateHeap());
    }
#endif
  }

  const Instance& DefaultParameterValueAt(intptr_t i) const {
    ASSERT(default_parameter_values_ != NULL);
    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_ != NULL; }
  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; }

  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_ != NULL; }

  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_ != NULL;
  }

  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_ != NULL;
  }
  void EnsureFinallyReturnTemp(bool is_async);

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

  ZoneGrowableArray<const Field*>* 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_;
  ZoneGrowableArray<const Field*>* guarded_fields_;
  ZoneGrowableArray<const Instance*>* default_parameter_values_;

  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_
