// Copyright (c) 2017, 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_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
#define RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include "vm/compiler/frontend/base_flow_graph_builder.h"

namespace dart {
namespace kernel {

// Responsible for building IR code for prologues of functions.
//
// This code handles initialization of local variables which the
// prologue needs to setup, including initialization of the:
//
//    * current context variable, from the passed closure object
//    * function_type_arguments variable, from the stack above fp
//    * raw parameter variables, from the stack above fp
//
// if needed.
//
// Furthermore it performs all necessary checks which could lead into a
// no-such-method bailout, including check that:
//
//    * the number of passed positional arguments is correct
//    * the names of passed named arguments are correct
//    * the number of function type arguments is correct
//
// if needed.
//
// Most of these things are done by interpreting the caller-supplied arguments
// descriptor.
class PrologueBuilder : public BaseFlowGraphBuilder {
 public:
  PrologueBuilder(const ParsedFunction* parsed_function,
                  intptr_t last_used_id,
                  bool compiling_for_osr,
                  bool is_inlining)
      : BaseFlowGraphBuilder(parsed_function, last_used_id),
        compiling_for_osr_(compiling_for_osr),
        is_inlining_(is_inlining) {}

  BlockEntryInstr* BuildPrologue(BlockEntryInstr* entry,
                                 PrologueInfo* prologue_info,
                                 JoinEntryInstr* nsm = nullptr);

  Fragment BuildOptionalParameterHandling(JoinEntryInstr* nsm,
                                          LocalVariable* temp_var);

  static bool HasEmptyPrologue(const Function& function);
  static bool PrologueSkippableOnUncheckedEntry(const Function& function);

  intptr_t last_used_block_id() const { return last_used_block_id_; }

 private:
  Fragment BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
                                         bool expect_type_args);

  Fragment BuildFixedParameterLengthChecks(JoinEntryInstr* nsm);

  Fragment BuildClosureContextHandling();

  Fragment BuildTypeArgumentsHandling(JoinEntryInstr* nsm);

  LocalVariable* ParameterVariable(intptr_t index) {
    return parsed_function_->RawParameterVariable(index);
  }

  const Instance& DefaultParameterValueAt(intptr_t i) {
    if (parsed_function_->default_parameter_values() != NULL) {
      return parsed_function_->DefaultParameterValueAt(i);
    }

    ASSERT(parsed_function_->function().kind() ==
           FunctionLayout::kNoSuchMethodDispatcher);
    return Instance::null_instance();
  }

  void SortOptionalNamedParametersInto(int* opt_param_position,
                                       int num_fixed_params,
                                       int num_params);

  bool compiling_for_osr_;
  bool is_inlining_;
};

}  // namespace kernel
}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
