// 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_UNOPTIMIZED_COMPILATION_INFO_H_
#define V8_UNOPTIMIZED_COMPILATION_INFO_H_

#include <memory>

#include "src/feedback-vector.h"
#include "src/globals.h"
#include "src/handles.h"
#include "src/objects.h"
#include "src/source-position-table.h"
#include "src/utils.h"

namespace v8 {
namespace internal {

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

  Zone* zone() { return zone_; }

  // Compilation flag accessors.

  void MarkAsEval() { SetFlag(kIsEval); }
  bool is_eval() const { return GetFlag(kIsEval); }

  void MarkAsNative() { SetFlag(kIsNative); }
  bool is_native() const { return GetFlag(kIsNative); }

  void MarkAsCollectTypeProfile() { SetFlag(kCollectTypeProfile); }
  bool collect_type_profile() const { return GetFlag(kCollectTypeProfile); }

  // 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<FixedArray> asm_wasm_data() const { return asm_wasm_data_; }
  void SetAsmWasmData(Handle<FixedArray> asm_wasm_data) {
    asm_wasm_data_ = asm_wasm_data;
  }

  FeedbackVectorSpec* feedback_vector_spec() { return &feedback_vector_spec_; }

 private:
  // Various configuration flags for a compilation, as well as some properties
  // of the compiled code produced by a compilation.
  enum Flag {
    kIsEval = 1 << 0,
    kIsNative = 1 << 1,
    kCollectTypeProfile = 1 << 2,
    kUntrustedCodeMitigations = 1 << 3,
  };

  void SetFlag(Flag flag) { flags_ |= flag; }
  bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }

  // Compilation flags.
  unsigned flags_;

  // The zone from which the compilation pipeline working on this
  // OptimizedCompilationInfo allocates.
  Zone* zone_;

  // 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 array generated by the asmjs compiler.
  Handle<FixedArray> asm_wasm_data_;

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

}  // namespace internal
}  // namespace v8

#endif  // V8_UNOPTIMIZED_COMPILATION_INFO_H_
