// Copyright (c) 2019, 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_STUB_CODE_COMPILER_H_
#define RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_

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

#include <functional>

#include "vm/allocation.h"
#include "vm/compiler/runtime_api.h"
#include "vm/constants.h"
#include "vm/growable_array.h"
#include "vm/stub_code_list.h"
#include "vm/tagged_pointer.h"

namespace dart {

// Forward declarations.
class Code;
class DescriptorList;
class Label;

namespace compiler {

// Forward declarations.
class Assembler;

// Represents an unresolved PC-relative Call/TailCall.
class UnresolvedPcRelativeCall : public ZoneAllocated {
 public:
  UnresolvedPcRelativeCall(intptr_t offset,
                           const dart::Code& target,
                           bool is_tail_call)
      : offset_(offset), target_(target), is_tail_call_(is_tail_call) {}

  intptr_t offset() const { return offset_; }
  const dart::Code& target() const { return target_; }
  bool is_tail_call() const { return is_tail_call_; }

 private:
  const intptr_t offset_;
  const dart::Code& target_;
  const bool is_tail_call_;
};

using UnresolvedPcRelativeCalls = GrowableArray<UnresolvedPcRelativeCall*>;

class StubCodeCompiler {
 public:
  StubCodeCompiler(Assembler* assembler_, DescriptorList* pc_descriptors_list)
      : assembler(assembler_), pc_descriptors_list_(pc_descriptors_list) {}

  Assembler* assembler;

  void EnsureIsNewOrRemembered();
  static ArrayPtr BuildStaticCallsTable(
      Zone* zone,
      compiler::UnresolvedPcRelativeCalls* unresolved_calls);

#define STUB_CODE_GENERATE(name) void Generate##name##Stub();
  VM_STUB_CODE_LIST(STUB_CODE_GENERATE)
#undef STUB_CODE_GENERATE

  void GenerateAllocationStubForClass(
      UnresolvedPcRelativeCalls* unresolved_calls,
      const Class& cls,
      const dart::Code& allocate_object,
      const dart::Code& allocat_object_parametrized);

  enum Optimized {
    kUnoptimized,
    kOptimized,
  };
  enum CallType {
    kInstanceCall,
    kStaticCall,
  };
  enum Exactness {
    kCheckExactness,
    kIgnoreExactness,
  };
  void GenerateNArgsCheckInlineCacheStub(intptr_t num_args,
                                         const RuntimeEntry& handle_ic_miss,
                                         Token::Kind kind,
                                         Optimized optimized,
                                         CallType type,
                                         Exactness exactness);
  void GenerateNArgsCheckInlineCacheStubForEntryKind(
      intptr_t num_args,
      const RuntimeEntry& handle_ic_miss,
      Token::Kind kind,
      Optimized optimized,
      CallType type,
      Exactness exactness,
      CodeEntryKind entry_kind);
  void GenerateUsageCounterIncrement(Register temp_reg);
  void GenerateOptimizedUsageCounterIncrement();

  // Calculates the offset (in words) from FP to the provided [cpu_register].
  //
  // Assumes
  //   * all [kDartAvailableCpuRegs] followed by saved-PC, saved-FP were
  //     pushed on the stack
  //   * [cpu_register] is in [kDartAvailableCpuRegs]
  //
  // The intended use of this function is to find registers on the stack which
  // were spilled in the
  // `StubCode::*<stub-name>Shared{With,Without}FpuRegsStub()`
  static intptr_t WordOffsetFromFpToCpuRegister(Register cpu_register);

#if !defined(TARGET_ARCH_IA32)
  // Used for passing functions that generate exit branches for a
  // SubtypeTestCache search stub. Must generate a return instruction.
  using STCSearchExitGenerator = std::function<void(Assembler*, int)>;
#endif

 private:
#if !defined(TARGET_ARCH_IA32)
  // Generates the code for searching a subtype test cache for an entry that
  // matches the contents of the TypeTestABI registers. If no matching
  // entry is found, then the code generated by [not_found] is executed.
  // Otherwise, the code generated by [found] is executed, which can assume
  // that [cache_entry_reg] points to the start of the matching cache entry.
  // Both generators should return from the stub and not fall through.
  //
  // Inputs in addition to those in TypeTestABI:
  // - null_reg: a register containing the address Object::null().
  //
  // The following registers from TypeTestABI are inputs under the following
  // conditions:
  // - kScratchReg: always
  // - kInstanceReg: always
  // - kDstTypeReg: [n] >= 3
  // - kInstantiatorTypeArgumentsReg: [n] >= 4
  // - kFunctionTypeArgumentsReg: [n] >= 5
  //
  // Has the following input registers in addition to those in TypeTestABI:
  // - null_reg: contains the ObjectPtr for Object::null()
  // - cache_entry_reg: contains the ArrayPtr for the backing array of the STC
  //
  // The following registers must be provided for the given conditions and
  // are clobbered, and can be kNoRegister otherwise:
  // - instance_cid_or_sig_reg: always
  // - instance_type_args_reg: [n] >= 2
  // - parent_fun_type_args_reg: [n] >= 6
  // - delayed_type_args_reg: [n] >= 7
  //
  // The following registers must be distinct from other inputs when provided,
  // but can be kNoRegister:
  // - cache_entry_end_reg: used in the hash-based cache iteration loop
  //   on each iteration
  // - cache_entry_start_reg, used in the hash-based cache iteration loop
  //   to reset if iteration hits the end of the entries
  // - cache_entry_count_reg, used to calculate the starting index to probe
  // Note that if any of these are kNoRegister, then a stack slot is used to
  // store and retrieve the corresponding value.
  //
  // Note that all input registers must be distinct, except for the case
  // of kInstanceReg, which can be used for one of [delayed_type_args_reg],
  // [cache_entry_end_reg], [cache_entry_start_reg], or [cache_entry_count_reg],
  // which are all set after the last use of kInstanceReg.
  //
  // Also note that if any non-TypeTestABI registers overlap with any
  // non-scratch TypeTestABI registers, the original value of the TypeTestABI
  // register must be stored before the generated code and restored afterwards.
  static void GenerateSubtypeTestCacheSearch(
      Assembler* assembler,
      int n,
      Register null_reg,
      Register cache_entry_reg,
      Register instance_cid_or_sig_reg,
      Register instance_type_args_reg,
      Register parent_fun_type_args_reg,
      Register delayed_type_args_reg,
      Register cache_entry_end_reg,
      Register cache_entry_start_reg,
      Register cache_entry_count_reg,
      const STCSearchExitGenerator& gen_found,
      const STCSearchExitGenerator& gen_not_found);
#endif

  // Common function for generating the different SubtypeTestCache search
  // stubs. Check architecture-specific version for inputs/outputs.
  static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n);

  // Common function for generating InitLateStaticField and
  // InitLateFinalStaticField stubs.
  void GenerateInitLateStaticFieldStub(bool is_final);

  // Common function for generating InitLateInstanceField and
  // InitLateFinalInstanceField stubs.
  void GenerateInitLateInstanceFieldStub(bool is_final);

  // Common function for generating AllocateClosure[TA][Generic] stubs.
  void GenerateAllocateClosureStub(bool has_instantiator_type_args,
                                   bool is_generic);

  // Common function for generating Allocate<TypedData>Array stubs.
  void GenerateAllocateTypedDataArrayStub(intptr_t cid);

  void GenerateAllocateSmallRecordStub(intptr_t num_fields,
                                       bool has_named_fields);

  void GenerateSharedStubGeneric(bool save_fpu_registers,
                                 intptr_t self_code_stub_offset_from_thread,
                                 bool allow_return,
                                 std::function<void()> perform_runtime_call);

  // Generates shared slow path stub which saves registers and calls
  // [target] runtime entry.
  // If [store_runtime_result_in_result_register], then stub puts result into
  // SharedSlowPathStubABI::kResultReg.
  void GenerateSharedStub(bool save_fpu_registers,
                          const RuntimeEntry* target,
                          intptr_t self_code_stub_offset_from_thread,
                          bool allow_return,
                          bool store_runtime_result_in_result_register = false);

  void GenerateLateInitializationError(bool with_fpu_regs);

  void GenerateRangeError(bool with_fpu_regs);
  void GenerateWriteError(bool with_fpu_regs);

  void GenerateSuspendStub(bool call_suspend_function,
                           bool pass_type_arguments,
                           intptr_t suspend_entry_point_offset_in_thread,
                           intptr_t suspend_function_offset_in_object_store);
  void GenerateInitSuspendableFunctionStub(
      intptr_t init_entry_point_offset_in_thread,
      intptr_t init_function_offset_in_object_store);
  void GenerateReturnStub(intptr_t return_entry_point_offset_in_thread,
                          intptr_t return_function_offset_in_object_store,
                          intptr_t return_stub_offset_in_thread);

  void GenerateLoadBSSEntry(BSS::Relocation relocation,
                            Register dst,
                            Register tmp);
  void InsertBSSRelocation(BSS::Relocation reloc);

  void GenerateLoadFfiCallbackMetadataRuntimeFunction(uword function_index,
                                                      Register dst);

  DescriptorList* pc_descriptors_list_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(StubCodeCompiler);
};

}  // namespace compiler

enum DeoptStubKind { kLazyDeoptFromReturn, kLazyDeoptFromThrow, kEagerDeopt };

// Zap value used to indicate unused CODE_REG in deopt.
static constexpr uword kZapCodeReg = 0xf1f1f1f1;

// Zap value used to indicate unused return address in deopt.
static constexpr uword kZapReturnAddress = 0xe1e1e1e1;

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
