// Copyright 2015 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_COMPILER_FRAME_STATES_H_
#define V8_COMPILER_FRAME_STATES_H_

#include "src/builtins/builtins.h"
#include "src/compiler/node.h"
#include "src/handles/handles.h"
#include "src/objects/shared-function-info.h"
#include "src/utils/utils.h"

namespace v8 {
namespace internal {

namespace compiler {

class JSGraph;
class Node;
class SharedFunctionInfoRef;

// Flag that describes how to combine the current environment with
// the output of a node to obtain a framestate for lazy bailout.
class OutputFrameStateCombine {
 public:
  static const size_t kInvalidIndex = SIZE_MAX;

  static OutputFrameStateCombine Ignore() {
    return OutputFrameStateCombine(kInvalidIndex);
  }
  static OutputFrameStateCombine PokeAt(size_t index) {
    return OutputFrameStateCombine(index);
  }

  size_t GetOffsetToPokeAt() const {
    DCHECK_NE(parameter_, kInvalidIndex);
    return parameter_;
  }

  bool IsOutputIgnored() const { return parameter_ == kInvalidIndex; }

  size_t ConsumedOutputCount() const { return IsOutputIgnored() ? 0 : 1; }

  bool operator==(OutputFrameStateCombine const& other) const {
    return parameter_ == other.parameter_;
  }
  bool operator!=(OutputFrameStateCombine const& other) const {
    return !(*this == other);
  }

  friend size_t hash_value(OutputFrameStateCombine const&);
  friend std::ostream& operator<<(std::ostream&,
                                  OutputFrameStateCombine const&);

 private:
  explicit OutputFrameStateCombine(size_t parameter) : parameter_(parameter) {}

  size_t const parameter_;
};


// The type of stack frame that a FrameState node represents.
enum class FrameStateType {
  kInterpretedFunction,            // Represents an InterpretedFrame.
  kArgumentsAdaptor,               // Represents an ArgumentsAdaptorFrame.
  kConstructStub,                  // Represents a ConstructStubFrame.
  kBuiltinContinuation,            // Represents a continuation to a stub.
  kJavaScriptBuiltinContinuation,  // Represents a continuation to a JavaScipt
                                   // builtin.
  kJavaScriptBuiltinContinuationWithCatch  // Represents a continuation to a
                                           // JavaScipt builtin with a catch
                                           // handler.
};

class FrameStateFunctionInfo {
 public:
  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
                         int local_count,
                         Handle<SharedFunctionInfo> shared_info)
      : type_(type),
        parameter_count_(parameter_count),
        local_count_(local_count),
        shared_info_(shared_info) {}

  int local_count() const { return local_count_; }
  int parameter_count() const { return parameter_count_; }
  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
  FrameStateType type() const { return type_; }

  static bool IsJSFunctionType(FrameStateType type) {
    return type == FrameStateType::kInterpretedFunction ||
           type == FrameStateType::kJavaScriptBuiltinContinuation ||
           type == FrameStateType::kJavaScriptBuiltinContinuationWithCatch;
  }

 private:
  FrameStateType const type_;
  int const parameter_count_;
  int const local_count_;
  Handle<SharedFunctionInfo> const shared_info_;
};


class FrameStateInfo final {
 public:
  FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
                 const FrameStateFunctionInfo* info)
      : bailout_id_(bailout_id),
        frame_state_combine_(state_combine),
        info_(info) {}

  FrameStateType type() const {
    return info_ == nullptr ? FrameStateType::kInterpretedFunction
                            : info_->type();
  }
  BailoutId bailout_id() const { return bailout_id_; }
  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
  MaybeHandle<SharedFunctionInfo> shared_info() const {
    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
                            : info_->shared_info();
  }
  int parameter_count() const {
    return info_ == nullptr ? 0 : info_->parameter_count();
  }
  int local_count() const {
    return info_ == nullptr ? 0 : info_->local_count();
  }
  const FrameStateFunctionInfo* function_info() const { return info_; }

 private:
  BailoutId const bailout_id_;
  OutputFrameStateCombine const frame_state_combine_;
  const FrameStateFunctionInfo* const info_;
};

bool operator==(FrameStateInfo const&, FrameStateInfo const&);
bool operator!=(FrameStateInfo const&, FrameStateInfo const&);

size_t hash_value(FrameStateInfo const&);

std::ostream& operator<<(std::ostream&, FrameStateInfo const&);

static constexpr int kFrameStateParametersInput = 0;
static constexpr int kFrameStateLocalsInput = 1;
static constexpr int kFrameStateStackInput = 2;
static constexpr int kFrameStateContextInput = 3;
static constexpr int kFrameStateFunctionInput = 4;
static constexpr int kFrameStateOuterStateInput = 5;
static constexpr int kFrameStateInputCount = kFrameStateOuterStateInput + 1;

enum class ContinuationFrameStateMode { EAGER, LAZY, LAZY_WITH_CATCH };

FrameState CreateStubBuiltinContinuationFrameState(
    JSGraph* graph, Builtins::Name name, Node* context, Node* const* parameters,
    int parameter_count, Node* outer_frame_state,
    ContinuationFrameStateMode mode);

FrameState CreateJavaScriptBuiltinContinuationFrameState(
    JSGraph* graph, const SharedFunctionInfoRef& shared, Builtins::Name name,
    Node* target, Node* context, Node* const* stack_parameters,
    int stack_parameter_count, Node* outer_frame_state,
    ContinuationFrameStateMode mode);

FrameState CreateGenericLazyDeoptContinuationFrameState(
    JSGraph* graph, const SharedFunctionInfoRef& shared, Node* target,
    Node* context, Node* receiver, Node* outer_frame_state);

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_FRAME_STATES_H_
