// 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_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
#define V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_

#include "src/base/compiler-specific.h"
#include "src/globals.h"
#include "src/interpreter/bytecodes.h"
#include "src/source-position-table.h"

namespace v8 {
namespace internal {

class BytecodeArray;
class SourcePositionTableBuilder;

namespace interpreter {

class BytecodeLabel;
class BytecodeLoopHeader;
class BytecodeNode;
class BytecodeJumpTable;
class ConstantArrayBuilder;
class HandlerTableBuilder;

namespace bytecode_array_writer_unittest {
class BytecodeArrayWriterUnittest;
}  // namespace bytecode_array_writer_unittest

// Class for emitting bytecode as the final stage of the bytecode
// generation pipeline.
class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
 public:
  BytecodeArrayWriter(
      Zone* zone, ConstantArrayBuilder* constant_array_builder,
      SourcePositionTableBuilder::RecordingMode source_position_mode);

  void Write(BytecodeNode* node);
  void WriteJump(BytecodeNode* node, BytecodeLabel* label);
  void WriteJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
  void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
  void BindLabel(BytecodeLabel* label);
  void BindLoopHeader(BytecodeLoopHeader* loop_header);
  void BindJumpTableEntry(BytecodeJumpTable* jump_table, int case_value);
  void BindHandlerTarget(HandlerTableBuilder* handler_table_builder,
                         int handler_id);
  void BindTryRegionStart(HandlerTableBuilder* handler_table_builder,
                          int handler_id);
  void BindTryRegionEnd(HandlerTableBuilder* handler_table_builder,
                        int handler_id);

  Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate, int register_count,
                                        int parameter_count,
                                        Handle<ByteArray> handler_table);

  bool RemainderOfBlockIsDead() const { return exit_seen_in_block_; }

 private:
  // Maximum sized packed bytecode is comprised of a prefix bytecode,
  // plus the actual bytecode, plus the maximum number of operands times
  // the maximum operand size.
  static const size_t kMaxSizeOfPackedBytecode =
      2 * sizeof(Bytecode) +
      Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast);

  // Constants that act as placeholders for jump operands to be
  // patched. These have operand sizes that match the sizes of
  // reserved constant pool entries.
  const uint32_t k8BitJumpPlaceholder = 0x7f;
  const uint32_t k16BitJumpPlaceholder =
      k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8);
  const uint32_t k32BitJumpPlaceholder =
      k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16);

  void PatchJump(size_t jump_target, size_t jump_location);
  void PatchJumpWith8BitOperand(size_t jump_location, int delta);
  void PatchJumpWith16BitOperand(size_t jump_location, int delta);
  void PatchJumpWith32BitOperand(size_t jump_location, int delta);

  void EmitBytecode(const BytecodeNode* const node);
  void EmitJump(BytecodeNode* node, BytecodeLabel* label);
  void EmitJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
  void EmitSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
  void UpdateSourcePositionTable(const BytecodeNode* const node);

  void UpdateExitSeenInBlock(Bytecode bytecode);

  void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info);
  void InvalidateLastBytecode();

  void StartBasicBlock();

  ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
  SourcePositionTableBuilder* source_position_table_builder() {
    return &source_position_table_builder_;
  }
  ConstantArrayBuilder* constant_array_builder() {
    return constant_array_builder_;
  }

  ZoneVector<uint8_t> bytecodes_;
  int unbound_jumps_;
  SourcePositionTableBuilder source_position_table_builder_;
  ConstantArrayBuilder* constant_array_builder_;

  Bytecode last_bytecode_;
  size_t last_bytecode_offset_;
  bool last_bytecode_had_source_info_;
  bool elide_noneffectful_bytecodes_;

  bool exit_seen_in_block_;

  friend class bytecode_array_writer_unittest::BytecodeArrayWriterUnittest;
  DISALLOW_COPY_AND_ASSIGN(BytecodeArrayWriter);
};

}  // namespace interpreter
}  // namespace internal
}  // namespace v8

#endif  // V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
