// 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_HANDLER_TABLE_H_
#define V8_CODEGEN_HANDLER_TABLE_H_

#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/utils/utils.h"

namespace v8 {
namespace internal {

class Assembler;
class ByteArray;
class BytecodeArray;

namespace wasm {
class WasmCode;
}

// HandlerTable is a byte array containing entries for exception handlers in
// the code object it is associated with. The tables come in two flavors:
// 1) Based on ranges: Used for unoptimized code. Stored in a {ByteArray} that
//    is attached to each {BytecodeArray}. Contains one entry per exception
//    handler and a range representing the try-block covered by that handler.
//    Layout looks as follows:
//      [ range-start , range-end , handler-offset , handler-data ]
// 2) Based on return addresses: Used for turbofanned code. Stored directly in
//    the instruction stream of the {Code} object. Contains one entry per
//    call-site that could throw an exception. Layout looks as follows:
//      [ return-address-offset , handler-offset ]
class V8_EXPORT_PRIVATE HandlerTable {
 public:
  // Conservative prediction whether a given handler will locally catch an
  // exception or cause a re-throw to outside the code boundary. Since this is
  // undecidable it is merely an approximation (e.g. useful for debugger).
  enum CatchPrediction {
    UNCAUGHT,     // The handler will (likely) rethrow the exception.
    CAUGHT,       // The exception will be caught by the handler.
    PROMISE,      // The exception will be caught and cause a promise rejection.
    DESUGARING,   // The exception will be caught, but both the exception and
                  // the catching are part of a desugaring and should therefore
                  // not be visible to the user (we won't notify the debugger of
                  // such exceptions).
    ASYNC_AWAIT,  // The exception will be caught and cause a promise rejection
                  // in the desugaring of an async function, so special
                  // async/await handling in the debugger can take place.
  };

  enum EncodingMode { kRangeBasedEncoding, kReturnAddressBasedEncoding };

  // Constructors for the various encodings.
  explicit HandlerTable(Code code);
  explicit HandlerTable(ByteArray byte_array);
  explicit HandlerTable(const wasm::WasmCode* code);
  explicit HandlerTable(BytecodeArray bytecode_array);
  HandlerTable(Address handler_table, int handler_table_size,
               EncodingMode encoding_mode);

  // Getters for handler table based on ranges.
  int GetRangeStart(int index) const;
  int GetRangeEnd(int index) const;
  int GetRangeHandler(int index) const;
  int GetRangeData(int index) const;

  // Setters for handler table based on ranges.
  void SetRangeStart(int index, int value);
  void SetRangeEnd(int index, int value);
  void SetRangeHandler(int index, int offset, CatchPrediction pred);
  void SetRangeData(int index, int value);

  // Returns the required length of the underlying byte array.
  static int LengthForRange(int entries);

  // Emitters for handler table based on return addresses.
  static int EmitReturnTableStart(Assembler* masm);
  static void EmitReturnEntry(Assembler* masm, int offset, int handler);

  // Lookup handler in a table based on ranges. The {pc_offset} is an offset to
  // the start of the potentially throwing instruction (using return addresses
  // for this value would be invalid).
  int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);

  // Lookup handler in a table based on return addresses.
  int LookupReturn(int pc_offset);

  // Returns the number of entries in the table.
  int NumberOfRangeEntries() const;
  int NumberOfReturnEntries() const;

#ifdef ENABLE_DISASSEMBLER
  void HandlerTableRangePrint(std::ostream& os);   // NOLINT
  void HandlerTableReturnPrint(std::ostream& os);  // NOLINT
#endif

 private:
  // Getters for handler table based on ranges.
  CatchPrediction GetRangePrediction(int index) const;

  // Gets entry size based on mode.
  static int EntrySizeFromMode(EncodingMode mode);

  // Getters for handler table based on return addresses.
  int GetReturnOffset(int index) const;
  int GetReturnHandler(int index) const;

  // Number of entries in the loaded handler table.
  const int number_of_entries_;

#ifdef DEBUG
  // The encoding mode of the table. Mostly useful for debugging to check that
  // used accessors and constructors fit together.
  const EncodingMode mode_;
#endif

  // Direct pointer into the encoded data. This pointer potentially points into
  // objects on the GC heap (either {ByteArray} or {Code}) and could become
  // stale during a collection. Hence we disallow any allocation.
  const Address raw_encoded_data_;
  DISALLOW_HEAP_ALLOCATION(no_gc_)

  // Layout description for handler table based on ranges.
  static const int kRangeStartIndex = 0;
  static const int kRangeEndIndex = 1;
  static const int kRangeHandlerIndex = 2;
  static const int kRangeDataIndex = 3;
  static const int kRangeEntrySize = 4;

  // Layout description for handler table based on return addresses.
  static const int kReturnOffsetIndex = 0;
  static const int kReturnHandlerIndex = 1;
  static const int kReturnEntrySize = 2;

  // Encoding of the {handler} field.
  class HandlerPredictionField : public BitField<CatchPrediction, 0, 3> {};
  class HandlerOffsetField : public BitField<int, 3, 29> {};
};

}  // namespace internal
}  // namespace v8

#endif  // V8_CODEGEN_HANDLER_TABLE_H_
