// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_CODEGEN_UNOPTIMIZED_COMPILATION_INFO_H_
#define V8_CODEGEN_UNOPTIMIZED_COMPILATION_INFO_H_

#include <memory>

#include "src/codegen/source-position-table.h"
#include "src/common/globals.h"
#include "src/handles/handles.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/objects.h"
#include "src/parsing/parse-info.h"
#include "src/utils/utils.h"

namespace v8 {
namespace internal {

class AsmWasmData;
class CoverageInfo;
class DeclarationScope;
class FunctionLiteral;
class Isolate;
class ParseInfo;
class SourceRangeMap;
class Zone;

// UnoptimizedCompilationInfo encapsulates the information needed to compile
// unoptimized code for a given function, and the results of the compilation.
class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
 public:
  UnoptimizedCompilationInfo(Zone* zone, ParseInfo* parse_info,
                             FunctionLiteral* literal);

  const UnoptimizedCompileFlags& flags() const { return flags_; }

  // Accessors for the input data of the function being compiled.

  FunctionLiteral* literal() const { return literal_; }
  void set_literal(FunctionLiteral* literal) {
    DCHECK_NOT_NULL(literal);
    literal_ = literal;
  }

  DeclarationScope* scope() const;

  int num_parameters() const;
  int num_parameters_including_this() const;

  // Accessors for optional compilation features.

  SourcePositionTableBuilder::RecordingMode SourcePositionRecordingMode() const;

  bool has_source_range_map() const { return source_range_map_ != nullptr; }
  SourceRangeMap* source_range_map() const { return source_range_map_; }
  void set_source_range_map(SourceRangeMap* source_range_map) {
    source_range_map_ = source_range_map;
  }

  bool has_coverage_info() const { return !coverage_info_.is_null(); }
  Handle<CoverageInfo> coverage_info() const { return coverage_info_; }
  void set_coverage_info(Handle<CoverageInfo> coverage_info) {
    coverage_info_ = coverage_info;
  }

  // Accessors for the output of compilation.

  bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
  Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
  void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
    bytecode_array_ = bytecode_array;
  }

  bool has_asm_wasm_data() const { return !asm_wasm_data_.is_null(); }
  Handle<AsmWasmData> asm_wasm_data() const { return asm_wasm_data_; }
  void SetAsmWasmData(Handle<AsmWasmData> asm_wasm_data) {
    asm_wasm_data_ = asm_wasm_data;
  }

  FeedbackVectorSpec* feedback_vector_spec() { return &feedback_vector_spec_; }

 private:
  // Compilation flags.
  const UnoptimizedCompileFlags flags_;

  // The root AST node of the function literal being compiled.
  FunctionLiteral* literal_;

  // Used when block coverage is enabled.
  SourceRangeMap* source_range_map_;

  // Encapsulates coverage information gathered by the bytecode generator.
  // Needs to be stored on the shared function info once compilation completes.
  Handle<CoverageInfo> coverage_info_;

  // Holds the bytecode array generated by the interpreter.
  Handle<BytecodeArray> bytecode_array_;

  // Holds the asm_wasm data struct generated by the asmjs compiler.
  Handle<AsmWasmData> asm_wasm_data_;

  // Holds the feedback vector spec generated during compilation
  FeedbackVectorSpec feedback_vector_spec_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_CODEGEN_UNOPTIMIZED_COMPILATION_INFO_H_
